diff --git a/ecc/goldilocks/curve.go b/ecc/goldilocks/curve.go index d855844bd..a10e8c035 100644 --- a/ecc/goldilocks/curve.go +++ b/ecc/goldilocks/curve.go @@ -1,9 +1,9 @@ -// Package goldilocks provides elliptic curve operations over the goldilocks curve. package goldilocks import fp "github.com/cloudflare/circl/math/fp448" -// Curve is the Goldilocks curve x^2+y^2=z^2-39081x^2y^2. +// Curve provides operations on the Goldilocks curve. +// Curve is a zero-length datatype. type Curve struct{} // Identity returns the identity point. @@ -31,8 +31,8 @@ func (Curve) IsOnCurve(P *Point) bool { return isOnCurve(&P.x, &P.y, &P.ta, &P.t // Order returns the number of points in the prime subgroup. func (Curve) Order() Scalar { return order } -// Double returns 2P. -func (Curve) Double(P *Point) *Point { R := *P; R.Double(); return &R } +// Double returns R = 2P. +func (Curve) Double(R, P *Point) *Point { R := *P; R.Double(); return &R } // Add returns P+Q. func (Curve) Add(P, Q *Point) *Point { R := *P; R.Add(Q); return &R } diff --git a/ecc/goldilocks/decaf.go b/ecc/goldilocks/decaf.go index 55452b710..60d439b5d 100644 --- a/ecc/goldilocks/decaf.go +++ b/ecc/goldilocks/decaf.go @@ -1,49 +1,53 @@ package goldilocks -import ( - fp "github.com/cloudflare/circl/math/fp448" -) +import fp "github.com/cloudflare/circl/math/fp448" -// Decaf provides a prime-order group. -// Internally, the implementation uses the twist of goldilocks curve. +// DecafEncodingSize is the size (in bytes) for storing a decaf element. +const DecafEncodingSize = fp.Size + +// Decaf provides operations of a prime-order group from goldilocks curve. +// Its internal implementation uses the twist of the goldilocks curve. +// This uses version 1.1 of the encoding. Decaf is a zero-length datatype. type Decaf struct{ c twistCurve } -// Elt is an element of the decaf group. +// Elt is an element of the Decaf group. It must be always initialized using +// one of the Decaf functions. type Elt struct{ p twistPoint } func (e Elt) String() string { return e.p.String() } -// IsValid is +// IsValid returns True if a is a valid element of the group. func (d Decaf) IsValid(a *Elt) bool { return d.c.IsOnCurve(&a.p) } -// IsIdentity is +// IsIdentity returns True if a is the identity of the group. func (d Decaf) IsIdentity(a *Elt) bool { return fp.IsZero(&a.p.x) } -// Identity is +// Identity returns the identity element of the group. func (d Decaf) Identity() *Elt { return &Elt{*d.c.Identity()} } -// Generator is +// Generator returns the generator element of the group. func (d Decaf) Generator() *Elt { return &Elt{*d.c.pull(Curve{}.Generator())} } -// Order is +// Order returns a scalar with the order of the group. func (d Decaf) Order() Scalar { return order } -// Add is +// Add calculates c=a+b, where + is the group operation. func (d Decaf) Add(c, a, b *Elt) { c.p = a.p; c.p.Add(&b.p) } -// Double is +// Double calculates c=a+a, where + is the group operation. func (d Decaf) Double(c, a *Elt) { c.p = a.p; c.p.Double() } -// Neg is +// Neg calculates c=-a, where - is the inverse of the group operation. func (d Decaf) Neg(c, a *Elt) { c.p = a.p; c.p.cneg(1) } -// Mul is +// Mul calculates c=n*a, where * is scalar multiplication on the group. func (d Decaf) Mul(c *Elt, n *Scalar, a *Elt) { c.p = *d.c.ScalarMult(n, &a.p) } -// MulGen is +// MulGen calculates c=n*g, where * is scalar multiplication on the group, +// and g is the generator of the group. func (d Decaf) MulGen(c *Elt, n *Scalar) { c.p = *d.c.ScalarBaseMult(n) } -// AreEqual is +// AreEqual returns True if a=b, where = is an equivalence relation. func (d Decaf) AreEqual(a, b *Elt) bool { l, r := &fp.Elt{}, &fp.Elt{} fp.Mul(l, &a.p.x, &b.p.y) @@ -52,7 +56,7 @@ func (d Decaf) AreEqual(a, b *Elt) bool { return fp.IsZero(l) } -// Marshal is +// Marshal returns a unique encoding of the element e. func (e *Elt) Marshal() []byte { x, ta, tb, z := e.p.x, e.p.ta, e.p.tb, e.p.z one, t, t2, s := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{} @@ -84,17 +88,18 @@ func (e *Elt) Marshal() []byte { return encS[:] } -// Unmarshal is +// Unmarshal if succeeds returns nil and constructs an element e from an +// encoding stored in a slice b of DecafEncodingSize bytes. func (e *Elt) Unmarshal(b []byte) error { - if len(b) < fp.Size { + if len(b) < DecafEncodingSize { return errInvalidDecoding } s := &fp.Elt{} - copy(s[:], b[:fp.Size]) + copy(s[:], b[:DecafEncodingSize]) isNeg := fp.Parity(s) p := fp.P() - if isNeg == 1 || !isLessThan(b[:fp.Size], p[:]) { + if isNeg == 1 || !isLessThan(b[:DecafEncodingSize], p[:]) { return errInvalidDecoding } diff --git a/ecc/goldilocks/doc.go b/ecc/goldilocks/doc.go new file mode 100644 index 000000000..83844e00b --- /dev/null +++ b/ecc/goldilocks/doc.go @@ -0,0 +1,53 @@ +// Package goldilocks provides elliptic curve operations over the goldilocks +// curve and the decaf group. +// +// Goldilocks Curve +// +// The goldilocks curve is defined over GF(2^448-2^224-1) by the twisted Edwards +// curve +// Goldilocks: ax^2+y^2 = 1 + dx^2y^2, where a=1 and d=-39081. +// This curve was proposed by Hamburg (1) and is also known as edwards448 +// after RFC-7748 (2). +// +// order = 4*(2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d) +// G = (x,y) = +// (224580040295924300187604334099896036246789641632564134246125461 +// 686950415467406032909029192869357953282578032075146446173674602635 +// 247710 +// +// Y(P) 298819210078481492676017930443930673437544040154080242095928241 +// 372331506189835876003536878655418784733982303233503462500531545062 +// 832660 + +// The datatypes Curve, Point, and Scalar provide methods to perform arithmetic +// operations on the Goldilocks curve. +// +// Decaf Group +// +// Decaf (3) is a prime-order group constructed as a quotient of groups. A Decaf +// element can be represented by any point in the coset P+J[2], where J is a +// Jacobi quartic and J[2] are its 2-torsion points. +// Since P+J[2] has four points, Decaf specifies rules to choose one canonical +// representative, which has a unique encoding. Two representations are +// equivalent if they belong to the same coset. +// +// The types Decaf, Elt, and Scalar provide methods to perform arithmetic +// operations on the Decaf group. +// +// Internals +// +// Both Goldilocks and Decaf use as internal representation the curve +// 4Iso-Goldilocks: ax^2+y^2 = 1 + dx^2y^2, where a=-1 and d=-39082. +// This curve is 4-degree isogeous to the Goldilocks curve, and 2-degree +// isogeneous to the Jacobi quartic. The 4Iso-Goldilocks curve was chosen as +// provides faster arithmetic operations. +// +// References +// +// (1) https://www.shiftleft.org/papers/goldilocks +// +// (2) https://tools.ietf.org/html/rfc7748 +// +// (3) https://doi.org/10.1007/978-3-662-47989-6_34 +// +package goldilocks