From be377bc6d9e7e9af0e1d73922fa30ff4e3884e83 Mon Sep 17 00:00:00 2001 From: armfazh Date: Tue, 9 Jun 2020 23:36:17 -0700 Subject: [PATCH] ted448 point public fields. --- .etc/golangci.yml | 3 +- ecc/decaf/decaf.go | 41 ++++++++++++++------------- internal/ted448/curve.go | 16 +++++------ internal/ted448/point.go | 61 ++++++++++++++++------------------------ 4 files changed, 54 insertions(+), 67 deletions(-) diff --git a/.etc/golangci.yml b/.etc/golangci.yml index 14aa62938..0c53dbd68 100644 --- a/.etc/golangci.yml +++ b/.etc/golangci.yml @@ -18,8 +18,7 @@ linters-settings: statements: 80 nestif: min-complexity: 6 - dogsled: - max-blank-identifiers: 3 + issues: max-issues-per-linter: 0 max-same-issues: 0 diff --git a/ecc/decaf/decaf.go b/ecc/decaf/decaf.go index 383248868..ce686f2e2 100644 --- a/ecc/decaf/decaf.go +++ b/ecc/decaf/decaf.go @@ -10,6 +10,8 @@ package decaf import ( + "unsafe" + "github.com/cloudflare/circl/internal/ted448" fp "github.com/cloudflare/circl/math/fp448" ) @@ -55,19 +57,13 @@ func Mul(c *Elt, n *Scalar, a *Elt) { ted448.ScalarMult(&c.p, n, &a.p) } func MulGen(c *Elt, n *Scalar) { ted448.ScalarBaseMult(&c.p, n) } // IsIdentity returns True if e is the identity of the group. -func (e *Elt) IsIdentity() bool { - x, y, _, _, z := e.p.Coordinates() - return fp.IsZero(&x) && !fp.IsZero(&y) && !fp.IsZero(&z) -} +func (e *Elt) IsIdentity() bool { return fp.IsZero(&e.p.X) && !fp.IsZero(&e.p.Y) && !fp.IsZero(&e.p.Z) } // IsEqual returns True if e=a, where = is an equivalence relation. func (e *Elt) IsEqual(a *Elt) bool { - x1, y1, _, _, _ := e.p.Coordinates() - x2, y2, _, _, _ := a.p.Coordinates() - l, r := &fp.Elt{}, &fp.Elt{} - fp.Mul(l, &x1, &y2) - fp.Mul(r, &x2, &y1) + fp.Mul(l, &e.p.X, &a.p.Y) + fp.Mul(r, &a.p.X, &e.p.Y) fp.Sub(l, l, r) return fp.IsZero(l) } @@ -116,22 +112,27 @@ func (e *Elt) UnmarshalBinary(data []byte) error { fp.Mul(y, y, t0) // y = (1 - a*s^2)*isr*den isValid := isPositiveS && isLessThanP && isQR - P, err := ted448.NewPoint(x, y) - if !isValid || err != nil { - return ErrInvalidDecoding + b := uint(*((*byte)(unsafe.Pointer(&isValid)))) + fp.Cmov(&e.p.X, x, b) + fp.Cmov(&e.p.Y, y, b) + fp.Cmov(&e.p.Ta, x, b) + fp.Cmov(&e.p.Tb, y, b) + fp.Cmov(&e.p.Z, &one, b) + var err error + if !isValid { + err = ErrInvalidDecoding } - e.p = *P - return nil + return err } // MarshalBinary returns a unique encoding of the element e. func (e *Elt) MarshalBinary() ([]byte, error) { - x, _, ta, tb, z := e.p.Coordinates() + 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{} fp.SetOne(one) - fp.Mul(t, &ta, &tb) // t = ta*tb - t0, t1 := x, *t // (t0,t1) = (x,t) - fp.Sqr(t2, &x) // t2 = x^2 + fp.Mul(t, ta, tb) // t = ta*tb + t0, t1 := *x, *t // (t0,t1) = (x,t) + fp.Sqr(t2, x) // t2 = x^2 fp.AddSub(&t0, &t1) // (t0,t1) = (x+t,x-t) fp.Mul(&t1, &t0, &t1) // t1 = (x+t)*(x-t) fp.Mul(&t0, &t1, &aMinusDTwist) // t0 = (a-d)*(x+t)*(x-t) @@ -142,9 +143,9 @@ func (e *Elt) MarshalBinary() ([]byte, error) { isNeg := fp.Parity(t2) // isNeg = sgn(t2) fp.Neg(t2, &t1) // t2 = -t1 fp.Cmov(&t1, t2, uint(isNeg)) // if t2 is negative then t1 = -t1 - fp.Mul(s, &t1, &z) // s = t1*z + fp.Mul(s, &t1, z) // s = t1*z fp.Sub(s, s, t) // s = t1*z - t - fp.Mul(s, s, &x) // s = x*(t1*z - t) + fp.Mul(s, s, x) // s = x*(t1*z - t) fp.Mul(s, s, &t0) // s = isr*x*(t1*z - t) fp.Mul(s, s, &aMinusDTwist) // s = (a-d)*isr*x*(t1*z - t) isNeg = fp.Parity(s) // isNeg = sgn(s) diff --git a/internal/ted448/curve.go b/internal/ted448/curve.go index dbd578576..07e9c3705 100644 --- a/internal/ted448/curve.go +++ b/internal/ted448/curve.go @@ -10,10 +10,10 @@ import ( ) // Identity returns the identity point. -func Identity() Point { return Point{y: fp.One(), z: fp.One()} } +func Identity() Point { return Point{Y: fp.One(), Z: fp.One()} } // Generator returns the generator point. -func Generator() Point { return Point{x: genX, y: genY, z: fp.One(), ta: genX, tb: genY} } +func Generator() Point { return Point{X: genX, Y: genY, Z: fp.One(), Ta: genX, Tb: genY} } // Order returns the number of points in the prime subgroup. func Order() Scalar { return order } @@ -23,18 +23,18 @@ func IsOnCurve(P *Point) bool { eq0 := *P != Point{} x2, y2, t, t2, z2 := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{} rhs, lhs := &fp.Elt{}, &fp.Elt{} - fp.Mul(t, &P.ta, &P.tb) // t = ta*tb - fp.Sqr(x2, &P.x) // x^2 - fp.Sqr(y2, &P.y) // y^2 - fp.Sqr(z2, &P.z) // z^2 + fp.Mul(t, &P.Ta, &P.Tb) // t = ta*tb + fp.Sqr(x2, &P.X) // x^2 + fp.Sqr(y2, &P.Y) // y^2 + fp.Sqr(z2, &P.Z) // z^2 fp.Sqr(t2, t) // t^2 fp.Sub(lhs, y2, x2) // -x^2 + y^2, since a=-1 fp.Mul(rhs, t2, &ParamD) // dt^2 fp.Add(rhs, rhs, z2) // z^2 + dt^2 fp.Sub(lhs, lhs, rhs) // ax^2 + y^2 - (z^2 + dt^2) eq1 := fp.IsZero(lhs) - fp.Mul(lhs, &P.x, &P.y) // xy - fp.Mul(rhs, t, &P.z) // tz + fp.Mul(lhs, &P.X, &P.Y) // xy + fp.Mul(rhs, t, &P.Z) // tz fp.Sub(lhs, lhs, rhs) // xy - tz eq2 := fp.IsZero(lhs) return eq0 && eq1 && eq2 diff --git a/internal/ted448/point.go b/internal/ted448/point.go index c318624f3..2ac46ed3a 100644 --- a/internal/ted448/point.go +++ b/internal/ted448/point.go @@ -1,14 +1,13 @@ package ted448 import ( - "errors" "fmt" fp "github.com/cloudflare/circl/math/fp448" ) // Point defines a point on the ted448 curve. -type Point struct{ x, y, z, ta, tb fp.Elt } +type Point struct{ X, Y, Z, Ta, Tb fp.Elt } type prePointAffine struct{ addYX, subYX, dt2 fp.Elt } @@ -18,28 +17,16 @@ type prePointProy struct { } func (P Point) String() string { - return fmt.Sprintf("x: %v\ny: %v\nta: %v\ntb: %v\nz: %v", P.x, P.y, P.ta, P.tb, P.z) + return fmt.Sprintf("x: %v\ny: %v\nta: %v\ntb: %v\nz: %v", P.X, P.Y, P.Ta, P.Tb, P.Z) } -// NewPoint creates a point from affine coordinates. -func NewPoint(x, y *fp.Elt) (*Point, error) { - P := &Point{x: *x, y: *y, ta: *x, tb: *y, z: fp.One()} - if !IsOnCurve(P) { - return nil, errors.New("invalid point") - } - return P, nil -} - -// Coordinates returns a copy of the coordinates. -func (P *Point) Coordinates() (x, y, ta, tb, z fp.Elt) { return P.x, P.y, P.ta, P.tb, P.z } - // cneg conditionally negates the point if b=1. func (P *Point) cneg(b uint) { t := &fp.Elt{} - fp.Neg(t, &P.x) - fp.Cmov(&P.x, t, b) - fp.Neg(t, &P.ta) - fp.Cmov(&P.ta, t, b) + fp.Neg(t, &P.X) + fp.Cmov(&P.X, t, b) + fp.Neg(t, &P.Ta) + fp.Cmov(&P.Ta, t, b) } // Double updates P with 2P. @@ -47,7 +34,7 @@ func (P *Point) Double() { // This is formula (7) from "ed448 Edwards Curves Revisited" by // Hisil H., Wong K.KH., Carter G., Dawson E. (2008) // https://doi.org/10.1007/978-3-540-89255-7_20 - Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb + Px, Py, Pz, Pta, Ptb := &P.X, &P.Y, &P.Z, &P.Ta, &P.Tb a, b, c, e, f, g, h := Px, Py, Pz, Pta, Px, Py, Ptb fp.Add(e, Px, Py) // x+y fp.Sqr(a, Px) // A = x^2 @@ -66,7 +53,7 @@ func (P *Point) Double() { // mixAdd calulates P= P+Q, where Q is a precomputed448 point with Z_Q = 1. func (P *Point) mixAddZ1(Q *prePointAffine) { - fp.Add(&P.z, &P.z, &P.z) // D = 2*z1 (z2=1) + fp.Add(&P.Z, &P.Z, &P.Z) // D = 2*z1 (z2=1) P.coreAddition(Q) } @@ -75,7 +62,7 @@ func (P *Point) coreAddition(Q *prePointAffine) { // This is the formula following (5) from "ed448 Edwards Curves Revisited" by // Hisil H., Wong K.KH., Carter G., Dawson E. (2008) // https://doi.org/10.1007/978-3-540-89255-7_20 - Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb + Px, Py, Pz, Pta, Ptb := &P.X, &P.Y, &P.Z, &P.Ta, &P.Tb addYX2, subYX2, dt2 := &Q.addYX, &Q.subYX, &Q.dt2 a, b, c, d, e, f, g, h := Px, Py, &fp.Elt{}, Pz, Pta, Px, Py, Ptb fp.Mul(c, Pta, Ptb) // t1 = ta*tb @@ -113,37 +100,37 @@ func (P *prePointAffine) cmov(Q *prePointAffine, b uint) { // mixAdd calculates P= P+Q, where Q is a precomputed448 point with Z_Q != 1. func (P *Point) mixAdd(Q *prePointProy) { - fp.Mul(&P.z, &P.z, &Q.z2) // D = 2*z1*z2 + fp.Mul(&P.Z, &P.Z, &Q.z2) // D = 2*z1*z2 P.coreAddition(&Q.prePointAffine) } // IsIdentity returns True is P is the identity. func (P *Point) IsIdentity() bool { - return fp.IsZero(&P.x) && !fp.IsZero(&P.y) && !fp.IsZero(&P.z) && P.y == P.z + return fp.IsZero(&P.X) && !fp.IsZero(&P.Y) && !fp.IsZero(&P.Z) && P.Y == P.Z } // IsEqual returns True if P is equivalent to Q. func (P *Point) IsEqual(Q *Point) bool { l, r := &fp.Elt{}, &fp.Elt{} - fp.Mul(l, &P.x, &Q.z) - fp.Mul(r, &Q.x, &P.z) + fp.Mul(l, &P.X, &Q.Z) + fp.Mul(r, &Q.X, &P.Z) fp.Sub(l, l, r) b := fp.IsZero(l) - fp.Mul(l, &P.y, &Q.z) - fp.Mul(r, &Q.y, &P.z) + fp.Mul(l, &P.Y, &Q.Z) + fp.Mul(r, &Q.Y, &P.Z) fp.Sub(l, l, r) b = b && fp.IsZero(l) - fp.Mul(l, &P.ta, &P.tb) - fp.Mul(l, l, &Q.z) - fp.Mul(r, &Q.ta, &Q.tb) - fp.Mul(r, r, &P.z) + fp.Mul(l, &P.Ta, &P.Tb) + fp.Mul(l, l, &Q.Z) + fp.Mul(r, &Q.Ta, &Q.Tb) + fp.Mul(r, r, &P.Z) fp.Sub(l, l, r) b = b && fp.IsZero(l) return b } // Neg obtains the inverse of P. -func (P *Point) Neg() { fp.Neg(&P.x, &P.x); fp.Neg(&P.ta, &P.ta) } +func (P *Point) Neg() { fp.Neg(&P.X, &P.X); fp.Neg(&P.Ta, &P.Ta) } // Add calculates P = P+Q. func (P *Point) Add(Q *Point) { @@ -176,10 +163,10 @@ func (P *prePointProy) cmov(Q *prePointProy, b uint) { // FromPoint precomputes some coordinates of Q for mised addition. func (P *prePointProy) FromPoint(Q *Point) { - fp.Add(&P.addYX, &Q.y, &Q.x) // addYX = X + Y - fp.Sub(&P.subYX, &Q.y, &Q.x) // subYX = Y - X - fp.Mul(&P.dt2, &Q.ta, &Q.tb) // T = ta*tb + fp.Add(&P.addYX, &Q.Y, &Q.X) // addYX = X + Y + fp.Sub(&P.subYX, &Q.Y, &Q.X) // subYX = Y - X + fp.Mul(&P.dt2, &Q.Ta, &Q.Tb) // T = ta*tb fp.Mul(&P.dt2, &P.dt2, &ParamD) // D*T fp.Add(&P.dt2, &P.dt2, &P.dt2) // dt2 = 2*D*T - fp.Add(&P.z2, &Q.z, &Q.z) // z2 = 2*Z + fp.Add(&P.z2, &Q.Z, &Q.Z) // z2 = 2*Z }