Skip to content

Commit

Permalink
Merge pull request #876 from Consensys/feat/bw6761-fixed-pairing
Browse files Browse the repository at this point in the history
Refactor(BW6-761): use revisited Ate pairing instead of Tate
  • Loading branch information
yelhousni authored Oct 24, 2023
2 parents 4dbc3c6 + 4937e78 commit b1768ff
Show file tree
Hide file tree
Showing 7 changed files with 1,165 additions and 200 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/bits-and-blooms/bitset v1.8.0
github.com/blang/semver/v4 v4.0.0
github.com/consensys/bavard v0.1.13
github.com/consensys/gnark-crypto v0.12.2-0.20231020130238-7e44877e07c5
github.com/consensys/gnark-crypto v0.12.2-0.20231023220848-538dff926c15
github.com/fxamacker/cbor/v2 v2.5.0
github.com/google/go-cmp v0.5.9
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
github.com/consensys/gnark-crypto v0.12.2-0.20231020130238-7e44877e07c5 h1:Ud0E+vD8mIknsNJAut+yn/QMKp5mkT06z+sLHKezMQU=
github.com/consensys/gnark-crypto v0.12.2-0.20231020130238-7e44877e07c5/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY=
github.com/consensys/gnark-crypto v0.12.2-0.20231017134050-6652a8b98254 h1:21iGClQpXhJ0PA6lRBpRbpmJFtfdV7R9QMCsQJ3A9mA=
github.com/consensys/gnark-crypto v0.12.2-0.20231017134050-6652a8b98254/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY=
github.com/consensys/gnark-crypto v0.12.2-0.20231023220848-538dff926c15 h1:fu5ienFKWWqrfMPbWnhw4zfIFZW3pzVIbv3KtASymbU=
github.com/consensys/gnark-crypto v0.12.2-0.20231023220848-538dff926c15/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down
185 changes: 72 additions & 113 deletions std/algebra/emulated/fields_bw6761/e6_pairing.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,65 +127,32 @@ func (e Ext6) ExpC2(z *E6) *E6 {
return result
}

