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. // `PublicKey` is Ed25519 public keys.
pub type PublicKey = []byte 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 { pub fn (p PublicKey) equal(x []byte) bool {
return subtle.constant_time_compare(p, PublicKey(x)) == 1 return subtle.constant_time_compare(p, PublicKey(x)) == 1
} }
// `PrivateKey` is Ed25519 private keys // PrivateKey is Ed25519 private keys
pub type PrivateKey = []byte pub type PrivateKey = []byte
// seed returns the private key seed corresponding to priv. RFC 8032's private keys correspond to seeds // seed returns the private key seed corresponding to priv.
// in this module. // RFC 8032's private keys correspond to seeds in this module.
pub fn (priv PrivateKey) seed() []byte { pub fn (priv PrivateKey) seed() []byte {
mut seed := []byte{len: ed25519.seed_size} mut seed := []byte{len: ed25519.seed_size}
copy(seed, priv[..32]) copy(seed, priv[..32])
return seed return seed
} }
// `public_key` returns the []byte corresponding to priv. // public_key returns the []byte corresponding to priv.
pub fn (priv PrivateKey) public_key() []byte { pub fn (priv PrivateKey) public_key() PublicKey {
assert priv.len == ed25519.private_key_size assert priv.len == ed25519.private_key_size
mut publickey := []byte{len: ed25519.public_key_size} mut publickey := []byte{len: ed25519.public_key_size}
copy(publickey, priv[32..]) 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 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 { pub fn (priv PrivateKey) sign(message []byte) ?[]byte {
/* /*
if opts.HashFunc() != crypto.Hash(0) { if opts.HashFunc() != crypto.Hash(0) {
@ -59,7 +59,7 @@ pub fn (priv PrivateKey) sign(message []byte) ?[]byte {
return sign(priv, message) 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 { pub fn sign(privatekey PrivateKey, message []byte) ?[]byte {
mut signature := []byte{len: ed25519.signature_size} mut signature := []byte{len: ed25519.signature_size}
sign_generic(signature, privatekey, message) ? sign_generic(signature, privatekey, message) ?
@ -107,7 +107,7 @@ fn sign_generic(signature []byte, privatekey []byte, message []byte) ? {
copy(signature[32..], ss.bytes()) 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 { pub fn verify(publickey PublicKey, message []byte, sig []byte) ?bool {
if publickey.len != ed25519.public_key_size { if publickey.len != ed25519.public_key_size {
return error('ed25519: bad public key length: $publickey.len') 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 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) { pub fn generate_key() ?(PublicKey, PrivateKey) {
mut seed := rand.bytes(ed25519.seed_size) ? mut seed := rand.bytes(ed25519.seed_size) ?
@ -154,7 +154,7 @@ pub fn generate_key() ?(PublicKey, PrivateKey) {
return 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 // correspond to seeds in this module
pub fn new_key_from_seed(seed []byte) PrivateKey { pub fn new_key_from_seed(seed []byte) PrivateKey {
// Outline the function body so that the returned key can be stack-allocated. // 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() pubkey2 := priv2.public_key()
if pubkey != pubkey2 { if ed25519.PublicKey(pubkey) != pubkey2 {
return false return false
} }

View File

@ -18,7 +18,7 @@ struct Uint128 {
// are allowed to alias. // are allowed to alias.
// //
// The zero value is a valid zero element. // The zero value is a valid zero element.
struct Element { pub struct Element {
mut: mut:
// An element t represents the integer // An element t represents the integer
// t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204 // 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 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. // identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry.
fn (mut v Element) carry_propagate_generic() Element { fn (mut v Element) carry_propagate_generic() Element {
c0 := v.l0 >> 51 c0 := v.l0 >> 51
@ -330,19 +330,19 @@ fn fe_square_generic(a Element) Element {
} }
// zero sets v = 0, and returns v. // zero sets v = 0, and returns v.
fn (mut v Element) zero() Element { pub fn (mut v Element) zero() Element {
v = edwards25519.fe_zero v = edwards25519.fe_zero
return v return v
} }
// one sets v = 1, and returns 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 v = edwards25519.fe_one
return v return v
} }
// reduce reduces v modulo 2^255 - 19 and returns it. // 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() v = v.carry_propagate_generic()
// After the light reduction we now have a edwards25519 element representation // After the light reduction we now have a edwards25519 element representation
@ -374,8 +374,8 @@ fn (mut v Element) reduce() Element {
return v return v
} }
// Add sets v = a + b, and returns v. // add sets v = a + b, and returns v.
fn (mut v Element) add(a Element, b Element) Element { pub fn (mut v Element) add(a Element, b Element) Element {
v.l0 = a.l0 + b.l0 v.l0 = a.l0 + b.l0
v.l1 = a.l1 + b.l1 v.l1 = a.l1 + b.l1
v.l2 = a.l2 + b.l2 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() return v.carry_propagate_generic()
} }
// Subtract sets v = a - b, and returns v. // subtract sets v = a - b, and returns v.
fn (mut v Element) subtract(a Element, b Element) Element { pub fn (mut v Element) subtract(a Element, b Element) Element {
// We first add 2 * p, to guarantee the subtraction won't underflow, and // 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). // then subtract b (which can be up to 2^255 + 2^13 * 19).
v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0 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() return v.carry_propagate_generic()
} }
// `negate` sets v = -a, and returns v. // negate sets v = -a, and returns v.
fn (mut v Element) negate(a Element) Element { pub fn (mut v Element) negate(a Element) Element {
return v.subtract(edwards25519.fe_zero, a) return v.subtract(edwards25519.fe_zero, a)
} }
// invert sets v = 1/z mod p, and returns v. // invert sets v = 1/z mod p, and returns v.
// //
// If z == 0, invert returns v = 0. // 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 // Inversion is implemented as exponentiation with exponent p 2. It uses the
// same sequence of 255 squarings and 11 multiplications as [Curve25519]. // same sequence of 255 squarings and 11 multiplications as [Curve25519].
mut z2 := Element{} mut z2 := Element{}
@ -481,13 +481,13 @@ fn (mut v Element) invert(z Element) Element {
} }
// square sets v = x * x, and returns v. // 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) v = fe_square_generic(x)
return v return v
} }
// multiply sets v = x * y, and returns 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) v = fe_mul_generic(x, y)
return v 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. // 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{} mut t0, mut t1, mut t2 := Element{}, Element{}, Element{}
t0.square(x) // x^2 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 // 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, // sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00,
// and returns r and 0. // 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{} mut a, mut b := Element{}, Element{}
// r = (u * v3) * (u * v7)^((p-5)/8) // 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. // 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 // see above notes
m := mask_64_bits(cond) m := mask_64_bits(cond)
v.l0 = (m & a.l0) | (~m & b.l0) 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. // 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) return int(v.bytes()[0] & 1)
} }
// absolute sets v to |u|, and returns v. // 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 e := Element{}
mut uk := u mut uk := u
return v.selected(e.negate(uk), uk, uk.is_negative()) return v.selected(e.negate(uk), uk, uk.is_negative())
} }
// set sets v = a, and returns v. // 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 v = a
return v return v
} }
// set_bytes sets v to x, where x is a 32-byte little-endian encoding. If x is // 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. // receiver is unchanged.
// //
// Consistent with RFC 7748, the most significant bit (the high bit of the // 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) // 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. // 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 { if x.len != 32 {
return error('edwards25519: invalid edwards25519 element input size') 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. // 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 mut u := ue
sa := u.bytes() sa := u.bytes()
sv := v.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. // 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 // mut u := ue
m := mask_64_bits(cond) m := mask_64_bits(cond)
mut t := m & (v.l0 ^ u.l0) 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. // 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) x0lo, x0hi := mul_51(x.l0, y)
x1lo, x1hi := mul_51(x.l1, y) x1lo, x1hi := mul_51(x.l1, y)
x2lo, x2hi := mul_51(x.l2, 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. // 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, // 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. // unchanged. Otherwise, set_extended_coordinates returns v.
fn (mut v Point) set_extended_coordinates(x Element, y Element, z Element, t Element) ?Point { fn (mut v Point) set_extended_coordinates(x Element, y Element, z Element, t Element) ?Point {
if !is_on_curve(x, y, z, t) { 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 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 // Curve25519 Montgomery curve, and returns its canonical 32 bytes encoding
// according to RFC 7748. // 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) 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 { pub fn (mut v Point) mult_by_cofactor(p Point) Point {
check_initialized(p) check_initialized(p)
mut result := ProjectiveP1{} mut result := ProjectiveP1{}
@ -128,7 +128,7 @@ pub fn (mut v Point) mult_by_cofactor(p Point) Point {
return v.from_p1(result) 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. // If t is zero, invert returns zero.
pub fn (mut s Scalar) invert(t Scalar) Scalar { pub fn (mut s Scalar) invert(t Scalar) Scalar {
@ -234,7 +234,7 @@ pub fn (mut s Scalar) invert(t Scalar) Scalar {
return s 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. // 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 { 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 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. // Execution time depends on the inputs.
pub fn (mut v Point) vartime_multiscalar_mult(scalars []Scalar, points []Point) Point { pub fn (mut v Point) vartime_multiscalar_mult(scalars []Scalar, points []Point) Point {

View File

@ -46,7 +46,6 @@ fn generator() ?Point {
} }
// Point types. // Point types.
struct ProjectiveP1 { struct ProjectiveP1 {
mut: mut:
x Element x Element
@ -77,7 +76,7 @@ mut:
z Element z Element
t Element t Element
// Make the type not comparable (i.e. used with == or as a map key), as // 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 // _ 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 // 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. // the receiver is unchanged. Otherwise, set_bytes returns v.
// //
// Note that set_bytes accepts all non-canonical encodings of valid points. // 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 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 { pub fn (mut v Point) set(u Point) Point {
v = u v = u
return v 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 { pub fn new_identity_point() Point {
mut p := Point{} mut p := Point{}
return p.set(edwards25519.id_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 { pub fn new_generator_point() Point {
mut p := Point{} mut p := Point{}
return p.set(edwards25519.gen_point) return p.set(edwards25519.gen_point)
@ -200,7 +199,7 @@ fn (mut v AffineCached) zero() AffineCached {
// Encoding. // 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. // Section 5.1.2.
pub fn (mut v Point) bytes() []byte { pub fn (mut v Point) bytes() []byte {
// This function is outlined to make the allocations inline in the caller // 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. // (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 { pub fn (mut v Point) add(p Point, q Point) Point {
check_initialized(p, q) check_initialized(p, q)
mut pc := ProjectiveCached{} mut pc := ProjectiveCached{}
@ -309,7 +308,7 @@ pub fn (mut v Point) add(p Point, q Point) Point {
return v.from_p1(result) 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 { pub fn (mut v Point) subtract(p Point, q Point) Point {
check_initialized(p, q) check_initialized(p, q)
mut pc := ProjectiveCached{} mut pc := ProjectiveCached{}
@ -444,7 +443,7 @@ fn (mut v ProjectiveP1) double(p ProjectiveP2) ProjectiveP1 {
// Negation. // Negation.
// `negate` sets v = -p, and returns v. // negate sets v = -p, and returns v.
pub fn (mut v Point) negate(p Point) Point { pub fn (mut v Point) negate(p Point) Point {
check_initialized(p) check_initialized(p)
v.x.negate(p.x) v.x.negate(p.x)
@ -454,7 +453,7 @@ pub fn (mut v Point) negate(p Point) Point {
return v 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 { pub fn (mut v Point) equal(u Point) int {
check_initialized(v, u) check_initialized(v, u)

View File

@ -21,7 +21,7 @@ mut:
s [32]byte s [32]byte
} }
const ( pub const (
sc_zero = Scalar{ 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, 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]! 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 { pub fn new_scalar() Scalar {
return 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 { pub fn (mut s Scalar) add(x Scalar, y Scalar) Scalar {
// s = 1 * x + y mod l // s = 1 * x + y mod l
sc_mul_add(mut s.s, edwards25519.sc_one.s, x.s, y.s) sc_mul_add(mut s.s, edwards25519.sc_one.s, x.s, y.s)
return 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 { 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) sc_mul_add(mut s.s, x.s, y.s, z.s)
return 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 { pub fn (mut s Scalar) subtract(x Scalar, y Scalar) Scalar {
// s = -1 * y + x mod l // s = -1 * y + x mod l
sc_mul_add(mut s.s, edwards25519.sc_minus_one.s, y.s, x.s) sc_mul_add(mut s.s, edwards25519.sc_minus_one.s, y.s, x.s)
return 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 { pub fn (mut s Scalar) negate(x Scalar) Scalar {
// s = -1 * x + 0 mod l // s = -1 * x + 0 mod l
sc_mul_add(mut s.s, edwards25519.sc_minus_one.s, x.s, edwards25519.sc_zero.s) sc_mul_add(mut s.s, edwards25519.sc_minus_one.s, x.s, edwards25519.sc_zero.s)
return 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 { pub fn (mut s Scalar) multiply(x Scalar, y Scalar) Scalar {
// s = x * y + 0 mod l // s = x * y + 0 mod l
sc_mul_add(mut s.s, x.s, y.s, edwards25519.sc_zero.s) sc_mul_add(mut s.s, x.s, y.s, edwards25519.sc_zero.s)
return 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 { pub fn (mut s Scalar) set(x Scalar) Scalar {
s = x s = x
return s 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 // distributed random bytes. If x is not of the right length, set_uniform_bytes
// returns an error, and the receiver is unchanged. // returns an error, and the receiver is unchanged.
pub fn (mut s Scalar) set_uniform_bytes(x []byte) ?Scalar { 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 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 // s, and returns s. If x is not a canonical encoding of s, set_canonical_bytes
// returns an error, and the receiver is unchanged. // returns an error, and the receiver is unchanged.
pub fn (mut s Scalar) set_canonical_bytes(x []byte) ?Scalar { 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 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 { fn is_reduced(s Scalar) bool {
for i := s.s.len - 1; i >= 0; i-- { for i := s.s.len - 1; i >= 0; i-- {
if s.s[i] > edwards25519.sc_minus_one.s[i] { if s.s[i] > edwards25519.sc_minus_one.s[i] {
@ -141,7 +141,7 @@ fn is_reduced(s Scalar) bool {
return true 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 // 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, // 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. // `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 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 { pub fn (mut s Scalar) bytes() []byte {
mut buf := []byte{len: 32} mut buf := []byte{len: 32}
copy(buf, s.s[..]) copy(buf, s.s[..])
return buf 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 { pub fn (s Scalar) equal(t Scalar) int {
return subtle.constant_time_compare(s.s[..], t.s[..]) 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. // 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. // 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 // This implementation is adapted from the one
// in curve25519-dalek and is documented there: // in curve25519-dalek and is documented there:
// https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871 // https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871

View File

@ -8,7 +8,7 @@ mut:
initonce sync.Once 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. // from 256i * basepoint. It is precomputed the first time it's used.
fn basepoint_table() []AffineLookupTable { fn basepoint_table() []AffineLookupTable {
mut bpt := &BasepointTablePrecomp{ mut bpt := &BasepointTablePrecomp{
@ -39,7 +39,7 @@ fn basepoint_table() []AffineLookupTable {
return bpt.table 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. // returns v.
// //
// The scalar multiplication is done in constant time. // 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 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. // The scalar multiplication is done in constant time.
pub fn (mut v Point) scalar_mult(mut x Scalar, q Point) Point { 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 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. // generator, and returns v.
// //
// Execution time depends on the inputs. // Execution time depends on the inputs.