ed25519: make public ed25519.internal.edwars25519.Element (#13488)

pull/13496/head
blackshirt 2022-02-17 03:56:14 +07:00 committed by GitHub
parent f68144774d
commit 54b10e99a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 72 additions and 73 deletions

View File

@ -20,24 +20,24 @@ pub const seed_size = 32
// `PublicKey` is Ed25519 public keys.
pub type PublicKey = []byte
// `equal` reports whether p and x have the same value.
// equal reports whether p and x have the same value.
pub fn (p PublicKey) equal(x []byte) bool {
return subtle.constant_time_compare(p, PublicKey(x)) == 1
}
// `PrivateKey` is Ed25519 private keys
// PrivateKey is Ed25519 private keys
pub type PrivateKey = []byte
// seed returns the private key seed corresponding to priv. RFC 8032's private keys correspond to seeds
// in this module.
// seed returns the private key seed corresponding to priv.
// RFC 8032's private keys correspond to seeds in this module.
pub fn (priv PrivateKey) seed() []byte {
mut seed := []byte{len: ed25519.seed_size}
copy(seed, priv[..32])
return seed
}
// `public_key` returns the []byte corresponding to priv.
pub fn (priv PrivateKey) public_key() []byte {
// public_key returns the []byte corresponding to priv.
pub fn (priv PrivateKey) public_key() PublicKey {
assert priv.len == ed25519.private_key_size
mut publickey := []byte{len: ed25519.public_key_size}
copy(publickey, priv[32..])
@ -49,7 +49,7 @@ pub fn (priv PrivateKey) equal(x []byte) bool {
return subtle.constant_time_compare(priv, PrivateKey(x)) == 1
}
// `sign` signs the given message with priv.
// sign signs the given message with priv.
pub fn (priv PrivateKey) sign(message []byte) ?[]byte {
/*
if opts.HashFunc() != crypto.Hash(0) {
@ -59,7 +59,7 @@ pub fn (priv PrivateKey) sign(message []byte) ?[]byte {
return sign(priv, message)
}
// `sign `signs the message with privatekey and returns a signature
// sign`signs the message with privatekey and returns a signature
pub fn sign(privatekey PrivateKey, message []byte) ?[]byte {
mut signature := []byte{len: ed25519.signature_size}
sign_generic(signature, privatekey, message) ?
@ -107,7 +107,7 @@ fn sign_generic(signature []byte, privatekey []byte, message []byte) ? {
copy(signature[32..], ss.bytes())
}
// `verify` reports whether sig is a valid signature of message by publickey.
// verify reports whether sig is a valid signature of message by publickey.
pub fn verify(publickey PublicKey, message []byte, sig []byte) ?bool {
if publickey.len != ed25519.public_key_size {
return error('ed25519: bad public key length: $publickey.len')
@ -143,7 +143,7 @@ pub fn verify(publickey PublicKey, message []byte, sig []byte) ?bool {
return subtle.constant_time_compare(sig[..32], rr.bytes()) == 1
}
// `generate_key` generates a public/private key pair entropy using `crypto.rand`.
// generate_key generates a public/private key pair entropy using `crypto.rand`.
pub fn generate_key() ?(PublicKey, PrivateKey) {
mut seed := rand.bytes(ed25519.seed_size) ?
@ -154,7 +154,7 @@ pub fn generate_key() ?(PublicKey, PrivateKey) {
return publickey, privatekey
}
// `new_key_from_seed` calculates a private key from a seed. private keys of RFC 8032
// new_key_from_seed calculates a private key from a seed. private keys of RFC 8032
// correspond to seeds in this module
pub fn new_key_from_seed(seed []byte) PrivateKey {
// Outline the function body so that the returned key can be stack-allocated.

View File

@ -117,7 +117,7 @@ fn works_check_on_sign_input_string(item string) bool {
}
pubkey2 := priv2.public_key()
if pubkey != pubkey2 {
if ed25519.PublicKey(pubkey) != pubkey2 {
return false
}

View File

@ -18,7 +18,7 @@ struct Uint128 {
// are allowed to alias.
//
// The zero value is a valid zero element.
struct Element {
pub struct Element {
mut:
// An element t represents the integer
// t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204
@ -222,7 +222,7 @@ fn fe_mul_generic(a Element, b Element) Element {
return v
}
// carryPropagate brings the limbs below 52 bits by applying the reduction
// carry_propagate_generic brings the limbs below 52 bits by applying the reduction
// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry.
fn (mut v Element) carry_propagate_generic() Element {
c0 := v.l0 >> 51
@ -330,19 +330,19 @@ fn fe_square_generic(a Element) Element {
}
// zero sets v = 0, and returns v.
fn (mut v Element) zero() Element {
pub fn (mut v Element) zero() Element {
v = edwards25519.fe_zero
return v
}
// one sets v = 1, and returns v.
fn (mut v Element) one() Element {
pub fn (mut v Element) one() Element {
v = edwards25519.fe_one
return v
}
// reduce reduces v modulo 2^255 - 19 and returns it.
fn (mut v Element) reduce() Element {
pub fn (mut v Element) reduce() Element {
v = v.carry_propagate_generic()
// After the light reduction we now have a edwards25519 element representation
@ -374,8 +374,8 @@ fn (mut v Element) reduce() Element {
return v
}
// Add sets v = a + b, and returns v.
fn (mut v Element) add(a Element, b Element) Element {
// add sets v = a + b, and returns v.
pub fn (mut v Element) add(a Element, b Element) Element {
v.l0 = a.l0 + b.l0
v.l1 = a.l1 + b.l1
v.l2 = a.l2 + b.l2
@ -388,8 +388,8 @@ fn (mut v Element) add(a Element, b Element) Element {
return v.carry_propagate_generic()
}
// Subtract sets v = a - b, and returns v.
fn (mut v Element) subtract(a Element, b Element) Element {
// subtract sets v = a - b, and returns v.
pub fn (mut v Element) subtract(a Element, b Element) Element {
// We first add 2 * p, to guarantee the subtraction won't underflow, and
// then subtract b (which can be up to 2^255 + 2^13 * 19).
v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0
@ -400,15 +400,15 @@ fn (mut v Element) subtract(a Element, b Element) Element {
return v.carry_propagate_generic()
}
// `negate` sets v = -a, and returns v.
fn (mut v Element) negate(a Element) Element {
// negate sets v = -a, and returns v.
pub fn (mut v Element) negate(a Element) Element {
return v.subtract(edwards25519.fe_zero, a)
}
// invert sets v = 1/z mod p, and returns v.
//
// If z == 0, invert returns v = 0.
fn (mut v Element) invert(z Element) Element {
pub fn (mut v Element) invert(z Element) Element {
// Inversion is implemented as exponentiation with exponent p 2. It uses the
// same sequence of 255 squarings and 11 multiplications as [Curve25519].
mut z2 := Element{}
@ -481,13 +481,13 @@ fn (mut v Element) invert(z Element) Element {
}
// square sets v = x * x, and returns v.
fn (mut v Element) square(x Element) Element {
pub fn (mut v Element) square(x Element) Element {
v = fe_square_generic(x)
return v
}
// multiply sets v = x * y, and returns v.
fn (mut v Element) multiply(x Element, y Element) Element {
pub fn (mut v Element) multiply(x Element, y Element) Element {
v = fe_mul_generic(x, y)
return v
}
@ -501,7 +501,7 @@ fn mul_51(a u64, b u32) (u64, u64) {
}
// pow_22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
fn (mut v Element) pow_22523(x Element) Element {
pub fn (mut v Element) pow_22523(x Element) Element {
mut t0, mut t1, mut t2 := Element{}, Element{}, Element{}
t0.square(x) // x^2
@ -556,7 +556,7 @@ fn (mut v Element) pow_22523(x Element) Element {
// If u/v is square, sqrt_ratio returns r and 1. If u/v is not square, sqrt_ratio
// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00,
// and returns r and 0.
fn (mut r Element) sqrt_ratio(u Element, v Element) (Element, int) {
pub fn (mut r Element) sqrt_ratio(u Element, v Element) (Element, int) {
mut a, mut b := Element{}, Element{}
// r = (u * v3) * (u * v7)^((p-5)/8)
@ -588,7 +588,7 @@ fn mask_64_bits(cond int) u64 {
}
// selected sets v to a if cond == 1, and to b if cond == 0.
fn (mut v Element) selected(a Element, b Element, cond int) Element {
pub fn (mut v Element) selected(a Element, b Element, cond int) Element {
// see above notes
m := mask_64_bits(cond)
v.l0 = (m & a.l0) | (~m & b.l0)
@ -600,31 +600,31 @@ fn (mut v Element) selected(a Element, b Element, cond int) Element {
}
// is_negative returns 1 if v is negative, and 0 otherwise.
fn (mut v Element) is_negative() int {
pub fn (mut v Element) is_negative() int {
return int(v.bytes()[0] & 1)
}
// absolute sets v to |u|, and returns v.
fn (mut v Element) absolute(u Element) Element {
pub fn (mut v Element) absolute(u Element) Element {
mut e := Element{}
mut uk := u
return v.selected(e.negate(uk), uk, uk.is_negative())
}
// set sets v = a, and returns v.
fn (mut v Element) set(a Element) Element {
pub fn (mut v Element) set(a Element) Element {
v = a
return v
}
// set_bytes sets v to x, where x is a 32-byte little-endian encoding. If x is
// not of the right length, SetUniformBytes returns nil and an error, and the
// not of the right length, SetUniformBytes returns an error, and the
// receiver is unchanged.
//
// Consistent with RFC 7748, the most significant bit (the high bit of the
// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1)
// are accepted. Note that this is laxer than specified by RFC 8032.
fn (mut v Element) set_bytes(x []byte) ?Element {
pub fn (mut v Element) set_bytes(x []byte) ?Element {
if x.len != 32 {
return error('edwards25519: invalid edwards25519 element input size')
}
@ -680,7 +680,7 @@ fn (mut v Element) bytes_generic() []byte {
}
// equal returns 1 if v and u are equal, and 0 otherwise.
fn (mut v Element) equal(ue Element) int {
pub fn (mut v Element) equal(ue Element) int {
mut u := ue
sa := u.bytes()
sv := v.bytes()
@ -688,7 +688,7 @@ fn (mut v Element) equal(ue Element) int {
}
// swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
fn (mut v Element) swap(mut u Element, cond int) {
pub fn (mut v Element) swap(mut u Element, cond int) {
// mut u := ue
m := mask_64_bits(cond)
mut t := m & (v.l0 ^ u.l0)
@ -709,7 +709,7 @@ fn (mut v Element) swap(mut u Element, cond int) {
}
// mult_32 sets v = x * y, and returns v.
fn (mut v Element) mult_32(x Element, y u32) Element {
pub fn (mut v Element) mult_32(x Element, y u32) Element {
x0lo, x0hi := mul_51(x.l0, y)
x1lo, x1hi := mul_51(x.l1, y)
x2lo, x2hi := mul_51(x.l2, y)

View File

@ -31,7 +31,7 @@ fn (mut s Scalar) pow2k(k int) {
// x = X/Z, y = Y/Z, and xy = T/Z as in https://eprint.iacr.org/2008/522.
//
// If the coordinates are invalid or don't represent a valid point on the curve,
// set_extended_coordinates returns nil and an error and the receiver is
// set_extended_coordinates returns an error and the receiver is
// unchanged. Otherwise, set_extended_coordinates returns v.
fn (mut v Point) set_extended_coordinates(x Element, y Element, z Element, t Element) ?Point {
if !is_on_curve(x, y, z, t) {
@ -79,7 +79,7 @@ fn is_on_curve(x Element, y Element, z Element, t Element) bool {
return lhs.equal(rhs) == 1
}
// `bytes_montgomery` converts v to a point on the birationally-equivalent
// bytes_montgomery converts v to a point on the birationally-equivalent
// Curve25519 Montgomery curve, and returns its canonical 32 bytes encoding
// according to RFC 7748.
//
@ -114,7 +114,7 @@ fn (mut v Point) bytes_montgomery_generic(mut buf [32]byte) []byte {
return copy_field_element(mut buf, mut u)
}
// `mult_by_cofactor` sets v = 8 * p, and returns v.
// mult_by_cofactor sets v = 8 * p, and returns v.
pub fn (mut v Point) mult_by_cofactor(p Point) Point {
check_initialized(p)
mut result := ProjectiveP1{}
@ -128,7 +128,7 @@ pub fn (mut v Point) mult_by_cofactor(p Point) Point {
return v.from_p1(result)
}
// `invert` sets s to the inverse of a nonzero scalar v, and returns s.
// invert sets s to the inverse of a nonzero scalar v, and returns s.
//
// If t is zero, invert returns zero.
pub fn (mut s Scalar) invert(t Scalar) Scalar {
@ -234,7 +234,7 @@ pub fn (mut s Scalar) invert(t Scalar) Scalar {
return s
}
// `multi_scalar_mult` sets v = sum(scalars[i] * points[i]), and returns v.
// multi_scalar_mult sets v = sum(scalars[i] * points[i]), and returns v.
//
// Execution time depends only on the lengths of the two slices, which must match.
pub fn (mut v Point) multi_scalar_mult(scalars []Scalar, points []Point) Point {
@ -291,7 +291,7 @@ pub fn (mut v Point) multi_scalar_mult(scalars []Scalar, points []Point) Point {
return v
}
// `vartime_multiscalar_mult` sets v = sum(scalars[i] * points[i]), and returns v.
// vartime_multiscalar_mult sets v = sum(scalars[i] * points[i]), and returns v.
//
// Execution time depends on the inputs.
pub fn (mut v Point) vartime_multiscalar_mult(scalars []Scalar, points []Point) Point {

View File

@ -46,7 +46,6 @@ fn generator() ?Point {
}
// Point types.
struct ProjectiveP1 {
mut:
x Element
@ -77,7 +76,7 @@ mut:
z Element
t Element
// Make the type not comparable (i.e. used with == or as a map key), as
// equivalent points can be represented by different Go values.
// equivalent points can be represented by different values.
// _ incomparable
}
@ -112,7 +111,7 @@ fn (mut v ProjectiveP2) zero() ProjectiveP2 {
}
// set_bytes sets v = x, where x is a 32-byte encoding of v. If x does not
// represent a valid point on the curve, set_bytes returns nil and an error and
// represent a valid point on the curve, set_bytes returns an error and
// the receiver is unchanged. Otherwise, set_bytes returns v.
//
// Note that set_bytes accepts all non-canonical encodings of valid points.
@ -165,19 +164,19 @@ pub fn (mut v Point) set_bytes(x []byte) ?Point {
return v
}
// `set` sets v = u, and returns v.
// set sets v = u, and returns v.
pub fn (mut v Point) set(u Point) Point {
v = u
return v
}
// `new_identity_point` returns a new Point set to the identity.
// new_identity_point returns a new Point set to the identity.
pub fn new_identity_point() Point {
mut p := Point{}
return p.set(edwards25519.id_point)
}
// `new_generator_point` returns a new Point set to the canonical generator.
// new_generator_point returns a new Point set to the canonical generator.
pub fn new_generator_point() Point {
mut p := Point{}
return p.set(edwards25519.gen_point)
@ -200,7 +199,7 @@ fn (mut v AffineCached) zero() AffineCached {
// Encoding.
// `bytes` returns the canonical 32-byte encoding of v, according to RFC 8032,
// bytes returns the canonical 32-byte encoding of v, according to RFC 8032,
// Section 5.1.2.
pub fn (mut v Point) bytes() []byte {
// This function is outlined to make the allocations inline in the caller
@ -298,7 +297,7 @@ fn (mut v AffineCached) from_p3(p Point) AffineCached {
// (Re)addition and subtraction.
// `add` sets v = p + q, and returns v.
// add sets v = p + q, and returns v.
pub fn (mut v Point) add(p Point, q Point) Point {
check_initialized(p, q)
mut pc := ProjectiveCached{}
@ -309,7 +308,7 @@ pub fn (mut v Point) add(p Point, q Point) Point {
return v.from_p1(result)
}
// `subtract` sets v = p - q, and returns v.
// subtract sets v = p - q, and returns v.
pub fn (mut v Point) subtract(p Point, q Point) Point {
check_initialized(p, q)
mut pc := ProjectiveCached{}
@ -444,7 +443,7 @@ fn (mut v ProjectiveP1) double(p ProjectiveP2) ProjectiveP1 {
// Negation.
// `negate` sets v = -p, and returns v.
// negate sets v = -p, and returns v.
pub fn (mut v Point) negate(p Point) Point {
check_initialized(p)
v.x.negate(p.x)
@ -454,7 +453,7 @@ pub fn (mut v Point) negate(p Point) Point {
return v
}
// `equal` returns 1 if v is equivalent to u, and 0 otherwise.
// equal returns 1 if v is equivalent to u, and 0 otherwise.
pub fn (mut v Point) equal(u Point) int {
check_initialized(v, u)

View File

@ -21,7 +21,7 @@ mut:
s [32]byte
}
const (
pub const (
sc_zero = Scalar{
s: [byte(0), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0]!
@ -38,52 +38,52 @@ const (
}
)
// `new_scalar` return new zero scalar
// new_scalar return new zero scalar
pub fn new_scalar() Scalar {
return Scalar{}
}
// `add` sets s = x + y mod l, and returns s.
// add sets s = x + y mod l, and returns s.
pub fn (mut s Scalar) add(x Scalar, y Scalar) Scalar {
// s = 1 * x + y mod l
sc_mul_add(mut s.s, edwards25519.sc_one.s, x.s, y.s)
return s
}
// `multiply_add` sets s = x * y + z mod l, and returns s.
// multiply_add sets s = x * y + z mod l, and returns s.
pub fn (mut s Scalar) multiply_add(x Scalar, y Scalar, z Scalar) Scalar {
sc_mul_add(mut s.s, x.s, y.s, z.s)
return s
}
// `subtract` sets s = x - y mod l, and returns s.
// subtract sets s = x - y mod l, and returns s.
pub fn (mut s Scalar) subtract(x Scalar, y Scalar) Scalar {
// s = -1 * y + x mod l
sc_mul_add(mut s.s, edwards25519.sc_minus_one.s, y.s, x.s)
return s
}
// `negate` sets s = -x mod l, and returns s.
// negate sets s = -x mod l, and returns s.
pub fn (mut s Scalar) negate(x Scalar) Scalar {
// s = -1 * x + 0 mod l
sc_mul_add(mut s.s, edwards25519.sc_minus_one.s, x.s, edwards25519.sc_zero.s)
return s
}
// `multiply` sets s = x * y mod l, and returns s.
// multiply sets s = x * y mod l, and returns s.
pub fn (mut s Scalar) multiply(x Scalar, y Scalar) Scalar {
// s = x * y + 0 mod l
sc_mul_add(mut s.s, x.s, y.s, edwards25519.sc_zero.s)
return s
}
// `set` sets s = x, and returns s.
// set sets s = x, and returns s.
pub fn (mut s Scalar) set(x Scalar) Scalar {
s = x
return s
}
// `set_uniform_bytes` sets s to an uniformly distributed value given 64 uniformly
// set_uniform_bytes sets s to an uniformly distributed value given 64 uniformly
// distributed random bytes. If x is not of the right length, set_uniform_bytes
// returns an error, and the receiver is unchanged.
pub fn (mut s Scalar) set_uniform_bytes(x []byte) ?Scalar {
@ -99,7 +99,7 @@ pub fn (mut s Scalar) set_uniform_bytes(x []byte) ?Scalar {
return s
}
// `set_canonical_bytes` sets s = x, where x is a 32-byte little-endian encoding of
// set_canonical_bytes sets s = x, where x is a 32-byte little-endian encoding of
// s, and returns s. If x is not a canonical encoding of s, set_canonical_bytes
// returns an error, and the receiver is unchanged.
pub fn (mut s Scalar) set_canonical_bytes(x []byte) ?Scalar {
@ -120,7 +120,7 @@ pub fn (mut s Scalar) set_canonical_bytes(x []byte) ?Scalar {
return s
}
// `is_reduced` returns whether the given scalar is reduced modulo l.
// is_reduced returns whether the given scalar is reduced modulo l.
fn is_reduced(s Scalar) bool {
for i := s.s.len - 1; i >= 0; i-- {
if s.s[i] > edwards25519.sc_minus_one.s[i] {
@ -141,7 +141,7 @@ fn is_reduced(s Scalar) bool {
return true
}
// `set_bytes_with_clamping` applies the buffer pruning described in RFC 8032,
// set_bytes_with_clamping applies the buffer pruning described in RFC 8032,
// Section 5.1.5 (also known as clamping) and sets s to the result. The input
// must be 32 bytes, and it is not modified. If x is not of the right length,
// `set_bytes_with_clamping` returns an error, and the receiver is unchanged.
@ -173,14 +173,14 @@ pub fn (mut s Scalar) set_bytes_with_clamping(x []byte) ?Scalar {
return s
}
// `bytes` returns the canonical 32-byte little-endian encoding of s.
// bytes returns the canonical 32-byte little-endian encoding of s.
pub fn (mut s Scalar) bytes() []byte {
mut buf := []byte{len: 32}
copy(buf, s.s[..])
return buf
}
// `equal` returns 1 if s and t are equal, and 0 otherwise.
// equal returns 1 if s and t are equal, and 0 otherwise.
pub fn (s Scalar) equal(t Scalar) int {
return subtle.constant_time_compare(s.s[..], t.s[..])
}
@ -977,7 +977,7 @@ fn sc_reduce(mut out [32]byte, mut s []byte) {
// non_adjacent_form computes a width-w non-adjacent form for this scalar.
//
// w must be between 2 and 8, or non_adjacent_form will panic.
fn (mut s Scalar) non_adjacent_form(w u32) []i8 {
pub fn (mut s Scalar) non_adjacent_form(w u32) []i8 {
// This implementation is adapted from the one
// in curve25519-dalek and is documented there:
// https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871

View File

@ -8,7 +8,7 @@ mut:
initonce sync.Once
}
// `basepoint_table` is a set of 32 affineLookupTables, where table i is generated
// basepoint_table is a set of 32 affineLookupTables, where table i is generated
// from 256i * basepoint. It is precomputed the first time it's used.
fn basepoint_table() []AffineLookupTable {
mut bpt := &BasepointTablePrecomp{
@ -39,7 +39,7 @@ fn basepoint_table() []AffineLookupTable {
return bpt.table
}
// `scalar_base_mult` sets v = x * B, where B is the canonical generator, and
// scalar_base_mult sets v = x * B, where B is the canonical generator, and
// returns v.
//
// The scalar multiplication is done in constant time.
@ -92,7 +92,7 @@ pub fn (mut v Point) scalar_base_mult(mut x Scalar) Point {
return v
}
// `scalar_mult` sets v = x * q, and returns v.
// scalar_mult sets v = x * q, and returns v.
//
// The scalar multiplication is done in constant time.
pub fn (mut v Point) scalar_mult(mut x Scalar, q Point) Point {
@ -149,7 +149,7 @@ fn basepoint_naf_table() NafLookupTable8 {
return bnft.table
}
// `vartime_double_scalar_base_mult` sets v = a * A + b * B, where B is the canonical
// vartime_double_scalar_base_mult sets v = a * A + b * B, where B is the canonical
// generator, and returns v.
//
// Execution time depends on the inputs.