// Square034 squares an E6 sparse element of the form
// MulBy014 multiplies z by an E6 sparse element of the form
//
// E6{
// B0: E3{A0: 1, A1: 0, A2: 0},
// B1: E3{A0: c3, A1: c4, A2: 0},
// B0: E3{A0: c0, A1: c1, A2: 0},
// B1: E3{A0: 0, A1: 1, A2: 0},
// }
func (e *Ext6) Square034(x *E6) *E6 {
x = e.Reduce(x)
c0 := &E3{
A0: *e.fp.Sub(&x.B0.A0, &x.B1.A0),
A1: *e.fp.Neg(&x.B1.A1),
A2: *e.fp.Zero(),
}

c3 := &E3{
A0: x.B0.A0,
A1: *e.fp.Neg(&x.B1.A0),
A2: *e.fp.Neg(&x.B1.A1),
}

c2 := &E3{
A0: x.B1.A0,
A1: x.B1.A1,
A2: *e.fp.Zero(),
}
c3 = e.MulBy01(c3, &c0.A0, &c0.A1)
c3 = e.Ext3.Add(c3, c2)

var z E6
z.B1.A0 = *e.fp.Add(&c2.A0, &c2.A0)
z.B1.A1 = *e.fp.Add(&c2.A1, &c2.A1)

z.B0.A0 = c3.A0
z.B0.A1 = *e.fp.Add(&c3.A1, &c2.A0)
z.B0.A2 = *e.fp.Add(&c3.A2, &c2.A1)
func (e *Ext6) MulBy014(z *E6, c0, c1 *baseEl) *E6 {
z = e.Reduce(z)

return &z
}
a := e.MulBy01(&z.B0, c0, c1)

// MulBy034 multiplies z by an E6 sparse element of the form
//
// E6{
// B0: E3{A0: 1, A1: 0, A2: 0},
// B1: E3{A0: c3, A1: c4, A2: 0},
// }
func (e *Ext6) MulBy034(z *E6, c3, c4 *baseEl) *E6 {
var b E3
// Mul by E3{0, 1, 0}
b.A0 = *mulFpByNonResidue(e.fp, &z.B1.A2)
b.A2 = z.B1.A1
b.A1 = z.B1.A0

z = e.Reduce(z)
a := z.B0
b := e.MulBy01(&z.B1, c3, c4)
c3 = e.fp.Add(e.fp.One(), c3)
d := e.Ext3.Add(&z.B0, &z.B1)
d = e.MulBy01(d, c3, c4)
one := e.fp.One()
d := e.fp.Add(c1, one)

zC1 := e.Ext3.Add(&a, b)
zC1 = e.Ext3.Neg(zC1)
zC1 = e.Ext3.Add(zC1, d)
zC0 := e.Ext3.MulByNonResidue(b)
zC0 = e.Ext3.Add(zC0, &a)
zC1 := e.Ext3.Add(&z.B1, &z.B0)
zC1 = e.Ext3.MulBy01(zC1, c0, d)
zC1 = e.Ext3.Sub(zC1, a)
zC1 = e.Ext3.Sub(zC1, &b)
zC0 := e.Ext3.MulByNonResidue(&b)
zC0 = e.Ext3.Add(zC0, a)

return &E6{
B0: *zC0,
Expand All @@ -196,85 +163,77 @@ func (e *Ext6) MulBy034(z *E6, c3, c4 *baseEl) *E6 {
// multiplies two E6 sparse element of the form:
//
// E6{
// C0: E6{B0: 1, B1: 0, B2: 0},
// C1: E6{B0: c3, B1: c4, B2: 0},
// B0: E3{A0: c0, A1: c1, A2: 0},
// B1: E3{A0: 0, A1: 1, A2: 0},
// }
//
// and
//
// E6{
// C0: E6{B0: 1, B1: 0, B2: 0},
// C1: E6{B0: d3, B1: d4, B2: 0},
// B0: E3{A0: d0, A1: d1, A2: 0},
// B1: E3{A0: 0, A1: 1, A2: 0},
// }
func (e *Ext6) Mul034By034(d3, d4, c3, c4 *baseEl) [5]*baseEl {
x3 := e.fp.Mul(c3, d3)
x4 := e.fp.Mul(c4, d4)
x04 := e.fp.Add(c4, d4)
x03 := e.fp.Add(c3, d3)
tmp := e.fp.Add(c3, c4)
x34 := e.fp.Add(d3, d4)
x34 = e.fp.Mul(x34, tmp)
x34 = e.fp.Sub(x34, x3)
x34 = e.fp.Sub(x34, x4)

zC0B0 := mulFpByNonResidue(e.fp, x4)
zC0B0 = e.fp.Add(zC0B0, e.fp.One())
zC0B1 := x3
zC0B2 := x34
zC1B0 := x03
zC1B1 := x04

return [5]*baseEl{zC0B0, zC0B1, zC0B2, zC1B0, zC1B1}
func (e Ext6) Mul014By014(d0, d1, c0, c1 *baseEl) [5]*baseEl {
one := e.fp.One()
x0 := e.fp.Mul(c0, d0)
x1 := e.fp.Mul(c1, d1)
tmp := e.fp.Add(c0, one)
x04 := e.fp.Add(d0, one)
x04 = e.fp.Mul(x04, tmp)
x04 = e.fp.Sub(x04, x0)
x04 = e.fp.Sub(x04, one)
tmp = e.fp.Add(c0, c1)
x01 := e.fp.Add(d0, d1)
x01 = e.fp.Mul(x01, tmp)
x01 = e.fp.Sub(x01, x0)
x01 = e.fp.Sub(x01, x1)
tmp = e.fp.Add(c1, one)
x14 := e.fp.Add(d1, one)
x14 = e.fp.Mul(x14, tmp)
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)

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

// MulBy01234 multiplies z by an E6 sparse element of the form
// Mul01245By014 multiplies two E6 sparse element of the form
//
// E6{
// C0: E3{A0: c0, A1: c1, A2: c2},
// C1: E3{A0: c3, A1: c4, A2: 0},
// C0: E3{B0: x0, B1: x1, B2: x2},
// C1: E3{B0: 0, B1: x4, B2: x5},
// }
func (e *Ext6) MulBy01234(z *E6, x [5]*baseEl) *E6 {
c0 := &E3{A0: *x[0], A1: *x[1], A2: *x[2]}
c1 := &E3{A0: *x[3], A1: *x[4], A2: *e.fp.Zero()}
a := e.Ext3.Add(&z.B0, &z.B1)
b := e.Ext3.Add(c0, c1)
a = e.Ext3.Mul(a, b)
b = e.Ext3.Mul(&z.B0, c0)
c := e.Ext3.MulBy01(&z.B1, x[3], x[4])
z1 := e.Ext3.Sub(a, b)
z1 = e.Ext3.Sub(z1, c)
z0 := e.Ext3.MulByNonResidue(c)
z0 = e.Ext3.Add(z0, b)
return &E6{
B0: *z0,
B1: *z1,
}
}

// multiplies two E6 sparse element of the form:
//
// E6{
// C0: E2{A0: x0, A1: x1, A2: x2},
// C1: E2{A0: x3, A1: x4, A2: 0},
// }
//
// and
// and
//
// E6{
// C0: E3{A0: 1, A1: 0, A2: 0},
// C1: E3{A0: z3, A1: z4, A2: 0},
// C0: E3{B0: d0, B1: d1, B2: 0},
// C1: E3{B0: 0, B1: 1, B2: 0},
// }
func (e *Ext6) Mul01234By034(x [5]*baseEl, z3, z4 *baseEl) *E6 {
func (e *Ext6) Mul01245By014(x [5]*baseEl, d0, d1 *baseEl) *E6 {
zero := e.fp.Zero()
c0 := &E3{A0: *x[0], A1: *x[1], A2: *x[2]}
c1 := &E3{A0: *x[3], A1: *x[4], A2: *e.fp.Zero()}
a := e.Ext3.Add(e.Ext3.One(), &E3{A0: *z3, A1: *z4, A2: *e.fp.Zero()})
b := e.Ext3.Add(c0, c1)
a = e.Ext3.Mul(a, b)
c := e.Ext3.Mul01By01(z3, z4, x[3], x[4])
z1 := e.Ext3.Sub(a, c0)
b := &E3{
A0: *x[0],
A1: *e.fp.Add(x[1], x[3]),
A2: *e.fp.Add(x[2], x[4]),
}
a := e.Ext3.MulBy01(b, d0, e.fp.Add(d1, e.fp.One()))
b = e.Ext3.MulBy01(c0, d0, d1)
c := &E3{
A0: *mulFpByNonResidue(e.fp, x[4]),
A1: *zero,
A2: *x[3],
}
z1 := e.Ext3.Sub(a, b)
z1 = e.Ext3.Sub(z1, c)
z0 := e.Ext3.MulByNonResidue(c)
z0 = e.Ext3.Add(z0, c0)
z0 = e.Ext3.Add(z0, b)
return &E6{
B0: *z0,
B1: *z1,
Expand Down
14 changes: 7 additions & 7 deletions std/algebra/emulated/fields_bw6761/e6_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,20 +365,20 @@ func TestExptFp6(t *testing.T) {
assert.NoError(err)
}

type e6MulBy034 struct {
type e6MulBy014 struct {
A E6 `gnark:",public"`
W E6
B, C baseEl
}

func (circuit *e6MulBy034) Define(api frontend.API) error {
func (circuit *e6MulBy014) Define(api frontend.API) error {
e := NewExt6(api)
res := e.MulBy034(&circuit.A, &circuit.B, &circuit.C)
res := e.MulBy014(&circuit.A, &circuit.B, &circuit.C)
e.AssertIsEqual(res, &circuit.W)
return nil
}

func TestFp12MulBy034(t *testing.T) {
func TestFp6MulBy014(t *testing.T) {

assert := test.NewAssert(t)
// witness values
Expand All @@ -389,16 +389,16 @@ func TestFp12MulBy034(t *testing.T) {
_, _ = b.SetRandom()
_, _ = c.SetRandom()
w.Set(&a)
w.MulBy034(&one, &b, &c)
w.MulBy014(&b, &c, &one)

witness := e6MulBy034{
witness := e6MulBy014{
A: FromE6(&a),
B: emulated.ValueOf[emulated.BW6761Fp](&b),
C: emulated.ValueOf[emulated.BW6761Fp](&c),
W: FromE6(&w),
}

err := test.IsSolved(&e6MulBy034{}, &witness, ecc.BN254.ScalarField())
err := test.IsSolved(&e6MulBy014{}, &witness, ecc.BN254.ScalarField())
assert.NoError(err)

}
Loading

0 comments on commit b1768ff

Please sign in to comment.