From 3ba464d9dfe41bb88458da9f687d78cf9a5c4838 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Wed, 12 Jun 2024 12:13:13 +0100 Subject: [PATCH 1/2] perf(ecc): faster affine Add --- ecc/bls12-377/g1.go | 53 ++++++++++++++---- ecc/bls12-377/g2.go | 53 ++++++++++++++---- ecc/bls12-378/g1.go | 53 ++++++++++++++---- ecc/bls12-378/g2.go | 53 ++++++++++++++---- ecc/bls12-381/g1.go | 53 ++++++++++++++---- ecc/bls12-381/g2.go | 53 ++++++++++++++---- ecc/bls24-315/g1.go | 53 ++++++++++++++---- ecc/bls24-315/g2.go | 53 ++++++++++++++---- ecc/bls24-317/g1.go | 53 ++++++++++++++---- ecc/bls24-317/g2.go | 53 ++++++++++++++---- ecc/bn254/g1.go | 53 ++++++++++++++---- ecc/bn254/g2.go | 53 ++++++++++++++---- ecc/bw6-633/g1.go | 53 ++++++++++++++---- ecc/bw6-633/g2.go | 53 ++++++++++++++---- ecc/bw6-756/g1.go | 53 ++++++++++++++---- ecc/bw6-756/g2.go | 53 ++++++++++++++---- ecc/bw6-761/g1.go | 53 ++++++++++++++---- ecc/bw6-761/g2.go | 53 ++++++++++++++---- ecc/secp256k1/g1.go | 53 ++++++++++++++---- internal/generator/ecc/template/point.go.tmpl | 54 +++++++++++++++---- 20 files changed, 880 insertions(+), 181 deletions(-) diff --git a/ecc/bls12-377/g1.go b/ecc/bls12-377/g1.go index c6effea1a..9d2739f1d 100644 --- a/ecc/bls12-377/g1.go +++ b/ecc/bls12-377/g1.go @@ -87,12 +87,49 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -106,11 +143,9 @@ func (p *G1Affine) Double(a *G1Affine) *G1Affine { // Sub subs two point in affine coordinates. func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { - var q G1Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G1Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bls12-377/g2.go b/ecc/bls12-377/g2.go index 2119650f1..b10ad7f06 100644 --- a/ecc/bls12-377/g2.go +++ b/ecc/bls12-377/g2.go @@ -79,12 +79,49 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fptower.E2 + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -98,11 +135,9 @@ func (p *G2Affine) Double(a *G2Affine) *G2Affine { // Sub subs two point in affine coordinates. func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { - var q G2Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G2Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bls12-378/g1.go b/ecc/bls12-378/g1.go index 5ef09adeb..10360478d 100644 --- a/ecc/bls12-378/g1.go +++ b/ecc/bls12-378/g1.go @@ -87,12 +87,49 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -106,11 +143,9 @@ func (p *G1Affine) Double(a *G1Affine) *G1Affine { // Sub subs two point in affine coordinates. func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { - var q G1Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G1Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bls12-378/g2.go b/ecc/bls12-378/g2.go index f3df1f3f7..026bca4ac 100644 --- a/ecc/bls12-378/g2.go +++ b/ecc/bls12-378/g2.go @@ -79,12 +79,49 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fptower.E2 + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -98,11 +135,9 @@ func (p *G2Affine) Double(a *G2Affine) *G2Affine { // Sub subs two point in affine coordinates. func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { - var q G2Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G2Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bls12-381/g1.go b/ecc/bls12-381/g1.go index f6703ddbe..019a96203 100644 --- a/ecc/bls12-381/g1.go +++ b/ecc/bls12-381/g1.go @@ -87,12 +87,49 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -106,11 +143,9 @@ func (p *G1Affine) Double(a *G1Affine) *G1Affine { // Sub subs two point in affine coordinates. func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { - var q G1Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G1Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bls12-381/g2.go b/ecc/bls12-381/g2.go index 3c36af2b4..7f08b2662 100644 --- a/ecc/bls12-381/g2.go +++ b/ecc/bls12-381/g2.go @@ -79,12 +79,49 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fptower.E2 + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -98,11 +135,9 @@ func (p *G2Affine) Double(a *G2Affine) *G2Affine { // Sub subs two point in affine coordinates. func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { - var q G2Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G2Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bls24-315/g1.go b/ecc/bls24-315/g1.go index db2081eb0..9672e7b2c 100644 --- a/ecc/bls24-315/g1.go +++ b/ecc/bls24-315/g1.go @@ -87,12 +87,49 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -106,11 +143,9 @@ func (p *G1Affine) Double(a *G1Affine) *G1Affine { // Sub subs two point in affine coordinates. func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { - var q G1Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G1Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bls24-315/g2.go b/ecc/bls24-315/g2.go index a84e2483d..6f529fc37 100644 --- a/ecc/bls24-315/g2.go +++ b/ecc/bls24-315/g2.go @@ -79,12 +79,49 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fptower.E4 + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -98,11 +135,9 @@ func (p *G2Affine) Double(a *G2Affine) *G2Affine { // Sub subs two point in affine coordinates. func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { - var q G2Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G2Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bls24-317/g1.go b/ecc/bls24-317/g1.go index 8a8adc551..892353cac 100644 --- a/ecc/bls24-317/g1.go +++ b/ecc/bls24-317/g1.go @@ -87,12 +87,49 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -106,11 +143,9 @@ func (p *G1Affine) Double(a *G1Affine) *G1Affine { // Sub subs two point in affine coordinates. func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { - var q G1Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G1Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bls24-317/g2.go b/ecc/bls24-317/g2.go index be3f988b6..120c08dfc 100644 --- a/ecc/bls24-317/g2.go +++ b/ecc/bls24-317/g2.go @@ -79,12 +79,49 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fptower.E4 + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -98,11 +135,9 @@ func (p *G2Affine) Double(a *G2Affine) *G2Affine { // Sub subs two point in affine coordinates. func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { - var q G2Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G2Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bn254/g1.go b/ecc/bn254/g1.go index 7ef165ef9..59387cea9 100644 --- a/ecc/bn254/g1.go +++ b/ecc/bn254/g1.go @@ -87,12 +87,49 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -106,11 +143,9 @@ func (p *G1Affine) Double(a *G1Affine) *G1Affine { // Sub subs two point in affine coordinates. func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { - var q G1Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G1Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bn254/g2.go b/ecc/bn254/g2.go index 7a398ef76..2e850ea71 100644 --- a/ecc/bn254/g2.go +++ b/ecc/bn254/g2.go @@ -79,12 +79,49 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fptower.E2 + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -98,11 +135,9 @@ func (p *G2Affine) Double(a *G2Affine) *G2Affine { // Sub subs two point in affine coordinates. func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { - var q G2Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G2Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bw6-633/g1.go b/ecc/bw6-633/g1.go index b62ad3892..5f889c88c 100644 --- a/ecc/bw6-633/g1.go +++ b/ecc/bw6-633/g1.go @@ -87,12 +87,49 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -106,11 +143,9 @@ func (p *G1Affine) Double(a *G1Affine) *G1Affine { // Sub subs two point in affine coordinates. func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { - var q G1Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G1Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bw6-633/g2.go b/ecc/bw6-633/g2.go index 0b533a165..51a1f55c4 100644 --- a/ecc/bw6-633/g2.go +++ b/ecc/bw6-633/g2.go @@ -79,12 +79,49 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -98,11 +135,9 @@ func (p *G2Affine) Double(a *G2Affine) *G2Affine { // Sub subs two point in affine coordinates. func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { - var q G2Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G2Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bw6-756/g1.go b/ecc/bw6-756/g1.go index 78cc02334..066285b9d 100644 --- a/ecc/bw6-756/g1.go +++ b/ecc/bw6-756/g1.go @@ -87,12 +87,49 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -106,11 +143,9 @@ func (p *G1Affine) Double(a *G1Affine) *G1Affine { // Sub subs two point in affine coordinates. func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { - var q G1Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G1Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bw6-756/g2.go b/ecc/bw6-756/g2.go index 5d264423b..86821c022 100644 --- a/ecc/bw6-756/g2.go +++ b/ecc/bw6-756/g2.go @@ -79,12 +79,49 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -98,11 +135,9 @@ func (p *G2Affine) Double(a *G2Affine) *G2Affine { // Sub subs two point in affine coordinates. func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { - var q G2Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G2Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bw6-761/g1.go b/ecc/bw6-761/g1.go index ed1098422..0b6198fe6 100644 --- a/ecc/bw6-761/g1.go +++ b/ecc/bw6-761/g1.go @@ -87,12 +87,49 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -106,11 +143,9 @@ func (p *G1Affine) Double(a *G1Affine) *G1Affine { // Sub subs two point in affine coordinates. func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { - var q G1Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G1Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/bw6-761/g2.go b/ecc/bw6-761/g2.go index f200d00e0..3c01f4b3f 100644 --- a/ecc/bw6-761/g2.go +++ b/ecc/bw6-761/g2.go @@ -79,12 +79,49 @@ func (p *G2Affine) ScalarMultiplicationBase(s *big.Int) *G2Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { var q G2Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -98,11 +135,9 @@ func (p *G2Affine) Double(a *G2Affine) *G2Affine { // Sub subs two point in affine coordinates. func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { - var q G2Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G2Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/ecc/secp256k1/g1.go b/ecc/secp256k1/g1.go index e75e18f96..1417e8b77 100644 --- a/ecc/secp256k1/g1.go +++ b/ecc/secp256k1/g1.go @@ -87,12 +87,49 @@ func (p *G1Affine) ScalarMultiplicationBase(s *big.Int) *G1Affine { } // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { var q G1Jac - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V fp.Element + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -106,11 +143,9 @@ func (p *G1Affine) Double(a *G1Affine) *G1Affine { // Sub subs two point in affine coordinates. func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { - var q G1Jac - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg G1Affine + bneg.Neg(b) + p.Add(a, &bneg) return p } diff --git a/internal/generator/ecc/template/point.go.tmpl b/internal/generator/ecc/template/point.go.tmpl index 944c4c8f9..c173459c1 100644 --- a/internal/generator/ecc/template/point.go.tmpl +++ b/internal/generator/ecc/template/point.go.tmpl @@ -104,12 +104,49 @@ func (p *{{ $TAffine }}) ScalarMultiplicationBase(s *big.Int) *{{ $TAffine }} { // Add adds two point in affine coordinates. +// Jacobian addition with Z1=Z2=1 +// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl func (p *{{ $TAffine }}) Add(a, b *{{ $TAffine }}) *{{ $TAffine }} { var q {{ $TJacobian }} - q.FromAffine(a) - q.AddMixed(b) - p.FromJacobian(&q) - return p + // a is infinity, return b + if a.IsInfinity() { + p.Set(b) + return p + } + // b is infinity, return a + if b.IsInfinity() { + p.Set(a) + return p + } + if a.X.Equal(&b.X) { + // if b == a, we double instead + if a.Y.Equal(&b.Y) { + q.DoubleMixed(a) + return p.FromJacobian(&q) + } else { + // if b == -a, we return 0 + return p.setInfinity() + } + } + var H, HH, I, J, r, V {{.CoordType}} + H.Sub(&b.X, &a.X) + HH.Square(&H) + I.Double(&HH).Double(&I) + J.Mul(&H, &I) + r.Sub(&b.Y, &a.Y) + r.Double(&r) + V.Mul(&a.X, &I) + q.X.Square(&r). + Sub(&q.X, &J). + Sub(&q.X, &V). + Sub(&q.X, &V) + q.Y.Sub(&V, &q.X). + Mul(&q.Y, &r) + J.Mul(&a.Y, &J).Double(&J) + q.Y.Sub(&q.Y, &J) + q.Z.Double(&H) + + return p.FromJacobian(&q) } // Double doubles a point in affine coordinates. @@ -123,15 +160,12 @@ func (p *{{ $TAffine }}) Double(a *{{ $TAffine }}) *{{ $TAffine }} { // Sub subs two point in affine coordinates. func (p *{{ $TAffine }}) Sub(a, b *{{ $TAffine }}) *{{ $TAffine }} { - var q {{ $TJacobian }} - q.FromAffine(a) - b.Y.Neg(&b.Y) - q.AddMixed(b) - p.FromJacobian(&q) + var bneg {{ $TAffine }} + bneg.Neg(b) + p.Add(a, &bneg) return p } - // Equal tests if two points (in Affine coordinates) are equal func (p *{{ $TAffine }}) Equal(a *{{ $TAffine }}) bool { return p.X.Equal(&a.X) && p.Y.Equal(&a.Y) From 6c1de6fc7e0c70bfa1dd1759028308783ef17b50 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Wed, 12 Jun 2024 15:15:25 +0100 Subject: [PATCH 2/2] test(ecc): affine Add involving (0,0) --- ecc/bls12-377/g1_test.go | 33 +++++++++++++++++++ ecc/bls12-377/g2_test.go | 33 +++++++++++++++++++ ecc/bls12-378/g1_test.go | 33 +++++++++++++++++++ ecc/bls12-378/g2_test.go | 33 +++++++++++++++++++ ecc/bls12-381/g1_test.go | 33 +++++++++++++++++++ ecc/bls12-381/g2_test.go | 33 +++++++++++++++++++ ecc/bls24-315/g1_test.go | 33 +++++++++++++++++++ ecc/bls24-315/g2_test.go | 33 +++++++++++++++++++ ecc/bls24-317/g1_test.go | 33 +++++++++++++++++++ ecc/bls24-317/g2_test.go | 33 +++++++++++++++++++ ecc/bn254/g1_test.go | 33 +++++++++++++++++++ ecc/bn254/g2_test.go | 33 +++++++++++++++++++ ecc/bw6-633/g1_test.go | 33 +++++++++++++++++++ ecc/bw6-633/g2_test.go | 33 +++++++++++++++++++ ecc/bw6-756/g1_test.go | 33 +++++++++++++++++++ ecc/bw6-756/g2_test.go | 33 +++++++++++++++++++ ecc/bw6-761/g1_test.go | 33 +++++++++++++++++++ ecc/bw6-761/g2_test.go | 33 +++++++++++++++++++ ecc/secp256k1/g1_test.go | 33 +++++++++++++++++++ .../ecc/template/tests/point.go.tmpl | 33 +++++++++++++++++++ 20 files changed, 660 insertions(+) diff --git a/ecc/bls12-377/g1_test.go b/ecc/bls12-377/g1_test.go index d0f8885f3..c2558e677 100644 --- a/ecc/bls12-377/g1_test.go +++ b/ecc/bls12-377/g1_test.go @@ -247,6 +247,39 @@ func TestG1AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BLS12-377] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BLS12-377] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BLS12-377] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G1Affine diff --git a/ecc/bls12-377/g2_test.go b/ecc/bls12-377/g2_test.go index ae8b55519..6e7876ee6 100644 --- a/ecc/bls12-377/g2_test.go +++ b/ecc/bls12-377/g2_test.go @@ -248,6 +248,39 @@ func TestG2AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BLS12-377] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BLS12-377] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BLS12-377] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G2Affine diff --git a/ecc/bls12-378/g1_test.go b/ecc/bls12-378/g1_test.go index 5a72daaef..8fd0e260b 100644 --- a/ecc/bls12-378/g1_test.go +++ b/ecc/bls12-378/g1_test.go @@ -247,6 +247,39 @@ func TestG1AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BLS12-378] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BLS12-378] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BLS12-378] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G1Affine diff --git a/ecc/bls12-378/g2_test.go b/ecc/bls12-378/g2_test.go index 74d55be45..ac43de860 100644 --- a/ecc/bls12-378/g2_test.go +++ b/ecc/bls12-378/g2_test.go @@ -248,6 +248,39 @@ func TestG2AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BLS12-378] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BLS12-378] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BLS12-378] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G2Affine diff --git a/ecc/bls12-381/g1_test.go b/ecc/bls12-381/g1_test.go index 37ea6660a..7f0fab5a1 100644 --- a/ecc/bls12-381/g1_test.go +++ b/ecc/bls12-381/g1_test.go @@ -247,6 +247,39 @@ func TestG1AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BLS12-381] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BLS12-381] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BLS12-381] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G1Affine diff --git a/ecc/bls12-381/g2_test.go b/ecc/bls12-381/g2_test.go index 408017439..d414651c6 100644 --- a/ecc/bls12-381/g2_test.go +++ b/ecc/bls12-381/g2_test.go @@ -248,6 +248,39 @@ func TestG2AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BLS12-381] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BLS12-381] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BLS12-381] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G2Affine diff --git a/ecc/bls24-315/g1_test.go b/ecc/bls24-315/g1_test.go index b7c4fdae7..c2fed674d 100644 --- a/ecc/bls24-315/g1_test.go +++ b/ecc/bls24-315/g1_test.go @@ -247,6 +247,39 @@ func TestG1AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BLS24-315] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BLS24-315] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BLS24-315] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G1Affine diff --git a/ecc/bls24-315/g2_test.go b/ecc/bls24-315/g2_test.go index 7c5b80c34..9fb276cc1 100644 --- a/ecc/bls24-315/g2_test.go +++ b/ecc/bls24-315/g2_test.go @@ -248,6 +248,39 @@ func TestG2AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BLS24-315] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BLS24-315] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BLS24-315] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G2Affine diff --git a/ecc/bls24-317/g1_test.go b/ecc/bls24-317/g1_test.go index 8a667f4c9..c4909aa9c 100644 --- a/ecc/bls24-317/g1_test.go +++ b/ecc/bls24-317/g1_test.go @@ -247,6 +247,39 @@ func TestG1AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BLS24-317] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BLS24-317] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BLS24-317] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G1Affine diff --git a/ecc/bls24-317/g2_test.go b/ecc/bls24-317/g2_test.go index 513796610..8d11b2422 100644 --- a/ecc/bls24-317/g2_test.go +++ b/ecc/bls24-317/g2_test.go @@ -248,6 +248,39 @@ func TestG2AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BLS24-317] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BLS24-317] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BLS24-317] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G2Affine diff --git a/ecc/bn254/g1_test.go b/ecc/bn254/g1_test.go index 2adce18f8..cfbb1ed07 100644 --- a/ecc/bn254/g1_test.go +++ b/ecc/bn254/g1_test.go @@ -247,6 +247,39 @@ func TestG1AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BN254] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BN254] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BN254] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G1Affine diff --git a/ecc/bn254/g2_test.go b/ecc/bn254/g2_test.go index 1a7f3c641..a8de3339b 100644 --- a/ecc/bn254/g2_test.go +++ b/ecc/bn254/g2_test.go @@ -247,6 +247,39 @@ func TestG2AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BN254] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BN254] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BN254] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G2Affine diff --git a/ecc/bw6-633/g1_test.go b/ecc/bw6-633/g1_test.go index 1fbd11a40..37ff9ba14 100644 --- a/ecc/bw6-633/g1_test.go +++ b/ecc/bw6-633/g1_test.go @@ -247,6 +247,39 @@ func TestG1AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BW6-633] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BW6-633] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BW6-633] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G1Affine diff --git a/ecc/bw6-633/g2_test.go b/ecc/bw6-633/g2_test.go index e85631cbc..271bc6ab0 100644 --- a/ecc/bw6-633/g2_test.go +++ b/ecc/bw6-633/g2_test.go @@ -234,6 +234,39 @@ func TestG2AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BW6-633] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BW6-633] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BW6-633] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G2Affine diff --git a/ecc/bw6-756/g1_test.go b/ecc/bw6-756/g1_test.go index 3d9836cec..a93bed7b9 100644 --- a/ecc/bw6-756/g1_test.go +++ b/ecc/bw6-756/g1_test.go @@ -247,6 +247,39 @@ func TestG1AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BW6-756] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BW6-756] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BW6-756] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G1Affine diff --git a/ecc/bw6-756/g2_test.go b/ecc/bw6-756/g2_test.go index e56f394f1..723c1d143 100644 --- a/ecc/bw6-756/g2_test.go +++ b/ecc/bw6-756/g2_test.go @@ -234,6 +234,39 @@ func TestG2AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BW6-756] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BW6-756] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BW6-756] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G2Affine diff --git a/ecc/bw6-761/g1_test.go b/ecc/bw6-761/g1_test.go index f6993a6a0..a17405039 100644 --- a/ecc/bw6-761/g1_test.go +++ b/ecc/bw6-761/g1_test.go @@ -247,6 +247,39 @@ func TestG1AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BW6-761] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BW6-761] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BW6-761] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G1Affine diff --git a/ecc/bw6-761/g2_test.go b/ecc/bw6-761/g2_test.go index ce8cac914..89f69def8 100644 --- a/ecc/bw6-761/g2_test.go +++ b/ecc/bw6-761/g2_test.go @@ -234,6 +234,39 @@ func TestG2AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[BW6-761] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[BW6-761] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G2Affine + var sInt big.Int + g := g2GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[BW6-761] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G2Affine diff --git a/ecc/secp256k1/g1_test.go b/ecc/secp256k1/g1_test.go index db00aaafb..f55a78e7c 100644 --- a/ecc/secp256k1/g1_test.go +++ b/ecc/secp256k1/g1_test.go @@ -247,6 +247,39 @@ func TestG1AffineOps(t *testing.T) { genScalar := GenFr() + properties.Property("[SECP256K1] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[SECP256K1] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 G1Affine + var sInt big.Int + g := g1GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[SECP256K1] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 G1Affine diff --git a/internal/generator/ecc/template/tests/point.go.tmpl b/internal/generator/ecc/template/tests/point.go.tmpl index 7c473893a..432fec1dc 100644 --- a/internal/generator/ecc/template/tests/point.go.tmpl +++ b/internal/generator/ecc/template/tests/point.go.tmpl @@ -282,6 +282,39 @@ func Test{{ $TAffine }}Ops(t *testing.T) { genScalar := GenFr() + properties.Property("[{{ toUpper .Name }}] Add(P,-P) should return the point at infinity", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 {{ toUpper .PointName }}Affine + var sInt big.Int + g := {{ toLower .PointName }}GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.Neg(&op1) + + op1.Add(&op1, &op2) + return op1.IsInfinity() + + }, + GenFr(), + )) + + properties.Property("[{{ toUpper .Name }}] Add(P,0) and Add(0,P) should return P", prop.ForAll( + func(s fr.Element) bool { + var op1, op2 {{ toUpper .PointName }}Affine + var sInt big.Int + g := {{ toLower .PointName }}GenAff + s.BigInt(&sInt) + op1.ScalarMultiplication(&g, &sInt) + op2.setInfinity() + + op1.Add(&op1, &op2) + op2.Add(&op2, &op1) + return op1.Equal(&op2) + + }, + GenFr(), + )) + properties.Property("[{{ toUpper .Name }}] Add should call double when adding the same point", prop.ForAll( func(s fr.Element) bool { var op1, op2 {{ toUpper .PointName }}Affine