Skip to content

Commit

Permalink
Adding goldilocks documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
armfazh committed Jul 24, 2020
1 parent a62d6bd commit a99153c
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 26 deletions.
8 changes: 4 additions & 4 deletions ecc/goldilocks/curve.go
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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 }
Expand Down
49 changes: 27 additions & 22 deletions ecc/goldilocks/decaf.go
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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{}
Expand Down Expand Up @@ -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
}

Expand Down
53 changes: 53 additions & 0 deletions ecc/goldilocks/doc.go
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit a99153c

Please sign in to comment.