Documentation ¶
Overview ¶
Package sw_bn254 implements G1 and G2 arithmetics and pairing computation over BN254 curve.
The implementation follows [Housni22]: "Pairings in Rank-1 Constraint Systems".
Index ¶
- func GetHints() []solver.Hint
- type BaseField
- type G1Affine
- type G2
- type G2Affine
- type GTEl
- type Pairing
- func (pr Pairing) AssertIsEqual(x, y *GTEl)
- func (pr Pairing) AssertIsOnCurve(P *G1Affine)
- func (pr Pairing) AssertIsOnG1(P *G1Affine)
- func (pr Pairing) AssertIsOnG2(Q *G2Affine)
- func (pr Pairing) AssertIsOnTwist(Q *G2Affine)
- func (pr Pairing) AssertMillerLoopAndFinalExpIsOne(P *G1Affine, Q *G2Affine, previous *GTEl)
- func (pr Pairing) FinalExponentiation(e *GTEl) *GTEl
- func (pr Pairing) FinalExponentiationUnsafe(e *GTEl) *GTEl
- func (pr Pairing) IsEqual(x, y *GTEl) frontend.Variable
- func (pr Pairing) IsMillerLoopAndFinalExpOne(P *G1Affine, Q *G2Affine, previous *GTEl) frontend.Variable
- func (pr Pairing) IsOnG2(Q *G2Affine) frontend.Variable
- func (pr Pairing) IsOnTwist(Q *G2Affine) frontend.Variable
- func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error)
- func (pr Pairing) MillerLoopAndMul(P *G1Affine, Q *G2Affine, previous *GTEl) (*GTEl, error)
- func (pr Pairing) Pair(P []*G1Affine, Q []*G2Affine) (*GTEl, error)
- func (pr Pairing) PairingCheck(P []*G1Affine, Q []*G2Affine) error
- type Scalar
- type ScalarField
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type BaseField ¶
BaseField is the emulated.FieldParams implementation of the curve base field.
type G1Affine ¶
type G1Affine = sw_emulated.AffinePoint[BaseField]
G1Affine is the point in G1. It is an alias to the generic emulated affine point.
func NewG1Affine ¶
NewG1Affine allocates a witness from the native G1 element and returns it.
type G2 ¶
type G2 struct { *fields_bn254.Ext2 // contains filtered or unexported fields }
func (*G2) AssertIsEqual ¶
AssertIsEqual asserts that p and q are the same point.
type G2Affine ¶
type G2Affine struct { P g2AffP Lines *lineEvaluations }
G2Affine represents G2 element with optional embedded line precomputations.
func NewG2Affine ¶
func NewG2AffineFixed ¶
NewG2AffineFixed returns witness of v with precomputations for efficient pairing computation.
func NewG2AffineFixedPlaceholder ¶
func NewG2AffineFixedPlaceholder() G2Affine
NewG2AffineFixedPlaceholder returns a placeholder for the circuit compilation when witness will be given with line precomputations using NewG2AffineFixed.
type Pairing ¶
type Pairing struct { *fields_bn254.Ext12 // contains filtered or unexported fields }
Example ¶
package main 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/emulated/sw_bn254" ) type PairCircuit struct { InG1 sw_bn254.G1Affine InG2 sw_bn254.G2Affine Res sw_bn254.GTEl } func (c *PairCircuit) Define(api frontend.API) error { pairing, err := sw_bn254.NewPairing(api) if err != nil { return fmt.Errorf("new pairing: %w", err) } // Pair method does not check that the points are in the proper groups. pairing.AssertIsOnG1(&c.InG1) pairing.AssertIsOnG2(&c.InG2) // Compute the pairing res, err := pairing.Pair([]*sw_bn254.G1Affine{&c.InG1}, []*sw_bn254.G2Affine{&c.InG2}) if err != nil { return fmt.Errorf("pair: %w", err) } pairing.AssertIsEqual(res, &c.Res) return nil } func main() { 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: sw_bn254.NewG1Affine(p), InG2: sw_bn254.NewG2Affine(q), Res: sw_bn254.NewGTEl(res), } ccs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) if err != nil { panic(err) } pk, vk, err := groth16.Setup(ccs) if err != nil { panic(err) } secretWitness, err := frontend.NewWitness(&witness, ecc.BN254.ScalarField()) if err != nil { panic(err) } publicWitness, err := secretWitness.Public() if err != nil { panic(err) } proof, err := groth16.Prove(ccs, pk, secretWitness) if err != nil { panic(err) } err = groth16.Verify(proof, vk, publicWitness) if err != nil { panic(err) } } 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 }
Output:
func (Pairing) AssertIsEqual ¶
func (Pairing) AssertIsOnCurve ¶
func (Pairing) AssertIsOnG1 ¶
func (Pairing) AssertIsOnG2 ¶
func (Pairing) AssertIsOnTwist ¶
func (Pairing) AssertMillerLoopAndFinalExpIsOne ¶
AssertMillerLoopAndFinalExpIsOne computes the Miller loop between P and Q, multiplies it in 𝔽p¹² by previous and checks that the result lies in the same equivalence class as the reduced pairing purported to be 1. This check replaces the final exponentiation step in-circuit and follows Section 4 of On Proving Pairings paper by A. Novakovic and L. Eagen.
This method is needed for evmprecompiles/ecpair.
func (Pairing) FinalExponentiation ¶
FinalExponentiation computes the exponentiation eᵈ where
d = (p¹²-1)/r = (p¹²-1)/Φ₁₂(p) ⋅ Φ₁₂(p)/r = (p⁶-1)(p²+1)(p⁴ - p² +1)/r.
We use instead d'= s ⋅ d, where s is the cofactor
2x₀(6x₀²+3x₀+1)
and r does NOT divide d'
FinalExponentiation returns a decompressed element in E12.
This is the safe version of the method where e may be {-1,1}. If it is known that e ≠ {-1,1} then using the unsafe version of the method saves considerable amount of constraints. When called with the result of [MillerLoop], then current method is applicable when length of the inputs to Miller loop is 1.
func (Pairing) FinalExponentiationUnsafe ¶
FinalExponentiationUnsafe computes the exponentiation eᵈ where
d = (p¹²-1)/r = (p¹²-1)/Φ₁₂(p) ⋅ Φ₁₂(p)/r = (p⁶-1)(p²+1)(p⁴ - p² +1)/r.
We use instead d'= s ⋅ d, where s is the cofactor
2x₀(6x₀²+3x₀+1)
and r does NOT divide d'
FinalExponentiationUnsafe returns a decompressed element in E12.
This is the unsafe version of the method where e may NOT be {-1,1}. If e ∈ {-1, 1}, then there exists no valid solution to the circuit. This method is applicable when called with the result of [MillerLoop] method when the length of the inputs to Miller loop is 1.
func (Pairing) IsMillerLoopAndFinalExpOne ¶
func (pr Pairing) IsMillerLoopAndFinalExpOne(P *G1Affine, Q *G2Affine, previous *GTEl) frontend.Variable
IsMillerLoopAndFinalExpOne computes the Miller loop between P and Q, multiplies it in 𝔽p¹² by previous and and returns a boolean indicating if the result lies in the same equivalence class as the reduced pairing purported to be 1. This check replaces the final exponentiation step in-circuit and follows Section 4 of On Proving Pairings paper by A. Novakovic and L. Eagen.
This method is needed for evmprecompiles/ecpair.
func (Pairing) IsOnG2 ¶
IsOnG2 returns a boolean indicating if the G2 point is in the subgroup. The method assumes that the point is already on the curve. Call Pairing.AssertIsOnTwist before to ensure point is on the curve.
func (Pairing) MillerLoop ¶
MillerLoop computes the multi-Miller loop ∏ᵢ { fᵢ_{6x₀+2,Q}(P) · ℓᵢ_{[6x₀+2]Q,π(Q)}(P) · ℓᵢ_{[6x₀+2]Q+π(Q),-π²(Q)}(P) }
func (Pairing) MillerLoopAndMul ¶
MillerLoopAndMul computes the Miller loop between P and Q and multiplies it in 𝔽p¹² by previous.
This method is needed for evmprecompiles/ecpair.
func (Pairing) Pair ¶
Pair calculates the reduced pairing for a set of points ∏ᵢ e(Pᵢ, Qᵢ).
This function doesn't check that the inputs are in the correct subgroups. See AssertIsOnG1 and AssertIsOnG2.
func (Pairing) PairingCheck ¶
PairingCheck calculates the reduced pairing for a set of points and asserts if the result is One ∏ᵢ e(Pᵢ, Qᵢ) =? 1
This function doesn't check that the inputs are in the correct subgroups. See AssertIsOnG1 and AssertIsOnG2.
type Scalar ¶
type Scalar = emulated.Element[ScalarField]
Scalar is the scalar in the groups. It is an alias to the emulated element defined over the scalar field of the groups.
type ScalarField ¶
ScalarField is the emulated.FieldParams implementation of the curve scalar field.