crypto.ed25519.internal.edwards25519 #
Description
crypto.ed25519.internal.edwards25519
provides arithmetic primitives operations that are useful to implement cryptographic schemes over the edwards25519 elliptic curve, including:
- Arithmetic functions for point addition, doubling, negation, scalar multiplicationwith an arbitrary point, with the base point, etc.2. Arithmetic functions dealing with scalars modulo the prime order L of the base point.
This modules was port of Golang edwards25519
library from edwards25519 to the V language.
About Edwards25519
Twisted Edwards curves are a family of elliptic curves allowing complete addition formulas without any special case and no point at infinity. Curve edwards25519 is based on prime 2^255 - 19 for efficient implementation. Equation and parameters are given in RFC 7748.
Constants #
const sc_zero = Scalar{
s: [u8(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]!
}
const sc_one = Scalar{
s: [u8(1), 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]!
}
const sc_minus_one = Scalar{
s: [u8(236), 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16]!
}
fn new_generator_point #
fn new_generator_point() Point
new_generator_point returns a new Point set to the canonical generator.
fn new_identity_point #
fn new_identity_point() Point
new_identity_point returns a new Point set to the identity.
fn new_scalar #
fn new_scalar() Scalar
new_scalar return new zero scalar
fn (Scalar) add #
fn (mut s Scalar) add(x Scalar, y Scalar) Scalar
add sets s = x + y mod l, and returns s.
fn (Scalar) bytes #
fn (mut s Scalar) bytes() []u8
bytes returns the canonical 32-byte little-endian encoding of s.
fn (Scalar) equal #
fn (s Scalar) equal(t Scalar) int
equal returns 1 if s and t are equal, and 0 otherwise.
fn (Scalar) invert #
fn (mut s Scalar) invert(t Scalar) Scalar
invert sets s to the inverse of a nonzero scalar v, and returns s.
If t is zero, invert returns zero.
fn (Scalar) multiply #
fn (mut s Scalar) multiply(x Scalar, y Scalar) Scalar
multiply sets s = x * y mod l, and returns s.
fn (Scalar) multiply_add #
fn (mut s Scalar) multiply_add(x Scalar, y Scalar, z Scalar) Scalar
multiply_add sets s = x * y + z mod l, and returns s.
fn (Scalar) negate #
fn (mut s Scalar) negate(x Scalar) Scalar
negate sets s = -x mod l, and returns s.
fn (Scalar) non_adjacent_form #
fn (mut s Scalar) non_adjacent_form(w u32) []i8
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 (Scalar) set #
fn (mut s Scalar) set(x Scalar) Scalar
set sets s = x, and returns s.
fn (Scalar) set_bytes_with_clamping #
fn (mut s Scalar) set_bytes_with_clamping(x []u8) !Scalar
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.
Note that since Scalar values are always reduced modulo the prime order of the curve, the resulting value will not preserve any of the cofactor-clearing properties that clamping is meant to provide. It will however work as expected as long as it is applied to points on the prime order subgroup, like in Ed25519. In fact, it is lost to history why RFC 8032 adopted the irrelevant RFC 7748 clamping, but it is now required for compatibility.
fn (Scalar) set_canonical_bytes #
fn (mut s Scalar) set_canonical_bytes(x []u8) !Scalar
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.
fn (Scalar) set_uniform_bytes #
fn (mut s Scalar) set_uniform_bytes(x []u8) !Scalar
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.
fn (Scalar) subtract #
fn (mut s Scalar) subtract(x Scalar, y Scalar) Scalar
subtract sets s = x - y mod l, and returns s.
struct Element #
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
//
// Between operations, all limbs are expected to be lower than 2^52.
l0 u64
l1 u64
l2 u64
l3 u64
l4 u64
}
Element represents an element of the edwards25519 GF(2^255-19). Note that this is not a cryptographically secure group, and should only be used to interact with edwards25519.Point coordinates.
This type works similarly to math/big.Int, and all arguments and receivers are allowed to alias.
The zero value is a valid zero element.
fn (Element) zero #
fn (mut v Element) zero() Element
zero sets v = 0, and returns v.
fn (Element) one #
fn (mut v Element) one() Element
one sets v = 1, and returns v.
fn (Element) reduce #
fn (mut v Element) reduce() Element
reduce reduces v modulo 2^255 - 19 and returns it.
fn (Element) add #
fn (mut v Element) add(a Element, b Element) Element
add sets v = a + b, and returns v.
fn (Element) subtract #
fn (mut v Element) subtract(a Element, b Element) Element
subtract sets v = a - b, and returns v.
fn (Element) negate #
fn (mut v Element) negate(a Element) Element
negate sets v = -a, and returns v.
fn (Element) invert #
fn (mut v Element) invert(z Element) Element
invert sets v = 1/z mod p, and returns v.
If z == 0, invert returns v = 0.
fn (Element) square #
fn (mut v Element) square(x Element) Element
square sets v = x * x, and returns v.
fn (Element) multiply #
fn (mut v Element) multiply(x Element, y Element) Element
multiply sets v = x * y, and returns v.
fn (Element) pow_22523 #
fn (mut v Element) pow_22523(x Element) Element
pow_22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
fn (Element) sqrt_ratio #
fn (mut r Element) sqrt_ratio(u Element, v Element) (Element, int)
sqrt_ratio sets r to the non-negative square root of the ratio of u and v.
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 (Element) selected #
fn (mut v Element) selected(a Element, b Element, cond int) Element
selected sets v to a if cond == 1, and to b if cond == 0.
fn (Element) is_negative #
fn (mut v Element) is_negative() int
is_negative returns 1 if v is negative, and 0 otherwise.
fn (Element) absolute #
fn (mut v Element) absolute(u Element) Element
absolute sets v to |u|, and returns v.
fn (Element) set #
fn (mut v Element) set(a Element) Element
set sets v = a, and returns v.
fn (Element) set_bytes #
fn (mut v Element) set_bytes(x []u8) !Element
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 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 (Element) bytes #
fn (mut v Element) bytes() []u8
bytes returns the canonical 32-byte little-endian encoding of v.
fn (Element) equal #
fn (mut v Element) equal(ue Element) int
equal returns 1 if v and u are equal, and 0 otherwise.
fn (Element) swap #
fn (mut v Element) swap(mut u Element, cond int)
swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
fn (Element) mult_32 #
fn (mut v Element) mult_32(x Element, y u32) Element
mult_32 sets v = x * y, and returns v.
struct Point #
struct Point {
mut:
// The point is internally represented in extended coordinates (x, y, z, T)
// where x = x/z, y = y/z, and xy = T/z per https://eprint.iacr.org/2008/522.
x Element
y Element
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 values.
// _ incomparable
}
Point represents a point on the edwards25519 curve.
This type works similarly to math/big.Int, and all arguments and receivers are allowed to alias.
The zero value is NOT valid, and it may be used only as a receiver.
fn (Point) add #
fn (mut v Point) add(p Point, q Point) Point
add sets v = p + q, and returns v.
fn (Point) bytes #
fn (mut v Point) bytes() []u8
bytes returns the canonical 32-byte encoding of v, according to RFC 8032, Section 5.1.2.
fn (Point) bytes_montgomery #
fn (mut v Point) bytes_montgomery() []u8
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.
Note that bytes_montgomery only encodes the u-coordinate, so v and -v encode to the same value. If v is the identity point, bytes_montgomery returns 32 zero bytes, analogously to the X25519 function.
fn (Point) equal #
fn (mut v Point) equal(u Point) int
equal returns 1 if v is equivalent to u, and 0 otherwise.
fn (Point) mult_by_cofactor #
fn (mut v Point) mult_by_cofactor(p Point) Point
mult_by_cofactor sets v = 8 * p, and returns v.
fn (Point) multi_scalar_mult #
fn (mut v Point) multi_scalar_mult(scalars []Scalar, points []Point) Point
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.
fn (Point) negate #
fn (mut v Point) negate(p Point) Point
negate sets v = -p, and returns v.
fn (Point) scalar_base_mult #
fn (mut v Point) scalar_base_mult(mut x Scalar) Point
scalar_base_mult sets v = x * B, where B is the canonical generator, and returns v.
The scalar multiplication is done in constant time.
fn (Point) scalar_mult #
fn (mut v Point) scalar_mult(mut x Scalar, q Point) Point
scalar_mult sets v = x * q, and returns v.
The scalar multiplication is done in constant time.
fn (Point) set #
fn (mut v Point) set(u Point) Point
set sets v = u, and returns v.
fn (Point) set_bytes #
fn (mut v Point) set_bytes(x []u8) !Point
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 an error and the receiver is unchanged. Otherwise, set_bytes returns v.
Note that set_bytes accepts all non-canonical encodings of valid points. That is, it follows decoding rules that match most implementations in the ecosystem rather than RFC 8032.
fn (Point) subtract #
fn (mut v Point) subtract(p Point, q Point) Point
subtract sets v = p - q, and returns v.
fn (Point) vartime_double_scalar_base_mult #
fn (mut v Point) vartime_double_scalar_base_mult(xa Scalar, aa Point, xb Scalar) Point
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.
fn (Point) vartime_multiscalar_mult #
fn (mut v Point) vartime_multiscalar_mult(scalars []Scalar, points []Point) Point
vartime_multiscalar_mult sets v = sum(scalars[i] * points[i]), and returns v.
Execution time depends on the inputs.