diff --git a/ecc/bls12-377/g1.go b/ecc/bls12-377/g1.go index 3feef20207..a5c6ae1d65 100644 --- a/ecc/bls12-377/g1.go +++ b/ecc/bls12-377/g1.go @@ -77,6 +77,7 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac // a is infinity, return b @@ -125,6 +126,7 @@ func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Affine) Double(a *G1Affine) *G1Affine { var q G1Jac q.FromAffine(a) @@ -252,7 +254,8 @@ func (p *G1Jac) Neg(q *G1Jac) *G1Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G1Jac) AddAssign(q *G1Jac) *G1Jac { // p is infinity, return q @@ -316,7 +319,8 @@ func (p *G1Jac) SubAssign(q *G1Jac) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { var XX, YY, YYYY, S, M, T fp.Element XX.Square(&a.X) @@ -347,6 +351,7 @@ func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { //if a is infinity return p @@ -396,7 +401,8 @@ func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) Double(q *G1Jac) *G1Jac { p.Set(q) p.DoubleAssign() @@ -405,33 +411,31 @@ func (p *G1Jac) Double(q *G1Jac) *G1Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) DoubleAssign() *G1Jac { - - var XX, YY, YYYY, ZZ, S, M, T fp.Element - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fp.Element + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -816,6 +820,7 @@ func (p *G1Jac) unsafeFromJacExtended(q *g1JacExtended) *G1Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -873,6 +878,8 @@ func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { @@ -902,6 +909,7 @@ func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -958,6 +966,7 @@ func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -1012,27 +1021,29 @@ func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -1041,26 +1052,26 @@ func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bls12-377/g2.go b/ecc/bls12-377/g2.go index 78b6138c52..86424ee1e9 100644 --- a/ecc/bls12-377/g2.go +++ b/ecc/bls12-377/g2.go @@ -83,6 +83,7 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac // a is infinity, return b @@ -131,6 +132,7 @@ func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Affine) Double(a *G2Affine) *G2Affine { var q G2Jac q.FromAffine(a) @@ -258,7 +260,8 @@ func (p *G2Jac) Neg(q *G2Jac) *G2Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G2Jac) AddAssign(q *G2Jac) *G2Jac { // p is infinity, return q @@ -322,7 +325,8 @@ func (p *G2Jac) SubAssign(q *G2Jac) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { var XX, YY, YYYY, S, M, T fptower.E2 XX.Square(&a.X) @@ -353,6 +357,7 @@ func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { //if a is infinity return p @@ -402,7 +407,8 @@ func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) Double(q *G2Jac) *G2Jac { p.Set(q) p.DoubleAssign() @@ -411,33 +417,31 @@ func (p *G2Jac) Double(q *G2Jac) *G2Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) DoubleAssign() *G2Jac { - - var XX, YY, YYYY, ZZ, S, M, T fptower.E2 - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fptower.E2 + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -764,6 +768,7 @@ func (p *G2Jac) unsafeFromJacExtended(q *g2JacExtended) *G2Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -821,6 +826,8 @@ func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { @@ -850,6 +857,7 @@ func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -906,6 +914,7 @@ func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -960,27 +969,29 @@ func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fptower.E2 + var U, V, W, S, M, t fptower.E2 U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -989,26 +1000,26 @@ func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fptower.E2 + var U, V, W, S, M, t fptower.E2 U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bls12-381/g1.go b/ecc/bls12-381/g1.go index ab00282afb..ee79e19e67 100644 --- a/ecc/bls12-381/g1.go +++ b/ecc/bls12-381/g1.go @@ -78,6 +78,7 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac // a is infinity, return b @@ -126,6 +127,7 @@ func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Affine) Double(a *G1Affine) *G1Affine { var q G1Jac q.FromAffine(a) @@ -261,7 +263,8 @@ func (p *G1Jac) Neg(q *G1Jac) *G1Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G1Jac) AddAssign(q *G1Jac) *G1Jac { // p is infinity, return q @@ -325,7 +328,8 @@ func (p *G1Jac) SubAssign(q *G1Jac) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { var XX, YY, YYYY, S, M, T fp.Element XX.Square(&a.X) @@ -356,6 +360,7 @@ func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { //if a is infinity return p @@ -405,7 +410,8 @@ func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) Double(q *G1Jac) *G1Jac { p.Set(q) p.DoubleAssign() @@ -414,33 +420,31 @@ func (p *G1Jac) Double(q *G1Jac) *G1Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) DoubleAssign() *G1Jac { - - var XX, YY, YYYY, ZZ, S, M, T fp.Element - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fp.Element + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -839,6 +843,7 @@ func (p *G1Jac) unsafeFromJacExtended(q *g1JacExtended) *G1Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -896,6 +901,8 @@ func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { @@ -925,6 +932,7 @@ func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -981,6 +989,7 @@ func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -1035,27 +1044,29 @@ func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -1064,26 +1075,26 @@ func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bls12-381/g2.go b/ecc/bls12-381/g2.go index d3e315c5e2..6da47e8ae9 100644 --- a/ecc/bls12-381/g2.go +++ b/ecc/bls12-381/g2.go @@ -85,6 +85,7 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac // a is infinity, return b @@ -133,6 +134,7 @@ func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Affine) Double(a *G2Affine) *G2Affine { var q G2Jac q.FromAffine(a) @@ -266,7 +268,8 @@ func (p *G2Jac) Neg(q *G2Jac) *G2Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G2Jac) AddAssign(q *G2Jac) *G2Jac { // p is infinity, return q @@ -330,7 +333,8 @@ func (p *G2Jac) SubAssign(q *G2Jac) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { var XX, YY, YYYY, S, M, T fptower.E2 XX.Square(&a.X) @@ -361,6 +365,7 @@ func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { //if a is infinity return p @@ -410,7 +415,8 @@ func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) Double(q *G2Jac) *G2Jac { p.Set(q) p.DoubleAssign() @@ -419,33 +425,31 @@ func (p *G2Jac) Double(q *G2Jac) *G2Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) DoubleAssign() *G2Jac { - - var XX, YY, YYYY, ZZ, S, M, T fptower.E2 - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fptower.E2 + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -785,6 +789,7 @@ func (p *G2Jac) unsafeFromJacExtended(q *g2JacExtended) *G2Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -842,6 +847,8 @@ func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { @@ -871,6 +878,7 @@ func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -927,6 +935,7 @@ func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -981,27 +990,29 @@ func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fptower.E2 + var U, V, W, S, M, t fptower.E2 U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -1010,26 +1021,26 @@ func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fptower.E2 + var U, V, W, S, M, t fptower.E2 U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bls24-315/g1.go b/ecc/bls24-315/g1.go index 1927391c45..76865690eb 100644 --- a/ecc/bls24-315/g1.go +++ b/ecc/bls24-315/g1.go @@ -77,6 +77,7 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac // a is infinity, return b @@ -125,6 +126,7 @@ func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Affine) Double(a *G1Affine) *G1Affine { var q G1Jac q.FromAffine(a) @@ -252,7 +254,8 @@ func (p *G1Jac) Neg(q *G1Jac) *G1Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G1Jac) AddAssign(q *G1Jac) *G1Jac { // p is infinity, return q @@ -316,7 +319,8 @@ func (p *G1Jac) SubAssign(q *G1Jac) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { var XX, YY, YYYY, S, M, T fp.Element XX.Square(&a.X) @@ -347,6 +351,7 @@ func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { //if a is infinity return p @@ -396,7 +401,8 @@ func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) Double(q *G1Jac) *G1Jac { p.Set(q) p.DoubleAssign() @@ -405,33 +411,31 @@ func (p *G1Jac) Double(q *G1Jac) *G1Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) DoubleAssign() *G1Jac { - - var XX, YY, YYYY, ZZ, S, M, T fp.Element - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fp.Element + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -793,6 +797,7 @@ func (p *G1Jac) unsafeFromJacExtended(q *g1JacExtended) *G1Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -850,6 +855,8 @@ func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { @@ -879,6 +886,7 @@ func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -935,6 +943,7 @@ func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -989,27 +998,29 @@ func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -1018,26 +1029,26 @@ func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bls24-315/g2.go b/ecc/bls24-315/g2.go index 0c63de104d..ef96c714a4 100644 --- a/ecc/bls24-315/g2.go +++ b/ecc/bls24-315/g2.go @@ -83,6 +83,7 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac // a is infinity, return b @@ -131,6 +132,7 @@ func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Affine) Double(a *G2Affine) *G2Affine { var q G2Jac q.FromAffine(a) @@ -258,7 +260,8 @@ func (p *G2Jac) Neg(q *G2Jac) *G2Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G2Jac) AddAssign(q *G2Jac) *G2Jac { // p is infinity, return q @@ -322,7 +325,8 @@ func (p *G2Jac) SubAssign(q *G2Jac) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { var XX, YY, YYYY, S, M, T fptower.E4 XX.Square(&a.X) @@ -353,6 +357,7 @@ func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { //if a is infinity return p @@ -402,7 +407,8 @@ func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) Double(q *G2Jac) *G2Jac { p.Set(q) p.DoubleAssign() @@ -411,33 +417,31 @@ func (p *G2Jac) Double(q *G2Jac) *G2Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) DoubleAssign() *G2Jac { - - var XX, YY, YYYY, ZZ, S, M, T fptower.E4 - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fptower.E4 + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -756,6 +760,7 @@ func (p *G2Jac) unsafeFromJacExtended(q *g2JacExtended) *G2Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -813,6 +818,8 @@ func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { @@ -842,6 +849,7 @@ func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -898,6 +906,7 @@ func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -952,27 +961,29 @@ func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fptower.E4 + var U, V, W, S, M, t fptower.E4 U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -981,26 +992,26 @@ func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fptower.E4 + var U, V, W, S, M, t fptower.E4 U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bls24-317/g1.go b/ecc/bls24-317/g1.go index e16a9761bc..f2c8a598e1 100644 --- a/ecc/bls24-317/g1.go +++ b/ecc/bls24-317/g1.go @@ -77,6 +77,7 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac // a is infinity, return b @@ -125,6 +126,7 @@ func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Affine) Double(a *G1Affine) *G1Affine { var q G1Jac q.FromAffine(a) @@ -252,7 +254,8 @@ func (p *G1Jac) Neg(q *G1Jac) *G1Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G1Jac) AddAssign(q *G1Jac) *G1Jac { // p is infinity, return q @@ -316,7 +319,8 @@ func (p *G1Jac) SubAssign(q *G1Jac) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { var XX, YY, YYYY, S, M, T fp.Element XX.Square(&a.X) @@ -347,6 +351,7 @@ func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { //if a is infinity return p @@ -396,7 +401,8 @@ func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) Double(q *G1Jac) *G1Jac { p.Set(q) p.DoubleAssign() @@ -405,33 +411,31 @@ func (p *G1Jac) Double(q *G1Jac) *G1Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) DoubleAssign() *G1Jac { - - var XX, YY, YYYY, ZZ, S, M, T fp.Element - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fp.Element + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -794,6 +798,7 @@ func (p *G1Jac) unsafeFromJacExtended(q *g1JacExtended) *G1Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -851,6 +856,8 @@ func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { @@ -880,6 +887,7 @@ func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -936,6 +944,7 @@ func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -990,27 +999,29 @@ func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -1019,26 +1030,26 @@ func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bls24-317/g2.go b/ecc/bls24-317/g2.go index 4a04094f36..aa94ad2f3a 100644 --- a/ecc/bls24-317/g2.go +++ b/ecc/bls24-317/g2.go @@ -83,6 +83,7 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac // a is infinity, return b @@ -131,6 +132,7 @@ func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Affine) Double(a *G2Affine) *G2Affine { var q G2Jac q.FromAffine(a) @@ -258,7 +260,8 @@ func (p *G2Jac) Neg(q *G2Jac) *G2Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G2Jac) AddAssign(q *G2Jac) *G2Jac { // p is infinity, return q @@ -322,7 +325,8 @@ func (p *G2Jac) SubAssign(q *G2Jac) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { var XX, YY, YYYY, S, M, T fptower.E4 XX.Square(&a.X) @@ -353,6 +357,7 @@ func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { //if a is infinity return p @@ -402,7 +407,8 @@ func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) Double(q *G2Jac) *G2Jac { p.Set(q) p.DoubleAssign() @@ -411,33 +417,31 @@ func (p *G2Jac) Double(q *G2Jac) *G2Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) DoubleAssign() *G2Jac { - - var XX, YY, YYYY, ZZ, S, M, T fptower.E4 - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fptower.E4 + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -756,6 +760,7 @@ func (p *G2Jac) unsafeFromJacExtended(q *g2JacExtended) *G2Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -813,6 +818,8 @@ func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { @@ -842,6 +849,7 @@ func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -898,6 +906,7 @@ func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -952,27 +961,29 @@ func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fptower.E4 + var U, V, W, S, M, t fptower.E4 U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -981,26 +992,26 @@ func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fptower.E4 + var U, V, W, S, M, t fptower.E4 U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bn254/g1.go b/ecc/bn254/g1.go index 06d54ff648..16dc0b9ff9 100644 --- a/ecc/bn254/g1.go +++ b/ecc/bn254/g1.go @@ -77,6 +77,7 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac // a is infinity, return b @@ -125,6 +126,7 @@ func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Affine) Double(a *G1Affine) *G1Affine { var q G1Jac q.FromAffine(a) @@ -250,7 +252,8 @@ func (p *G1Jac) Neg(q *G1Jac) *G1Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G1Jac) AddAssign(q *G1Jac) *G1Jac { // p is infinity, return q @@ -314,7 +317,8 @@ func (p *G1Jac) SubAssign(q *G1Jac) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { var XX, YY, YYYY, S, M, T fp.Element XX.Square(&a.X) @@ -345,6 +349,7 @@ func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { //if a is infinity return p @@ -394,7 +399,8 @@ func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) Double(q *G1Jac) *G1Jac { p.Set(q) p.DoubleAssign() @@ -403,33 +409,31 @@ func (p *G1Jac) Double(q *G1Jac) *G1Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) DoubleAssign() *G1Jac { - - var XX, YY, YYYY, ZZ, S, M, T fp.Element - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fp.Element + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -808,6 +812,7 @@ func (p *G1Jac) unsafeFromJacExtended(q *g1JacExtended) *G1Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -865,6 +870,8 @@ func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { @@ -894,6 +901,7 @@ func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -950,6 +958,7 @@ func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -1004,27 +1013,29 @@ func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -1033,26 +1044,26 @@ func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bn254/g2.go b/ecc/bn254/g2.go index c656b5c2c7..4bb5dd8f07 100644 --- a/ecc/bn254/g2.go +++ b/ecc/bn254/g2.go @@ -83,6 +83,7 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac // a is infinity, return b @@ -131,6 +132,7 @@ func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Affine) Double(a *G2Affine) *G2Affine { var q G2Jac q.FromAffine(a) @@ -271,7 +273,8 @@ func (p *G2Jac) Neg(q *G2Jac) *G2Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G2Jac) AddAssign(q *G2Jac) *G2Jac { // p is infinity, return q @@ -335,7 +338,8 @@ func (p *G2Jac) SubAssign(q *G2Jac) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { var XX, YY, YYYY, S, M, T fptower.E2 XX.Square(&a.X) @@ -366,6 +370,7 @@ func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { //if a is infinity return p @@ -415,7 +420,8 @@ func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) Double(q *G2Jac) *G2Jac { p.Set(q) p.DoubleAssign() @@ -424,33 +430,31 @@ func (p *G2Jac) Double(q *G2Jac) *G2Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) DoubleAssign() *G2Jac { - - var XX, YY, YYYY, ZZ, S, M, T fptower.E2 - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fptower.E2 + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -824,6 +828,7 @@ func (p *G2Jac) unsafeFromJacExtended(q *g2JacExtended) *G2Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -881,6 +886,8 @@ func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { @@ -910,6 +917,7 @@ func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -966,6 +974,7 @@ func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -1020,27 +1029,29 @@ func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fptower.E2 + var U, V, W, S, M, t fptower.E2 U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -1049,26 +1060,26 @@ func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fptower.E2 + var U, V, W, S, M, t fptower.E2 U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bw6-633/g1.go b/ecc/bw6-633/g1.go index 4c81ec4de1..86a16962a7 100644 --- a/ecc/bw6-633/g1.go +++ b/ecc/bw6-633/g1.go @@ -77,6 +77,7 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac // a is infinity, return b @@ -125,6 +126,7 @@ func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Affine) Double(a *G1Affine) *G1Affine { var q G1Jac q.FromAffine(a) @@ -252,7 +254,8 @@ func (p *G1Jac) Neg(q *G1Jac) *G1Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G1Jac) AddAssign(q *G1Jac) *G1Jac { // p is infinity, return q @@ -316,7 +319,8 @@ func (p *G1Jac) SubAssign(q *G1Jac) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { var XX, YY, YYYY, S, M, T fp.Element XX.Square(&a.X) @@ -347,6 +351,7 @@ func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { //if a is infinity return p @@ -396,7 +401,8 @@ func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) Double(q *G1Jac) *G1Jac { p.Set(q) p.DoubleAssign() @@ -405,33 +411,31 @@ func (p *G1Jac) Double(q *G1Jac) *G1Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) DoubleAssign() *G1Jac { - - var XX, YY, YYYY, ZZ, S, M, T fp.Element - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fp.Element + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -816,6 +820,7 @@ func (p *G1Jac) unsafeFromJacExtended(q *g1JacExtended) *G1Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -873,6 +878,8 @@ func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { @@ -902,6 +909,7 @@ func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -958,6 +966,7 @@ func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -1012,27 +1021,29 @@ func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -1041,26 +1052,26 @@ func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bw6-633/g2.go b/ecc/bw6-633/g2.go index 552552cd75..e5008f258f 100644 --- a/ecc/bw6-633/g2.go +++ b/ecc/bw6-633/g2.go @@ -83,6 +83,7 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac // a is infinity, return b @@ -131,6 +132,7 @@ func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Affine) Double(a *G2Affine) *G2Affine { var q G2Jac q.FromAffine(a) @@ -258,7 +260,8 @@ func (p *G2Jac) Neg(q *G2Jac) *G2Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G2Jac) AddAssign(q *G2Jac) *G2Jac { // p is infinity, return q @@ -322,7 +325,8 @@ func (p *G2Jac) SubAssign(q *G2Jac) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { var XX, YY, YYYY, S, M, T fp.Element XX.Square(&a.X) @@ -353,6 +357,7 @@ func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { //if a is infinity return p @@ -402,7 +407,8 @@ func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) Double(q *G2Jac) *G2Jac { p.Set(q) p.DoubleAssign() @@ -411,33 +417,31 @@ func (p *G2Jac) Double(q *G2Jac) *G2Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) DoubleAssign() *G2Jac { - - var XX, YY, YYYY, ZZ, S, M, T fp.Element - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fp.Element + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -746,6 +750,7 @@ func (p *G2Jac) unsafeFromJacExtended(q *g2JacExtended) *G2Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -803,6 +808,8 @@ func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { @@ -832,6 +839,7 @@ func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -888,6 +896,7 @@ func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -942,27 +951,29 @@ func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -971,26 +982,26 @@ func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bw6-761/g1.go b/ecc/bw6-761/g1.go index db3f863898..a12c8802eb 100644 --- a/ecc/bw6-761/g1.go +++ b/ecc/bw6-761/g1.go @@ -77,6 +77,7 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac // a is infinity, return b @@ -125,6 +126,7 @@ func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Affine) Double(a *G1Affine) *G1Affine { var q G1Jac q.FromAffine(a) @@ -252,7 +254,8 @@ func (p *G1Jac) Neg(q *G1Jac) *G1Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G1Jac) AddAssign(q *G1Jac) *G1Jac { // p is infinity, return q @@ -316,7 +319,8 @@ func (p *G1Jac) SubAssign(q *G1Jac) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { var XX, YY, YYYY, S, M, T fp.Element XX.Square(&a.X) @@ -347,6 +351,7 @@ func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { //if a is infinity return p @@ -396,7 +401,8 @@ func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) Double(q *G1Jac) *G1Jac { p.Set(q) p.DoubleAssign() @@ -405,33 +411,31 @@ func (p *G1Jac) Double(q *G1Jac) *G1Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) DoubleAssign() *G1Jac { - - var XX, YY, YYYY, ZZ, S, M, T fp.Element - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fp.Element + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -853,6 +857,7 @@ func (p *G1Jac) unsafeFromJacExtended(q *g1JacExtended) *G1Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -910,6 +915,8 @@ func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { @@ -939,6 +946,7 @@ func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -995,6 +1003,7 @@ func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -1049,27 +1058,29 @@ func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -1078,26 +1089,26 @@ func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/bw6-761/g2.go b/ecc/bw6-761/g2.go index cd732cd35b..296097af9d 100644 --- a/ecc/bw6-761/g2.go +++ b/ecc/bw6-761/g2.go @@ -83,6 +83,7 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac // a is infinity, return b @@ -131,6 +132,7 @@ func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Affine) Double(a *G2Affine) *G2Affine { var q G2Jac q.FromAffine(a) @@ -258,7 +260,8 @@ func (p *G2Jac) Neg(q *G2Jac) *G2Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G2Jac) AddAssign(q *G2Jac) *G2Jac { // p is infinity, return q @@ -322,7 +325,8 @@ func (p *G2Jac) SubAssign(q *G2Jac) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { var XX, YY, YYYY, S, M, T fp.Element XX.Square(&a.X) @@ -353,6 +357,7 @@ func (p *G2Jac) DoubleMixed(a *G2Affine) *G2Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { //if a is infinity return p @@ -402,7 +407,8 @@ func (p *G2Jac) AddMixed(a *G2Affine) *G2Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) Double(q *G2Jac) *G2Jac { p.Set(q) p.DoubleAssign() @@ -411,33 +417,31 @@ func (p *G2Jac) Double(q *G2Jac) *G2Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G2Jac) DoubleAssign() *G2Jac { - - var XX, YY, YYYY, ZZ, S, M, T fp.Element - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fp.Element + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -779,6 +783,7 @@ func (p *G2Jac) unsafeFromJacExtended(q *g2JacExtended) *G2Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -836,6 +841,8 @@ func (p *g2JacExtended) add(q *g2JacExtended) *g2JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { @@ -865,6 +872,7 @@ func (p *g2JacExtended) double(q *g2JacExtended) *g2JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -921,6 +929,7 @@ func (p *g2JacExtended) addMixed(a *G2Affine) *g2JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { //if a is infinity return p @@ -975,27 +984,29 @@ func (p *g2JacExtended) subMixed(a *G2Affine) *g2JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -1004,26 +1015,26 @@ func (p *g2JacExtended) doubleNegMixed(a *G2Affine) *g2JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g2JacExtended) doubleMixed(a *G2Affine) *g2JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/grumpkin/g1.go b/ecc/grumpkin/g1.go index ea8e99505c..534de99564 100644 --- a/ecc/grumpkin/g1.go +++ b/ecc/grumpkin/g1.go @@ -77,6 +77,7 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac // a is infinity, return b @@ -125,6 +126,7 @@ func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Affine) Double(a *G1Affine) *G1Affine { var q G1Jac q.FromAffine(a) @@ -252,7 +254,8 @@ func (p *G1Jac) Neg(q *G1Jac) *G1Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G1Jac) AddAssign(q *G1Jac) *G1Jac { // p is infinity, return q @@ -316,7 +319,8 @@ func (p *G1Jac) SubAssign(q *G1Jac) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { var XX, YY, YYYY, S, M, T fp.Element XX.Square(&a.X) @@ -347,6 +351,7 @@ func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { //if a is infinity return p @@ -396,7 +401,8 @@ func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) Double(q *G1Jac) *G1Jac { p.Set(q) p.DoubleAssign() @@ -405,33 +411,31 @@ func (p *G1Jac) Double(q *G1Jac) *G1Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) DoubleAssign() *G1Jac { - - var XX, YY, YYYY, ZZ, S, M, T fp.Element - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fp.Element + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -760,6 +764,7 @@ func (p *G1Jac) unsafeFromJacExtended(q *g1JacExtended) *G1Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -817,6 +822,8 @@ func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { @@ -846,6 +853,7 @@ func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -902,6 +910,7 @@ func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -956,27 +965,29 @@ func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -985,26 +996,26 @@ func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/ecc/secp256k1/g1.go b/ecc/secp256k1/g1.go index a86a45d4ed..4122305414 100644 --- a/ecc/secp256k1/g1.go +++ b/ecc/secp256k1/g1.go @@ -77,6 +77,7 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac // a is infinity, return b @@ -125,6 +126,7 @@ func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Affine) Double(a *G1Affine) *G1Affine { var q G1Jac q.FromAffine(a) @@ -252,7 +254,8 @@ func (p *G1Jac) Neg(q *G1Jac) *G1Jac { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *G1Jac) AddAssign(q *G1Jac) *G1Jac { // p is infinity, return q @@ -316,7 +319,8 @@ func (p *G1Jac) SubAssign(q *G1Jac) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { var XX, YY, YYYY, S, M, T fp.Element XX.Square(&a.X) @@ -347,6 +351,7 @@ func (p *G1Jac) DoubleMixed(a *G1Affine) *G1Jac { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { //if a is infinity return p @@ -396,7 +401,8 @@ func (p *G1Jac) AddMixed(a *G1Affine) *G1Jac { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) Double(q *G1Jac) *G1Jac { p.Set(q) p.DoubleAssign() @@ -405,33 +411,31 @@ func (p *G1Jac) Double(q *G1Jac) *G1Jac { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *G1Jac) DoubleAssign() *G1Jac { - - var XX, YY, YYYY, ZZ, S, M, T fp.Element - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) + var A, B, C, D, E, F, t fp.Element + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) return p } @@ -753,6 +757,7 @@ func (p *G1Jac) unsafeFromJacExtended(q *g1JacExtended) *G1Jac { // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { //if q is infinity return p if q.ZZ.IsZero() { @@ -810,6 +815,8 @@ func (p *g1JacExtended) add(q *g1JacExtended) *g1JacExtended { // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { @@ -839,6 +846,7 @@ func (p *g1JacExtended) double(q *g1JacExtended) *g1JacExtended { // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -895,6 +903,7 @@ func (p *g1JacExtended) addMixed(a *G1Affine) *g1JacExtended { // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { //if a is infinity return p @@ -949,27 +958,29 @@ func (p *g1JacExtended) subMixed(a *G1Affine) *g1JacExtended { } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) U.Neg(&U) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Add(&p.Y, &L) + Add(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) @@ -978,26 +989,26 @@ func (p *g1JacExtended) doubleNegMixed(a *G1Affine) *g1JacExtended { // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *g1JacExtended) doubleMixed(a *G1Affine) *g1JacExtended { - var U, V, W, S, XX, M, S2, L fp.Element + var U, V, W, S, M, t fp.Element U.Double(&a.Y) V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). - Sub(&p.Y, &L) + Sub(&p.Y, &t) p.ZZ.Set(&V) p.ZZZ.Set(&W) diff --git a/internal/generator/ecc/template/point.go.tmpl b/internal/generator/ecc/template/point.go.tmpl index df791eb4f7..aaeff9d798 100644 --- a/internal/generator/ecc/template/point.go.tmpl +++ b/internal/generator/ecc/template/point.go.tmpl @@ -109,6 +109,7 @@ func (p *{{ $TAffine }}) ScalarMultiplicationBase(s *big.Int) *{{ $TAffine }} { // It uses the Jacobian addition with a.Z=b.Z=1 and converts the result to affine coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl +// ~Cost: 4M + 2S func (p *{{ $TAffine }}) Add(a, b *{{ $TAffine }}) *{{ $TAffine }} { var q {{ $TJacobian }} // a is infinity, return b @@ -157,6 +158,7 @@ func (p *{{ $TAffine }}) Add(a, b *{{ $TAffine }}) *{{ $TAffine }} { // addition with a.Z=1, and converts it back to affine coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *{{ $TAffine }}) Double(a *{{ $TAffine }}) *{{ $TAffine }} { var q {{ $TJacobian }} q.FromAffine(a) @@ -337,7 +339,8 @@ func (p *{{ $TJacobian }}) Neg(q *{{ $TJacobian }}) *{{ $TJacobian }} { // AddAssign sets p to p+a in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl +// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl +// ~Cost: 11M + 5S func (p *{{ $TJacobian }}) AddAssign(q *{{ $TJacobian }}) *{{ $TJacobian }} { // p is infinity, return q @@ -401,7 +404,8 @@ func (p *{{ $TJacobian }}) SubAssign(q *{{ $TJacobian }}) *{{ $TJacobian }} { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl +// ~Cost: 1M + 5S func (p *{{ $TJacobian }}) DoubleMixed(a *{{ $TAffine }}) *{{ $TJacobian }} { var XX, YY, YYYY, S, M, T {{.CoordType}} XX.Square(&a.X) @@ -432,6 +436,7 @@ func (p *{{ $TJacobian }}) DoubleMixed(a *{{ $TAffine }}) *{{ $TJacobian }} { // AddMixed sets p to p+a in Jacobian coordinates, where a.Z = 1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl +// ~Cost: 7M + 4S func (p *{{ $TJacobian }}) AddMixed(a *{{ $TAffine }}) *{{ $TJacobian }} { //if a is infinity return p @@ -481,7 +486,8 @@ func (p *{{ $TJacobian }}) AddMixed(a *{{ $TAffine }}) *{{ $TJacobian }} { // Double sets p to [2]q in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *{{ $TJacobian }}) Double(q *{{ $TJacobian }}) *{{ $TJacobian }} { p.Set(q) p.DoubleAssign() @@ -490,35 +496,33 @@ func (p *{{ $TJacobian }}) Double(q *{{ $TJacobian }}) *{{ $TJacobian }} { // DoubleAssign doubles p in Jacobian coordinates. // -// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2007-bl +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l +// ~Cost: 2M + 5S func (p *{{ $TJacobian }}) DoubleAssign() *{{ $TJacobian }} { - - var XX, YY, YYYY, ZZ, S, M, T {{.CoordType}} - - XX.Square(&p.X) - YY.Square(&p.Y) - YYYY.Square(&YY) - ZZ.Square(&p.Z) - S.Add(&p.X, &YY) - S.Square(&S). - Sub(&S, &XX). - Sub(&S, &YYYY). - Double(&S) - M.Double(&XX).Add(&M, &XX) - p.Z.Add(&p.Z, &p.Y). - Square(&p.Z). - Sub(&p.Z, &YY). - Sub(&p.Z, &ZZ) - T.Square(&M) - p.X = T - T.Double(&S) - p.X.Sub(&p.X, &T) - p.Y.Sub(&S, &p.X). - Mul(&p.Y, &M) - YYYY.Double(&YYYY).Double(&YYYY).Double(&YYYY) - p.Y.Sub(&p.Y, &YYYY) - - return p + var A, B, C, D, E, F, t {{.CoordType}} + A.Square(&p.X) + B.Square(&p.Y) + C.Square(&B) + D.Add(&p.X, &B). + Square(&D). + Sub(&D, &A). + Sub(&D, &C). + Double(&D) + E.Double(&A). + Add(&E, &A) + F.Square(&E) + t.Double(&D) + p.Z.Mul(&p.Y, &p.Z). + Double(&p.Z) + p.X.Sub(&F, &t) + p.Y.Sub(&D, &p.X). + Mul(&p.Y, &E) + t.Double(&C). + Double(&t). + Double(&t) + p.Y.Sub(&p.Y, &t) + + return p } // ScalarMultiplication computes and returns p = [s]a @@ -1593,6 +1597,7 @@ func (p *{{ $TJacobian }}) unsafeFromJacExtended(q *{{ $TJacobianExtended }}) *{ // add sets p to p+q in extended Jacobian coordinates. // // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-add-2008-s +// ~Cost: 12M + 2S func (p *{{ $TJacobianExtended }}) add(q *{{ $TJacobianExtended }}) *{{ $TJacobianExtended }} { //if q is infinity return p if q.ZZ.IsZero() { @@ -1651,6 +1656,8 @@ func (p *{{ $TJacobianExtended }}) add(q *{{ $TJacobianExtended }}) *{{ $TJacobi // double sets p to [2]q in Jacobian extended coordinates. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// ~Cost: 6M + 3S +// // N.B.: since we consider any point on Z=0 as the point at infinity // this doubling formula works for infinity points as well. func (p *{{ $TJacobianExtended }}) double(q *{{ $TJacobianExtended }}) *{{ $TJacobianExtended }} { @@ -1680,6 +1687,7 @@ func (p *{{ $TJacobianExtended }}) double(q *{{ $TJacobianExtended }}) *{{ $TJac // addMixed sets p to p+q in extended Jacobian coordinates, where a.ZZ=1. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *{{ $TJacobianExtended }}) addMixed(a *{{ $TAffine }}) *{{ $TJacobianExtended }} { {{ template "mAdd" dict "all" . "negate" false}} } @@ -1687,24 +1695,29 @@ func (p *{{ $TJacobianExtended }}) addMixed(a *{{ $TAffine }}) *{{ $TJacobianExt // subMixed works the same as addMixed, but negates a.Y. // // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#addition-madd-2008-s +// ~Cost: 8M + 2S func (p *{{ $TJacobianExtended }}) subMixed(a *{{ $TAffine }}) *{{ $TJacobianExtended }} { {{ template "mAdd" dict "all" . "negate" true}} } -// doubleNegMixed works the same as double, but negates q.Y. +// doubleNegMixed works the same as doubleMixed, but negates q.Y. +// +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *{{ $TJacobianExtended }}) doubleNegMixed(a *{{ $TAffine }}) *{{ $TJacobianExtended }} { {{ template "mDouble" dict "all" . "negate" true}} } // doubleMixed sets p to [2]a in Jacobian extended coordinates, where a.ZZ=1. // -// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-dbl-2008-s-1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-xyzz.html#doubling-mdbl-2008-s-1 +// ~Cost: 4M + 3S func (p *{{ $TJacobianExtended }}) doubleMixed(a *{{ $TAffine }}) *{{ $TJacobianExtended }} { {{ template "mDouble" dict "all" . "negate" false}} } {{define "mDouble" }} - var U, V, W, S, XX, M, S2, L {{.all.CoordType}} + var U, V, W, S, M, t {{.all.CoordType}} U.Double(&a.Y) {{- if .negate}} @@ -1713,20 +1726,19 @@ func (p *{{ $TJacobianExtended }}) doubleMixed(a *{{ $TAffine }}) *{{ $TJacobian V.Square(&U) W.Mul(&U, &V) S.Mul(&a.X, &V) - XX.Square(&a.X) - M.Double(&XX). - Add(&M, &XX) // -> + A, but A=0 here - S2.Double(&S) - L.Mul(&W, &a.Y) - - p.X.Square(&M). - Sub(&p.X, &S2) + t.Square(&a.X) + M.Double(&t). + Add(&M, &t) // -> + A, but A=0 here + p.X.Square(&M) + t.Double(&S) + p.X.Sub(&p.X, &t) + t.Mul(&W, &a.Y) p.Y.Sub(&S, &p.X). Mul(&p.Y, &M). {{- if .negate}} - Add(&p.Y, &L) + Add(&p.Y, &t) {{- else}} - Sub(&p.Y, &L) + Sub(&p.Y, &t) {{- end}} p.ZZ.Set(&V) p.ZZZ.Set(&W)