sw_bls12381

package
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 22, 2024 License: Apache-2.0 Imports: 9 Imported by: 11

Documentation

Overview

Package sw_bls12381 implements G1 and G2 arithmetics and pairing computation over BLS12-381 curve.

The implementation follows Housni22: "Pairings in Rank-1 Constraint Systems".

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BaseField added in v0.10.0

type BaseField = emulated.BLS12381Fp

BaseField is the emulated.FieldParams impelementation of the curve base field.

type G1

type G1 struct {
	// contains filtered or unexported fields
}

func NewG1

func NewG1(api frontend.API) (*G1, error)

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

func NewG1Affine(v bls12381.G1Affine) G1Affine

NewG1Affine allocates a witness from the native G1 element and returns it.

type G2

type G2 struct {
	*fields_bls12381.Ext2
	// contains filtered or unexported fields
}

func NewG2

func NewG2(api frontend.API) *G2

func (*G2) AssertIsEqual

func (g2 *G2) AssertIsEqual(p, q *G2Affine)

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 NewG2Affine(v bls12381.G2Affine) G2Affine

func NewG2AffineFixed added in v0.10.0

func NewG2AffineFixed(v bls12381.G2Affine) G2Affine

NewG2AffineFixed returns witness of v with precomputations for efficient pairing computation.

func NewG2AffineFixedPlaceholder added in v0.10.0

func NewG2AffineFixedPlaceholder() G2Affine

NewG2AffineFixedPlaceholder returns a placeholder for the circuit compilation when witness will be given with line precomputations using NewG2AffineFixed.

type GTEl

type GTEl = fields_bls12381.E12

func NewGTEl

func NewGTEl(v bls12381.GT) GTEl

type Pairing

type Pairing struct {
	*fields_bls12381.Ext12
	// contains filtered or unexported fields
}
Example
package main

import (
	"crypto/rand"
	"fmt"

	"github.com/consensys/gnark-crypto/ecc"
	bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381"
	"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_bls12381"
)

type PairCircuit struct {
	InG1 sw_bls12381.G1Affine
	InG2 sw_bls12381.G2Affine
	Res  sw_bls12381.GTEl
}

func (c *PairCircuit) Define(api frontend.API) error {
	pairing, err := sw_bls12381.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_bls12381.G1Affine{&c.InG1}, []*sw_bls12381.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 := bls12381.Pair([]bls12381.G1Affine{p}, []bls12381.G2Affine{q})
	if err != nil {
		panic(err)
	}
	circuit := PairCircuit{}
	witness := PairCircuit{
		InG1: sw_bls12381.NewG1Affine(p),
		InG2: sw_bls12381.NewG2Affine(q),
		Res:  sw_bls12381.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 bls12381.G1Affine, q bls12381.G2Affine, err error) {
	_, _, G1AffGen, G2AffGen := bls12381.Generators()
	mod := bls12381.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 NewPairing

func NewPairing(api frontend.API) (*Pairing, error)

func (Pairing) AssertIsEqual

func (pr Pairing) AssertIsEqual(x, y *GTEl)

func (Pairing) AssertIsOnCurve

func (pr Pairing) AssertIsOnCurve(P *G1Affine)

func (Pairing) AssertIsOnG1

func (pr Pairing) AssertIsOnG1(P *G1Affine)

func (Pairing) AssertIsOnG2

func (pr Pairing) AssertIsOnG2(Q *G2Affine)

func (Pairing) AssertIsOnTwist

func (pr Pairing) AssertIsOnTwist(Q *G2Affine)

func (Pairing) FinalExponentiation

func (pr Pairing) FinalExponentiation(e *GTEl) *GTEl

FinalExponentiation computes the exponentiation (∏ᵢ zᵢ)ᵈ where

d = (p¹²-1)/r = (p¹²-1)/Φ₁₂(p) ⋅ Φ₁₂(p)/r = (p⁶-1)(p²+1)(p⁴ - p² +1)/r

we use instead

d=s ⋅ (p⁶-1)(p²+1)(p⁴ - p² +1)/r

where s is the cofactor 3 (Hayashida et al.).

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

func (pr Pairing) FinalExponentiationUnsafe(e *GTEl) *GTEl

FinalExponentiationUnsafe computes the exponentiation (∏ᵢ zᵢ)ᵈ where

d = (p¹²-1)/r = (p¹²-1)/Φ₁₂(p) ⋅ Φ₁₂(p)/r = (p⁶-1)(p²+1)(p⁴ - p² +1)/r

we use instead

d=s ⋅ (p⁶-1)(p²+1)(p⁴ - p² +1)/r

where s is the cofactor 3 (Hayashida et al.).

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

func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error)

MillerLoop computes the multi-Miller loop ∏ᵢ { fᵢ_{u,Q}(P) }

func (Pairing) Pair

func (pr Pairing) Pair(P []*G1Affine, Q []*G2Affine) (*GTEl, error)

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

func (pr Pairing) PairingCheck(P []*G1Affine, Q []*G2Affine) error

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.

type Scalar added in v0.9.1

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.

func NewScalar added in v0.9.1

func NewScalar(v fr_bls12381.Element) Scalar

NewScalar allocates a witness from the native scalar and returns it.

type ScalarField added in v0.10.0

type ScalarField = emulated.BLS12381Fr

ScalarField is the emulated.FieldParams impelementation of the curve scalar field.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL