Skip to content

Commit

Permalink
refactor: algebra interface and pairing
Browse files Browse the repository at this point in the history
  • Loading branch information
yelhousni committed Nov 11, 2023
1 parent 5461270 commit 44d4faf
Show file tree
Hide file tree
Showing 19 changed files with 163 additions and 162 deletions.
14 changes: 7 additions & 7 deletions std/algebra/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,31 +53,31 @@ func GetCurve[S ScalarT, G1El G1ElementT](api frontend.API) (Curve[S, G1El], err
// GetPairing returns the [Pairing] implementation corresponding to the groups
// type parameters. The method allows to have a fully generic implementation
// without taking into consideration the initialization differences.
func GetPairing[G1El G1ElementT, G2El G2ElementT, GtEl GtElementT](api frontend.API) (Pairing[G1El, G2El, GtEl], error) {
var ret Pairing[G1El, G2El, GtEl]
func GetPairing[G1El G1ElementT, G2El G2ElementT, GtEl GtElementT, L LinesT](api frontend.API) (Pairing[G1El, G2El, GtEl, LinesT], error) {
var ret Pairing[G1El, G2El, GtEl, LinesT]
switch s := any(&ret).(type) {
case *Pairing[sw_bn254.G1Affine, sw_bn254.G2Affine, sw_bn254.GTEl]:
case *Pairing[sw_bn254.G1Affine, sw_bn254.G2Affine, sw_bn254.GTEl, sw_bn254.LineEvaluation]:
p, err := sw_bn254.NewPairing(api)
if err != nil {
return ret, fmt.Errorf("new pairing: %w", err)
}
*s = p
case *Pairing[sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl]:
case *Pairing[sw_bw6761.G1Affine, sw_bw6761.G2Affine, sw_bw6761.GTEl, sw_bw6761.LineEvaluation]:
p, err := sw_bw6761.NewPairing(api)
if err != nil {
return ret, fmt.Errorf("new pairing: %w", err)
}
*s = p
case *Pairing[sw_bls12381.G1Affine, sw_bls12381.G2Affine, sw_bls12381.GTEl]:
case *Pairing[sw_bls12381.G1Affine, sw_bls12381.G2Affine, sw_bls12381.GTEl, sw_bls12381.LineEvaluation]:
p, err := sw_bls12381.NewPairing(api)
if err != nil {
return ret, fmt.Errorf("new pairing: %w", err)
}
*s = p
case *Pairing[sw_bls12377.G1Affine, sw_bls12377.G2Affine, sw_bls12377.GT]:
case *Pairing[sw_bls12377.G1Affine, sw_bls12377.G2Affine, sw_bls12377.GT, sw_bls12377.LineEvaluation]:
p := sw_bls12377.NewPairing(api)
*s = p
case *Pairing[sw_bls24315.G1Affine, sw_bls24315.G2Affine, sw_bls24315.GT]:
case *Pairing[sw_bls24315.G1Affine, sw_bls24315.G2Affine, sw_bls24315.GT, sw_bls24315.LineEvaluation]:
p := sw_bls24315.NewPairing(api)
*s = p
default:
Expand Down
46 changes: 23 additions & 23 deletions std/algebra/emulated/sw_bls12381/pairing.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,11 @@ func (pr Pairing) finalExponentiation(e *GTEl, unsafe bool) *GTEl {
return &result
}

// lineEvaluation represents a sparse Fp12 Elmt (result of the line evaluation)
// LineEvaluation represents a sparse Fp12 Elmt (result of the line evaluation)
// line: 1 - R0(x/y) - R1(1/y) = 0 instead of R0'*y - R1'*x - R2' = 0 This
// makes the multiplication by lines (MulBy014) and between lines (Mul014By014)
// circuit-efficient.
type lineEvaluation struct {
type LineEvaluation struct {
R0, R1 fields_bls12381.E2
}

Expand Down Expand Up @@ -325,7 +325,7 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {

res := pr.Ext12.One()

var l1, l2 *lineEvaluation
var l1, l2 *LineEvaluation
Qacc := make([]*G2Affine, n)
yInv := make([]*emulated.Element[emulated.BLS12381Fp], n)
xNegOverY := make([]*emulated.Element[emulated.BLS12381Fp], n)
Expand Down Expand Up @@ -359,7 +359,7 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
res.C0.B0 = *pr.MulByElement(&l1.R1, yInv[0])
res.C1.B1 = *pr.Ext2.One()
// line evaluation at P[0]
l2 = &lineEvaluation{
l2 = &LineEvaluation{
R0: *pr.MulByElement(&l2.R0, xNegOverY[0]),
R1: *pr.MulByElement(&l2.R1, yInv[0]),
}
Expand All @@ -384,12 +384,12 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
// l2 the line ℓ passing 2Q[k] and Q[k]
Qacc[k], l1, l2 = pr.tripleStep(Qacc[k])
// line evaluation at P[k]
l1 = &lineEvaluation{
l1 = &LineEvaluation{
R0: *pr.MulByElement(&l1.R0, xNegOverY[k]),
R1: *pr.MulByElement(&l1.R1, yInv[k]),
}
// line evaluation at P[k]
l2 = &lineEvaluation{
l2 = &LineEvaluation{
R0: *pr.MulByElement(&l2.R0, xNegOverY[k]),
R1: *pr.MulByElement(&l2.R1, yInv[k]),
}
Expand All @@ -411,7 +411,7 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
// Qacc[k] ← 2Qacc[k] and l1 the tangent ℓ passing 2Qacc[k]
Qacc[k], l1 = pr.doubleStep(Qacc[k])
// line evaluation at P[k]
l1 = &lineEvaluation{
l1 = &LineEvaluation{
R0: *pr.MulByElement(&l1.R0, xNegOverY[k]),
R1: *pr.MulByElement(&l1.R1, yInv[k]),
}
Expand All @@ -425,12 +425,12 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
// l2 the line ℓ passing (Qacc[k]+Q[k]) and Qacc[k]
Qacc[k], l1, l2 = pr.doubleAndAddStep(Qacc[k], Q[k])
// line evaluation at P[k]
l1 = &lineEvaluation{
l1 = &LineEvaluation{
R0: *pr.MulByElement(&l1.R0, xNegOverY[k]),
R1: *pr.MulByElement(&l1.R1, yInv[k]),
}
// line evaluation at P[k]
l2 = &lineEvaluation{
l2 = &LineEvaluation{
R0: *pr.MulByElement(&l2.R0, xNegOverY[k]),
R1: *pr.MulByElement(&l2.R1, yInv[k]),
}
Expand All @@ -448,7 +448,7 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
// l1 the tangent ℓ passing 2Qacc[k]
l1 = pr.tangentCompute(Qacc[k])
// line evaluation at P[k]
l1 = &lineEvaluation{
l1 = &LineEvaluation{
R0: *pr.MulByElement(&l1.R0, xNegOverY[k]),
R1: *pr.MulByElement(&l1.R1, yInv[k]),
}
Expand All @@ -464,9 +464,9 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {

// doubleAndAddStep doubles p1 and adds p2 to the result in affine coordinates, and evaluates the line in Miller loop
// https://eprint.iacr.org/2022/1162 (Section 6.1)
func (pr Pairing) doubleAndAddStep(p1, p2 *G2Affine) (*G2Affine, *lineEvaluation, *lineEvaluation) {
func (pr Pairing) doubleAndAddStep(p1, p2 *G2Affine) (*G2Affine, *LineEvaluation, *LineEvaluation) {

var line1, line2 lineEvaluation
var line1, line2 LineEvaluation
var p G2Affine

// compute λ1 = (y2-y1)/(x2-x1)
Expand Down Expand Up @@ -516,10 +516,10 @@ func (pr Pairing) doubleAndAddStep(p1, p2 *G2Affine) (*G2Affine, *lineEvaluation

// doubleStep doubles a point in affine coordinates, and evaluates the line in Miller loop
// https://eprint.iacr.org/2022/1162 (Section 6.1)
func (pr Pairing) doubleStep(p1 *G2Affine) (*G2Affine, *lineEvaluation) {
func (pr Pairing) doubleStep(p1 *G2Affine) (*G2Affine, *LineEvaluation) {

var p G2Affine
var line lineEvaluation
var line LineEvaluation

// λ = 3x²/2y
n := pr.Ext2.Square(&p1.X)
Expand Down Expand Up @@ -551,7 +551,7 @@ func (pr Pairing) doubleStep(p1 *G2Affine) (*G2Affine, *lineEvaluation) {

// addStep adds two points in affine coordinates, and evaluates the line in Miller loop
// https://eprint.iacr.org/2022/1162 (Section 6.1)
func (pr Pairing) addStep(p1, p2 *G2Affine) (*G2Affine, *lineEvaluation) {
func (pr Pairing) addStep(p1, p2 *G2Affine) (*G2Affine, *LineEvaluation) {

// compute λ = (y2-y1)/(x2-x1)
p2ypy := pr.Ext2.Sub(&p2.Y, &p1.Y)
Expand All @@ -572,7 +572,7 @@ func (pr Pairing) addStep(p1, p2 *G2Affine) (*G2Affine, *lineEvaluation) {
res.X = *xr
res.Y = *yr

var line lineEvaluation
var line LineEvaluation
line.R0 = *λ
line.R1 = *pr.Ext2.Mul(λ, &p1.X)
line.R1 = *pr.Ext2.Sub(&line.R1, &p1.Y)
Expand All @@ -582,9 +582,9 @@ func (pr Pairing) addStep(p1, p2 *G2Affine) (*G2Affine, *lineEvaluation) {
}

// tripleStep triples p1 in affine coordinates, and evaluates the line in Miller loop
func (pr Pairing) tripleStep(p1 *G2Affine) (*G2Affine, *lineEvaluation, *lineEvaluation) {
func (pr Pairing) tripleStep(p1 *G2Affine) (*G2Affine, *LineEvaluation, *LineEvaluation) {

var line1, line2 lineEvaluation
var line1, line2 LineEvaluation
var res G2Affine

// λ1 = 3x²/2y
Expand Down Expand Up @@ -632,7 +632,7 @@ func (pr Pairing) tripleStep(p1 *G2Affine) (*G2Affine, *lineEvaluation, *lineEva
}

// tangentCompute computes the line that goes through p1 and p2 but does not compute p1+p2
func (pr Pairing) tangentCompute(p1 *G2Affine) *lineEvaluation {
func (pr Pairing) tangentCompute(p1 *G2Affine) *LineEvaluation {

// λ = 3x²/2y
n := pr.Ext2.Square(&p1.X)
Expand All @@ -641,7 +641,7 @@ func (pr Pairing) tangentCompute(p1 *G2Affine) *lineEvaluation {
d := pr.Ext2.Double(&p1.Y)
λ := pr.Ext2.DivUnchecked(n, d)

var line lineEvaluation
var line LineEvaluation
line.R0 = *λ
line.R1 = *pr.Ext2.Mul(λ, &p1.X)
line.R1 = *pr.Ext2.Sub(&line.R1, &p1.Y)
Expand All @@ -656,7 +656,7 @@ func (pr Pairing) tangentCompute(p1 *G2Affine) *lineEvaluation {

// MillerLoopFixedQ computes the multi-Miller loop as in MillerLoop
// but Qᵢ are fixed points in G2 known in advance.
func (pr Pairing) MillerLoopFixedQ(P []*G1Affine, lines [][2][63]lineEvaluation) (*GTEl, error) {
func (pr Pairing) MillerLoopFixedQ(P []*G1Affine, lines [][2][63]LineEvaluation) (*GTEl, error) {

// check input size match
n := len(P)
Expand Down Expand Up @@ -752,7 +752,7 @@ func (pr Pairing) MillerLoopFixedQ(P []*G1Affine, lines [][2][63]lineEvaluation)
// ∏ᵢ e(Pᵢ, Qᵢ) where Qᵢ are fixed points known in advance.
//
// This function doesn't check that the inputs are in the correct subgroup. See IsInSubGroup.
func (pr Pairing) PairFixedQ(P []*G1Affine, lines [][2][63]lineEvaluation) (*GTEl, error) {
func (pr Pairing) PairFixedQ(P []*G1Affine, lines [][2][63]LineEvaluation) (*GTEl, error) {
f, err := pr.MillerLoopFixedQ(P, lines)
if err != nil {
return nil, err
Expand All @@ -764,7 +764,7 @@ func (pr Pairing) PairFixedQ(P []*G1Affine, lines [][2][63]lineEvaluation) (*GTE
// ∏ᵢ e(Pᵢ, Qᵢ) =? 1 where Qᵢ are fixed points known in advance.
//
// This function doesn't check that the inputs are in the correct subgroups.
func (pr Pairing) PairingFixedQCheck(P []*G1Affine, lines [][2][63]lineEvaluation) error {
func (pr Pairing) PairingFixedQCheck(P []*G1Affine, lines [][2][63]LineEvaluation) error {
f, err := pr.PairFixedQ(P, lines)
if err != nil {
return err
Expand Down
10 changes: 5 additions & 5 deletions std/algebra/emulated/sw_bls12381/pairing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ func TestGroupMembershipSolve(t *testing.T) {

type PairFixedCircuit struct {
InG1 G1Affine
Lines [2][63]lineEvaluation
Lines [2][63]LineEvaluation
Res GTEl
}

Expand All @@ -252,7 +252,7 @@ func (c *PairFixedCircuit) Define(api frontend.API) error {
if err != nil {
return fmt.Errorf("new pairing: %w", err)
}
res, err := pairing.PairFixedQ([]*G1Affine{&c.InG1}, [][2][63]lineEvaluation{c.Lines})
res, err := pairing.PairFixedQ([]*G1Affine{&c.InG1}, [][2][63]LineEvaluation{c.Lines})
if err != nil {
return fmt.Errorf("pair: %w", err)
}
Expand All @@ -278,8 +278,8 @@ func TestPairFixedTestSolve(t *testing.T) {
type DoublePairFixedCircuit struct {
In1G1 G1Affine
In2G1 G1Affine
Lines1 [2][63]lineEvaluation
Lines2 [2][63]lineEvaluation
Lines1 [2][63]LineEvaluation
Lines2 [2][63]LineEvaluation
Res GTEl
}

Expand All @@ -288,7 +288,7 @@ func (c *DoublePairFixedCircuit) Define(api frontend.API) error {
if err != nil {
return fmt.Errorf("new pairing: %w", err)
}
res, err := pairing.PairFixedQ([]*G1Affine{&c.In1G1, &c.In2G1}, [][2][63]lineEvaluation{c.Lines1, c.Lines2})
res, err := pairing.PairFixedQ([]*G1Affine{&c.In1G1, &c.In2G1}, [][2][63]LineEvaluation{c.Lines1, c.Lines2})
if err != nil {
return fmt.Errorf("pair: %w", err)
}
Expand Down
8 changes: 4 additions & 4 deletions std/algebra/emulated/sw_bls12381/precomputations.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ import (
// Q.Y.A0 = 0xce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801
// Q.Y.A1 = 0x606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be

var precomputedLines [2][63]lineEvaluation
var precomputedLines [2][63]LineEvaluation
var precomputedLinesOnce sync.Once

func getPrecomputedLines() [2][63]lineEvaluation {
func getPrecomputedLines() [2][63]LineEvaluation {
precomputedLinesOnce.Do(func() {
precomputedLines = computePrecomputedLines()
})
return precomputedLines
}

func computePrecomputedLines() [2][63]lineEvaluation {
var PrecomputedLines [2][63]lineEvaluation
func computePrecomputedLines() [2][63]LineEvaluation {
var PrecomputedLines [2][63]LineEvaluation
_, _, _, G2AffGen := bls12381.Generators()
lines := bls12381.PrecomputeLines(G2AffGen)
for j := 0; j < 63; j++ {
Expand Down
Loading

0 comments on commit 44d4faf

Please sign in to comment.