forked from Consensys/gnark
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add BN254 pairing using field emulation * refactor: make methods private * feat: add equality assertion for GT elements * docs: add package documentation and example
- Loading branch information
Showing
8 changed files
with
1,433 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// Package pairing_bn254 implements pairing over BN254 curve. | ||
// | ||
// The implementation follows very closely the implementation of its out-circuit | ||
// counterpart in [gnark-crypto]. | ||
// | ||
// [gnark-crypto]: https://github.com/ConsenSys/gnark-crypto/tree/master/ecc/bn254 | ||
package pairing_bn254 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package pairing_bn254_test | ||
|
||
import ( | ||
"crypto/rand" | ||
"fmt" | ||
|
||
"github.com/consensys/gnark-crypto/ecc" | ||
"github.com/consensys/gnark-crypto/ecc/bn254" | ||
"github.com/consensys/gnark/backend/groth16" | ||
"github.com/consensys/gnark/frontend" | ||
"github.com/consensys/gnark/frontend/cs/r1cs" | ||
"github.com/consensys/gnark/std/algebra/pairing_bn254" | ||
) | ||
|
||
type PairCircuit struct { | ||
InG1 pairing_bn254.G1Affine | ||
InG2 pairing_bn254.G2Affine | ||
Res pairing_bn254.GTEl | ||
} | ||
|
||
func (c *PairCircuit) Define(api frontend.API) error { | ||
pairing, err := pairing_bn254.NewPairing(api) | ||
if err != nil { | ||
return fmt.Errorf("new pairing: %w", err) | ||
} | ||
res, err := pairing.Pair([]*pairing_bn254.G1Affine{&c.InG1}, []*pairing_bn254.G2Affine{&c.InG2}) | ||
if err != nil { | ||
return fmt.Errorf("pair: %w", err) | ||
} | ||
pairing.AssertIsEqual(res, &c.Res) | ||
return nil | ||
} | ||
|
||
func ExamplePairing() { | ||
p, q, err := randomG1G2Affines() | ||
if err != nil { | ||
panic(err) | ||
} | ||
res, err := bn254.Pair([]bn254.G1Affine{p}, []bn254.G2Affine{q}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
circuit := PairCircuit{} | ||
witness := PairCircuit{ | ||
InG1: pairing_bn254.NewG1Affine(p), | ||
InG2: pairing_bn254.NewG2Affine(q), | ||
Res: pairing_bn254.NewGTEl(res), | ||
} | ||
ccs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("compiled") | ||
} | ||
pk, vk, err := groth16.Setup(ccs) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("setup done") | ||
} | ||
secretWitness, err := frontend.NewWitness(&witness, ecc.BN254.ScalarField()) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("secret witness") | ||
} | ||
publicWitness, err := secretWitness.Public() | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("public witness") | ||
} | ||
proof, err := groth16.Prove(ccs, pk, secretWitness) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("proof") | ||
} | ||
err = groth16.Verify(proof, vk, publicWitness) | ||
if err != nil { | ||
panic(err) | ||
} else { | ||
fmt.Println("verify") | ||
} | ||
} | ||
|
||
func randomG1G2Affines() (p bn254.G1Affine, q bn254.G2Affine, err error) { | ||
_, _, G1AffGen, G2AffGen := bn254.Generators() | ||
mod := bn254.ID.ScalarField() | ||
s1, err := rand.Int(rand.Reader, mod) | ||
if err != nil { | ||
return p, q, err | ||
} | ||
s2, err := rand.Int(rand.Reader, mod) | ||
if err != nil { | ||
return p, q, err | ||
} | ||
p.ScalarMultiplication(&G1AffGen, s1) | ||
q.ScalarMultiplication(&G2AffGen, s2) | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package pairing_bn254 | ||
|
||
import ( | ||
"github.com/consensys/gnark-crypto/ecc/bn254" | ||
"github.com/consensys/gnark/std/algebra/weierstrass" | ||
"github.com/consensys/gnark/std/math/emulated" | ||
) | ||
|
||
type G1Affine = weierstrass.AffinePoint[emulated.BN254Fp] | ||
|
||
func NewG1Affine(v bn254.G1Affine) G1Affine { | ||
return G1Affine{ | ||
X: emulated.ValueOf[emulated.BN254Fp](v.X), | ||
Y: emulated.ValueOf[emulated.BN254Fp](v.Y), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package pairing_bn254 | ||
|
||
import ( | ||
"github.com/consensys/gnark-crypto/ecc/bn254" | ||
"github.com/consensys/gnark/std/math/emulated" | ||
) | ||
|
||
type G2Affine struct { | ||
X, Y e2 | ||
} | ||
|
||
type g2Jacobian struct { | ||
X, Y, Z e2 | ||
} | ||
|
||
type g2Projective struct { | ||
X, Y, Z e2 | ||
} | ||
|
||
func NewG2Affine(v bn254.G2Affine) G2Affine { | ||
return G2Affine{ | ||
X: e2{ | ||
A0: emulated.ValueOf[emulated.BN254Fp](v.X.A0), | ||
A1: emulated.ValueOf[emulated.BN254Fp](v.X.A1), | ||
}, | ||
Y: e2{ | ||
A0: emulated.ValueOf[emulated.BN254Fp](v.Y.A0), | ||
A1: emulated.ValueOf[emulated.BN254Fp](v.Y.A1), | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package pairing_bn254 | ||
|
||
import ( | ||
"github.com/consensys/gnark-crypto/ecc/bn254" | ||
"github.com/consensys/gnark/std/math/emulated" | ||
) | ||
|
||
type GTEl = e12 | ||
|
||
func NewGTEl(v bn254.GT) GTEl { | ||
return GTEl{ | ||
C0: e6{ | ||
B0: e2{ | ||
A0: emulated.ValueOf[emulated.BN254Fp](v.C0.B0.A0), | ||
A1: emulated.ValueOf[emulated.BN254Fp](v.C0.B0.A1), | ||
}, | ||
B1: e2{ | ||
A0: emulated.ValueOf[emulated.BN254Fp](v.C0.B1.A0), | ||
A1: emulated.ValueOf[emulated.BN254Fp](v.C0.B1.A1), | ||
}, | ||
B2: e2{ | ||
A0: emulated.ValueOf[emulated.BN254Fp](v.C0.B2.A0), | ||
A1: emulated.ValueOf[emulated.BN254Fp](v.C0.B2.A1), | ||
}, | ||
}, | ||
C1: e6{ | ||
B0: e2{ | ||
A0: emulated.ValueOf[emulated.BN254Fp](v.C1.B0.A0), | ||
A1: emulated.ValueOf[emulated.BN254Fp](v.C1.B0.A1), | ||
}, | ||
B1: e2{ | ||
A0: emulated.ValueOf[emulated.BN254Fp](v.C1.B1.A0), | ||
A1: emulated.ValueOf[emulated.BN254Fp](v.C1.B1.A1), | ||
}, | ||
B2: e2{ | ||
A0: emulated.ValueOf[emulated.BN254Fp](v.C1.B2.A0), | ||
A1: emulated.ValueOf[emulated.BN254Fp](v.C1.B2.A1), | ||
}, | ||
}, | ||
} | ||
} |
Oops, something went wrong.