github.com/cloudflare/circl@v1.5.0/ecc/goldilocks/curve.go (about) 1 // Package goldilocks provides elliptic curve operations over the goldilocks curve. 2 package goldilocks 3 4 import fp "github.com/cloudflare/circl/math/fp448" 5 6 // Curve is the Goldilocks curve x^2+y^2=z^2-39081x^2y^2. 7 type Curve struct{} 8 9 // Identity returns the identity point. 10 func (Curve) Identity() *Point { 11 return &Point{ 12 y: fp.One(), 13 z: fp.One(), 14 } 15 } 16 17 // IsOnCurve returns true if the point lies on the curve. 18 func (Curve) IsOnCurve(P *Point) bool { 19 x2, y2, t, t2, z2 := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{} 20 rhs, lhs := &fp.Elt{}, &fp.Elt{} 21 fp.Mul(t, &P.ta, &P.tb) // t = ta*tb 22 fp.Sqr(x2, &P.x) // x^2 23 fp.Sqr(y2, &P.y) // y^2 24 fp.Sqr(z2, &P.z) // z^2 25 fp.Sqr(t2, t) // t^2 26 fp.Add(lhs, x2, y2) // x^2 + y^2 27 fp.Mul(rhs, t2, ¶mD) // dt^2 28 fp.Add(rhs, rhs, z2) // z^2 + dt^2 29 fp.Sub(lhs, lhs, rhs) // x^2 + y^2 - (z^2 + dt^2) 30 eq0 := fp.IsZero(lhs) 31 32 fp.Mul(lhs, &P.x, &P.y) // xy 33 fp.Mul(rhs, t, &P.z) // tz 34 fp.Sub(lhs, lhs, rhs) // xy - tz 35 eq1 := fp.IsZero(lhs) 36 return eq0 && eq1 37 } 38 39 // Generator returns the generator point. 40 func (Curve) Generator() *Point { 41 return &Point{ 42 x: genX, 43 y: genY, 44 z: fp.One(), 45 ta: genX, 46 tb: genY, 47 } 48 } 49 50 // Order returns the number of points in the prime subgroup. 51 func (Curve) Order() Scalar { return order } 52 53 // Double returns 2P. 54 func (Curve) Double(P *Point) *Point { R := *P; R.Double(); return &R } 55 56 // Add returns P+Q. 57 func (Curve) Add(P, Q *Point) *Point { R := *P; R.Add(Q); return &R } 58 59 // ScalarMult returns kP. This function runs in constant time. 60 func (e Curve) ScalarMult(k *Scalar, P *Point) *Point { 61 k4 := &Scalar{} 62 k4.divBy4(k) 63 return e.pull(twistCurve{}.ScalarMult(k4, e.push(P))) 64 } 65 66 // ScalarBaseMult returns kG where G is the generator point. This function runs in constant time. 67 func (e Curve) ScalarBaseMult(k *Scalar) *Point { 68 k4 := &Scalar{} 69 k4.divBy4(k) 70 return e.pull(twistCurve{}.ScalarBaseMult(k4)) 71 } 72 73 // CombinedMult returns mG+nP, where G is the generator point. This function is non-constant time. 74 func (e Curve) CombinedMult(m, n *Scalar, P *Point) *Point { 75 m4 := &Scalar{} 76 n4 := &Scalar{} 77 m4.divBy4(m) 78 n4.divBy4(n) 79 return e.pull(twistCurve{}.CombinedMult(m4, n4, twistCurve{}.pull(P))) 80 }