Skip to content

Commit

Permalink
Merge pull request #931 from Consensys/perf/bw6-finalExp
Browse files Browse the repository at this point in the history
Perf: optimize addition chains in BW6-761 final exponentiation
  • Loading branch information
yelhousni authored Nov 22, 2023
2 parents 3aa2559 + 5479586 commit ec07217
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 50 deletions.
28 changes: 15 additions & 13 deletions std/algebra/emulated/fields_bw6761/e6.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fields_bw6761

import (
"math/big"

bw6761 "github.com/consensys/gnark-crypto/ecc/bw6-761"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/math/emulated"
Expand Down Expand Up @@ -137,7 +139,7 @@ func (e Ext6) CyclotomicSquareCompressed(x *E6) *E6 {
t[6] = mulFpByNonResidue(e.fp, t[5])
// t5 = 4 * nr * g1 * g5 + 2 * g3
t[5] = e.fp.Add(t[6], &x.B1.A0)
t[5] = e.fp.Add(t[5], t[5])
t[5] = e.fp.MulConst(t[5], big.NewInt(2))
// z3 = 6 * nr * g1 * g5 + 2 * g3
z.B1.A0 = *e.fp.Add(t[5], t[6])

Expand All @@ -152,7 +154,7 @@ func (e Ext6) CyclotomicSquareCompressed(x *E6) *E6 {
t[1] = e.fp.Mul(&x.B0.A2, &x.B0.A2)

// t6 = 2 * nr * g5² + 2 * g1² - 2*g2
t[6] = e.fp.Add(t[6], t[6])
t[6] = e.fp.MulConst(t[6], big.NewInt(2))
// z2 = 3 * nr * g5² + 3 * g1² - 2*g2
z.B0.A2 = *e.fp.Add(t[6], t[5])

Expand All @@ -163,7 +165,7 @@ func (e Ext6) CyclotomicSquareCompressed(x *E6) *E6 {
// t6 = g3² + nr * g2² - g1
t[6] = e.fp.Sub(t[5], &x.B0.A1)
// t6 = 2 * g3² + 2 * nr * g2² - 2 * g1
t[6] = e.fp.Add(t[6], t[6])
t[6] = e.fp.MulConst(t[6], big.NewInt(2))
// z1 = 3 * g3² + 3 * nr * g2² - 2 * g1
z.B0.A1 = *e.fp.Add(t[6], t[5])

Expand All @@ -174,7 +176,7 @@ func (e Ext6) CyclotomicSquareCompressed(x *E6) *E6 {
// t6 = 2 * g3 * g2 + g5
t[6] = e.fp.Add(t[5], &x.B1.A2)
// t6 = 4 * g3 * g2 + 2 * g5
t[6] = e.fp.Add(t[6], t[6])
t[6] = e.fp.MulConst(t[6], big.NewInt(2))
// z5 = 6 * g3 * g2 + 2 * g5
z.B1.A2 = *e.fp.Add(t[5], t[6])

Expand Down Expand Up @@ -207,7 +209,7 @@ func (e Ext6) DecompressKarabina(x *E6) *E6 {
// t1 = g2
selector1 := e.fp.IsZero(&x.B1.A0)
_t[0] = e.fp.Mul(&x.B0.A1, &x.B0.A1)
_t[0] = e.fp.Add(_t[0], _t[0])
_t[0] = e.fp.MulConst(_t[0], big.NewInt(2))
_t[1] = &x.B0.A2

// if g2 == g3 == 0
Expand All @@ -218,13 +220,13 @@ func (e Ext6) DecompressKarabina(x *E6) *E6 {
// t1 = 4 * g3
t[0] = e.fp.Mul(&x.B0.A1, &x.B0.A1)
t[1] = e.fp.Sub(t[0], &x.B0.A2)
t[1] = e.fp.Add(t[1], t[1])
t[1] = e.fp.MulConst(t[1], big.NewInt(2))
t[1] = e.fp.Add(t[1], t[0])
t[2] = e.fp.Mul(&x.B1.A2, &x.B1.A2)
t[0] = mulFpByNonResidue(e.fp, t[2])
t[0] = e.fp.Add(t[0], t[1])
t[1] = e.fp.Add(&x.B1.A0, &x.B1.A0)
t[1] = e.fp.Add(t[1], t[1])
t[1] = e.fp.MulConst(t[1], big.NewInt(2))

// g4 = (E * g5^2 + 3 * g1^2 - 2 * g2)/4g3 or (2 * g1 * g5)/g2
t[0] = e.fp.Select(selector1, _t[0], t[0])
Expand All @@ -240,7 +242,7 @@ func (e Ext6) DecompressKarabina(x *E6) *E6 {
// t2 = 2 * g4² - 3 * g2 * g1
t[2] = e.fp.Mul(&z.B1.A1, &z.B1.A1)
t[2] = e.fp.Sub(t[2], t[1])
t[2] = e.fp.Add(t[2], t[2])
t[2] = e.fp.MulConst(t[2], big.NewInt(2))
t[2] = e.fp.Sub(t[2], t[1])
// t1 = g3 * g5 (g3 can be 0)
t[1] = e.fp.Mul(&x.B1.A0, &x.B1.A2)
Expand Down Expand Up @@ -302,20 +304,20 @@ func (e Ext6) CyclotomicSquare(x *E6) *E6 {

var z E6
z.B0.A0 = *e.fp.Sub(t[0], &x.B0.A0)
z.B0.A0 = *e.fp.Add(&z.B0.A0, &z.B0.A0)
z.B0.A0 = *e.fp.MulConst(&z.B0.A0, big.NewInt(2))
z.B0.A0 = *e.fp.Add(&z.B0.A0, t[0])
z.B0.A1 = *e.fp.Sub(t[2], &x.B0.A1)
z.B0.A1 = *e.fp.Add(&z.B0.A1, &z.B0.A1)
z.B0.A1 = *e.fp.MulConst(&z.B0.A1, big.NewInt(2))
z.B0.A1 = *e.fp.Add(&z.B0.A1, t[2])
z.B0.A2 = *e.fp.Sub(t[4], &x.B0.A2)
z.B0.A2 = *e.fp.Add(&z.B0.A2, &z.B0.A2)
z.B0.A2 = *e.fp.MulConst(&z.B0.A2, big.NewInt(2))
z.B0.A2 = *e.fp.Add(&z.B0.A2, t[4])

z.B1.A0 = *e.fp.Add(t[8], &x.B1.A0)
z.B1.A0 = *e.fp.Add(&z.B1.A0, &z.B1.A0)
z.B1.A0 = *e.fp.MulConst(&z.B1.A0, big.NewInt(2))
z.B1.A0 = *e.fp.Add(&z.B1.A0, t[8])
z.B1.A1 = *e.fp.Add(t[6], &x.B1.A1)
z.B1.A1 = *e.fp.Add(&z.B1.A1, &z.B1.A1)
z.B1.A1 = *e.fp.MulConst(&z.B1.A1, big.NewInt(2))
z.B1.A1 = *e.fp.Add(&z.B1.A1, t[6])
z.B1.A2 = *e.fp.Add(t[7], &x.B1.A2)
z.B1.A2 = *e.fp.Add(&z.B1.A2, &z.B1.A2)
Expand Down
91 changes: 54 additions & 37 deletions std/algebra/emulated/fields_bw6761/e6_pairing.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package fields_bw6761

import (
"math/big"

"github.com/consensys/gnark/std/math/emulated"
)

func (e Ext6) nSquareCompressed(z *E6, n int) *E6 {
for i := 0; i < n; i++ {
z = e.CyclotomicSquareCompressed(z)
Expand All @@ -8,7 +14,7 @@ func (e Ext6) nSquareCompressed(z *E6, n int) *E6 {
}

// ExpX0Minus1 set z to z^{x₀-1} in E6 and return z
// x₀-1 = 91893752504881257682351033800651177983
// x₀-1 = 9586122913090633728
func (e Ext6) ExpX0Minus1(z *E6) *E6 {
z = e.Reduce(z)
result := e.Copy(z)
Expand All @@ -35,27 +41,27 @@ func (e Ext6) ExpX0Minus1(z *E6) *E6 {
func (e Ext6) ExpX0Minus1Square(z *E6) *E6 {
z = e.Reduce(z)
result := e.Copy(z)
result = e.CyclotomicSquare(result)
t0 := e.Mul(z, result)
result = e.nSquareCompressed(result, 3)
result = e.DecompressKarabina(result)
t0 := e.CyclotomicSquare(result)
t2 := e.Mul(z, t0)
result = e.Mul(result, t2)
t0 = e.Mul(z, result)
t1 := e.CyclotomicSquare(t0)
t0 = e.Mul(t0, t1)
result = e.Mul(result, t0)
t1 = e.Mul(t1, result)
t0 = e.Mul(t0, t1)
t2 := e.CyclotomicSquare(t0)
t2 = e.Mul(t1, t2)
t0 = e.Mul(t0, t2)
t2 = e.nSquareCompressed(t2, 7)
t1 = e.Mul(t2, t1)
t3 := e.nSquareCompressed(t1, 7)
t3 = e.DecompressKarabina(t3)
t2 = e.Mul(t2, t3)
t2 = e.nSquareCompressed(t2, 11)
t2 = e.DecompressKarabina(t2)
t1 = e.Mul(t1, t2)
t1 = e.nSquareCompressed(t1, 11)
t1 = e.DecompressKarabina(t1)
t1 = e.Mul(t0, t1)
t1 = e.nSquareCompressed(t1, 9)
t1 = e.DecompressKarabina(t1)
t0 = e.Mul(t0, t1)
t0 = e.CyclotomicSquare(t0)
t0 = e.nSquareCompressed(t0, 7)
t0 = e.DecompressKarabina(t0)
result = e.Mul(result, t0)
result = e.nSquareCompressed(result, 3)
result = e.DecompressKarabina(result)
result = e.Mul(z, result)
result = e.nSquareCompressed(result, 92)
result = e.DecompressKarabina(result)

Expand All @@ -64,11 +70,27 @@ func (e Ext6) ExpX0Minus1Square(z *E6) *E6 {
}

// ExpX0Plus1 set z to z^(x₀+1) in E6 and return z
// x₀+1 = 91893752504881257682351033800651177985
// x₀+1 = 9586122913090633730
func (e Ext6) ExpX0Plus1(z *E6) *E6 {
result := e.ExpX0Minus1(z)
t := e.CyclotomicSquare(z)
z = e.Reduce(z)
result := e.Copy(z)
t := e.CyclotomicSquare(result)
result = e.nSquareCompressed(t, 4)
result = e.DecompressKarabina(result)
result = e.Mul(result, z)
z33 := e.Copy(result)
result = e.nSquareCompressed(result, 7)
result = e.DecompressKarabina(result)
result = e.Mul(result, z33)
result = e.nSquareCompressed(result, 4)
result = e.DecompressKarabina(result)
result = e.Mul(result, z)
result = e.CyclotomicSquare(result)
result = e.Mul(result, z)
result = e.nSquareCompressed(result, 46)
result = e.DecompressKarabina(result)
result = e.Mul(result, t)

return result
}

Expand All @@ -78,12 +100,11 @@ func (e Ext6) ExptMinus1Div3(z *E6) *E6 {
z = e.Reduce(z)
result := e.Copy(z)
result = e.CyclotomicSquare(result)
result = e.CyclotomicSquare(result)
result = e.Mul(result, z)
t0 := e.Mul(result, z)
t0 = e.CyclotomicSquare(t0)
result = e.Mul(result, t0)
t0 = result
t0 = e.nSquareCompressed(t0, 7)
result = e.CyclotomicSquare(result)
result = e.Mul(result, z)
t0 := e.nSquareCompressed(result, 7)
t0 = e.DecompressKarabina(t0)
result = e.Mul(result, t0)
result = e.nSquareCompressed(result, 5)
Expand All @@ -100,11 +121,12 @@ func (e Ext6) ExptMinus1Div3(z *E6) *E6 {
// C1 = (ht+hy)/2 = 11
func (e Ext6) ExpC1(z *E6) *E6 {
z = e.Reduce(z)
result := e.CyclotomicSquare(z)
result := e.Copy(z)
result = e.CyclotomicSquare(result)
result = e.CyclotomicSquare(result)
result = e.Mul(result, z)
result = e.CyclotomicSquare(result)
result = e.Mul(result, z)
t0 := e.Mul(z, result)
t0 = e.CyclotomicSquare(t0)
result = e.Mul(result, t0)

return result
}
Expand All @@ -114,11 +136,9 @@ func (e Ext6) ExpC1(z *E6) *E6 {
// C2 = (ht**2+3*hy**2)/4 = 103
func (e Ext6) ExpC2(z *E6) *E6 {
z = e.Reduce(z)

result := e.CyclotomicSquare(z)
result = e.Mul(result, z)
t0 := result
t0 = e.nSquareCompressed(t0, 4)
t0 := e.nSquareCompressed(result, 4)
t0 = e.DecompressKarabina(t0)
result = e.Mul(result, t0)
result = e.CyclotomicSquare(result)
Expand Down Expand Up @@ -193,11 +213,8 @@ func (e Ext6) Mul014By014(d0, d1, c0, c1 *baseEl) [5]*baseEl {
x14 = e.fp.Sub(x14, x1)
x14 = e.fp.Sub(x14, one)

zC0B0 := e.fp.Add(one, one)
zC0B0 = e.fp.Add(zC0B0, zC0B0)
zC0B0 = e.fp.Neg(zC0B0)

zC0B0 = e.fp.Add(zC0B0, x0)
four := emulated.ValueOf[emulated.BW6761Fp](big.NewInt(4))
zC0B0 := e.fp.Sub(x0, &four)

return [5]*baseEl{zC0B0, x01, x1, x04, x14}
}
Expand Down

0 comments on commit ec07217

Please sign in to comment.