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, &paramD) // 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  }