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 ¶
- 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) FinalExponentiation(e *GTEl) *GTEl
- func (pr Pairing) FinalExponentiationIsOne(e *GTEl)
- func (pr Pairing) FinalExponentiationUnsafe(e *GTEl) *GTEl
- 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 ¶
This section is empty.
Types ¶
type BaseField ¶
BaseField is the emulated.FieldParams impelementation 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) 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) FinalExponentiationIsOne ¶
FinalExponentiationIsOne performs the final exponentiation on e and checks that the result in 1 in GT.
This method is needed for evmprecompiles/ecpair.
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) 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 impelementation of the curve scalar field.