Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pairing + Groth16 verifier std gadgets #182

Merged
merged 16 commits into from
Nov 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions std/algebra/fields/e12.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,18 +330,18 @@ func (e *E12) Conjugate(api frontend.API, e1 E12) *E12 {
}

// MulBy034 multiplication by sparse element
func (e *E12) MulBy034(api frontend.API, c0, c3, c4 E2, ext Extension) *E12 {
func (e *E12) MulBy034(api frontend.API, c3, c4 E2, ext Extension) *E12 {

var a, b, d E6
var d E6

a.MulByE2(api, e.C0, c0, ext)
a := e.C0
b := e.C1

b = e.C1
b.MulBy01(api, c3, c4, ext)

c0.Add(api, c0, c3)
c3.Add(api, E2{A0: 1, A1: 0}, c3)
d.Add(api, e.C0, e.C1)
d.MulBy01(api, c0, c4, ext)
d.MulBy01(api, c3, c4, ext)

e.C1.Add(api, a, b).Neg(api, e.C1).Add(api, e.C1, d)
e.C0.MulByNonResidue(api, b, ext).Add(api, e.C0, a)
Expand Down
16 changes: 7 additions & 9 deletions std/algebra/fields/e12_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,14 +364,14 @@ func TestExpFinalExpoFp12(t *testing.T) {
}

type fp12MulBy034 struct {
A E12 `gnark:",public"`
W E12
B, C, D E2
A E12 `gnark:",public"`
W E12
B, C E2
}

func (circuit *fp12MulBy034) Define(api frontend.API) error {
ext := GetBLS377ExtensionFp12(api)
circuit.A.MulBy034(api, circuit.B, circuit.C, circuit.D, ext)
circuit.A.MulBy034(api, circuit.B, circuit.C, ext)
circuit.A.MustBeEqual(api, circuit.W)
return nil
}
Expand All @@ -381,7 +381,8 @@ func TestFp12MulBy034(t *testing.T) {
var circuit, witness fp12MulBy034

var a bls12377.E12
var b, c, d bls12377.E2
var b, c, one bls12377.E2
one.SetOne()
a.SetRandom()
witness.A.Assign(&a)

Expand All @@ -391,10 +392,7 @@ func TestFp12MulBy034(t *testing.T) {
c.SetRandom()
witness.C.Assign(&c)

d.SetRandom()
witness.D.Assign(&d)

a.MulBy034(&b, &c, &d)
a.MulBy034(&one, &b, &c)

witness.W.Assign(&a)

Expand Down
33 changes: 33 additions & 0 deletions std/algebra/sw/g1.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,36 @@ func (p *G1Affine) MustBeEqual(api frontend.API, other G1Affine) {
api.AssertIsEqual(p.X, other.X)
api.AssertIsEqual(p.Y, other.Y)
}

// DoubleAndAdd computes 2*p1+p in affine coords
func (p *G1Affine) DoubleAndAdd(api frontend.API, p1, p2 *G1Affine) *G1Affine {

// compute lambda1 = (y2-y1)/(x2-x1)
l1 := api.DivUnchecked(api.Sub(p1.Y, p2.Y), api.Sub(p1.X, p2.X))

// compute x3 = lambda1**2-x1-x2
x3 := api.Mul(l1, l1)
x3 = api.Sub(x3, p1.X)
x3 = api.Sub(x3, p2.X)

// omit y3 computation
// compute lambda2 = -lambda1-2*y1/(x3-x1)
l2 := api.DivUnchecked(api.Add(p1.Y, p1.Y), api.Sub(x3, p1.X))
l2 = api.Add(l2, l1)
l2 = api.Neg(l2)

// compute x4 =lambda2**2-x1-x3
x4 := api.Mul(l2, l2)
x4 = api.Sub(x4, p1.X)
x4 = api.Sub(x4, x3)

// compute y4 = lambda2*(x1 - x4)-y1
y4 := api.Sub(p1.X, x4)
y4 = api.Mul(l2, y4)
y4 = api.Sub(y4, p1.Y)

p.X = x4
p.Y = y4

return p
}
41 changes: 41 additions & 0 deletions std/algebra/sw/g1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,47 @@ func TestDoubleAffineG1(t *testing.T) {

}

// -------------------------------------------------------------------------------------------------
// DoubleAndAdd affine

type g1DoubleAndAddAffine struct {
A, B G1Affine
C G1Affine `gnark:",public"`
}

func (circuit *g1DoubleAndAddAffine) Define(api frontend.API) error {
expected := circuit.A
expected.DoubleAndAdd(api, &circuit.A, &circuit.B)
expected.MustBeEqual(api, circuit.C)
return nil
}

func TestDoubleAndAddAffineG1(t *testing.T) {

// sample 2 random points
_a := randomPointG1()
_b := randomPointG1()
var a, b, c bls12377.G1Affine
a.FromJacobian(&_a)
b.FromJacobian(&_b)

// create the cs
var circuit, witness g1DoubleAndAddAffine

// assign the inputs
witness.A.Assign(&a)
witness.B.Assign(&b)

// compute the result
_a.Double(&_a).AddAssign(&_b)
c.FromJacobian(&_a)
witness.C.Assign(&c)

assert := test.NewAssert(t)
assert.SolvingSucceeded(&circuit, &witness, test.WithCurves(ecc.BW6_761))

}

// -------------------------------------------------------------------------------------------------
// Neg

Expand Down
38 changes: 38 additions & 0 deletions std/algebra/sw/g2.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,41 @@ func (p *G2Affine) MustBeEqual(api frontend.API, other G2Affine) {
p.X.MustBeEqual(api, other.X)
p.Y.MustBeEqual(api, other.Y)
}

// DoubleAndAdd computes 2*p1+p2 in affine coords
func (p *G2Affine) DoubleAndAdd(api frontend.API, p1, p2 *G2Affine, ext fields.Extension) *G2Affine {

var n, d, l1, l2, x3, x4, y4 fields.E2

// compute lambda1 = (y2-y1)/(x2-x1)
n.Sub(api, p1.Y, p2.Y)
d.Sub(api, p1.X, p2.X)
l1.Inverse(api, d, ext).Mul(api, l1, n, ext)

// compute x3 = lambda1**2-x1-x2
x3.Square(api, l1, ext).
Sub(api, x3, p1.X).
Sub(api, x3, p2.X)

// omit y3 computation
// compute lambda2 = -lambda1-2*y1/(x3-x1)
n.Double(api, p1.Y)
d.Sub(api, x3, p1.X)
l2.Inverse(api, d, ext).Mul(api, l2, n, ext)
l2.Add(api, l2, l1).Neg(api, l2)

// compute x4 =lambda2**2-x1-x3
x4.Square(api, l2, ext).
Sub(api, x4, p1.X).
Sub(api, x4, x3)

// compute y4 = lambda2*(x1 - x4)-y1
y4.Sub(api, p1.X, x4).
Mul(api, l2, y4, ext).
Sub(api, y4, p1.Y)

p.X = x4
p.Y = y4

return p
}
76 changes: 76 additions & 0 deletions std/algebra/sw/g2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark-crypto/ecc/bls12-377/fr"
"github.com/consensys/gnark/backend"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/algebra/fields"
"github.com/consensys/gnark/test"
Expand Down Expand Up @@ -142,6 +143,47 @@ func TestDoubleAssignG2(t *testing.T) {

}

// -------------------------------------------------------------------------------------------------
// DoubleAndAdd affine

type g2DoubleAndAddAffine struct {
A, B G2Affine
C G2Affine `gnark:",public"`
}

func (circuit *g2DoubleAndAddAffine) Define(api frontend.API) error {
expected := circuit.A
expected.DoubleAndAdd(api, &circuit.A, &circuit.B, fields.GetBLS377ExtensionFp12(api))
expected.MustBeEqual(api, circuit.C)
return nil
}

func TestDoubleAndAddAffineG2(t *testing.T) {

// sample 2 random points
_a := randomPointG2()
_b := randomPointG2()
var a, b, c bls12377.G2Affine
a.FromJacobian(&_a)
b.FromJacobian(&_b)

// create the cs
var circuit, witness g2DoubleAndAddAffine

// assign the inputs
witness.A.Assign(&a)
witness.B.Assign(&b)

// compute the result
_a.Double(&_a).AddAssign(&_b)
c.FromJacobian(&_a)
witness.C.Assign(&c)

assert := test.NewAssert(t)
assert.SolvingSucceeded(&circuit, &witness, test.WithCurves(ecc.BW6_761))

}

// -------------------------------------------------------------------------------------------------
// Double affine

Expand Down Expand Up @@ -224,3 +266,37 @@ func randomPointG2() bls12377.G2Jac {
p2.ScalarMultiplication(&p2, r1.ToBigIntRegular(&b))
return p2
}

// benches
func BenchmarkDoubleAffineG2(b *testing.B) {
var c g2DoubleAffine
b.Run("groth16", func(b *testing.B) {
for i := 0; i < b.N; i++ {
ccsBench, _ = frontend.Compile(ecc.BW6_761, backend.GROTH16, &c)
}

})
b.Log("groth16", ccsBench.GetNbConstraints())
}

func BenchmarkAddAssignAffineG2(b *testing.B) {
var c g2AddAssignAffine
b.Run("groth16", func(b *testing.B) {
for i := 0; i < b.N; i++ {
ccsBench, _ = frontend.Compile(ecc.BW6_761, backend.GROTH16, &c)
}

})
b.Log("groth16", ccsBench.GetNbConstraints())
}

func BenchmarkDoubleAndAddAffineG2(b *testing.B) {
var c g2DoubleAndAddAffine
b.Run("groth16", func(b *testing.B) {
for i := 0; i < b.N; i++ {
ccsBench, _ = frontend.Compile(ecc.BW6_761, backend.GROTH16, &c)
}

})
b.Log("groth16", ccsBench.GetNbConstraints())
}
Loading