Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 24 additions & 24 deletions std/algebra/emulated/sw_bls12381/pairing.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func NewPairing(api frontend.API) (*Pairing, error) {
//
// This function checks that the Qᵢ are in the correct subgroup, but does not
// check Pᵢ. See AssertIsOnG1.
func (pr Pairing) Pair(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
func (pr *Pairing) Pair(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
res, err := pr.MillerLoop(P, Q)
if err != nil {
return nil, fmt.Errorf("miller loop: %w", err)
Expand All @@ -99,7 +99,7 @@ func (pr Pairing) Pair(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
// ∏ᵢ e(Pᵢ, Qᵢ) =? 1
//
// This function doesn't check that the inputs are in the correct subgroups.
func (pr Pairing) PairingCheck(P []*G1Affine, Q []*G2Affine) error {
func (pr *Pairing) PairingCheck(P []*G1Affine, Q []*G2Affine) error {
// check input size match
nP := len(P)
nQ := len(Q)
Expand Down Expand Up @@ -181,15 +181,15 @@ func (pr Pairing) PairingCheck(P []*G1Affine, Q []*G2Affine) error {
return nil
}

func (pr Pairing) IsEqual(x, y *GTEl) frontend.Variable {
func (pr *Pairing) IsEqual(x, y *GTEl) frontend.Variable {
return pr.Ext12.IsEqual(x, y)
}

func (pr Pairing) AssertIsEqual(x, y *GTEl) {
func (pr *Pairing) AssertIsEqual(x, y *GTEl) {
pr.Ext12.AssertIsEqual(x, y)
}

func (pr Pairing) MuxG2(sel frontend.Variable, inputs ...*G2Affine) *G2Affine {
func (pr *Pairing) MuxG2(sel frontend.Variable, inputs ...*G2Affine) *G2Affine {
if len(inputs) == 0 {
return nil
}
Expand Down Expand Up @@ -253,7 +253,7 @@ func (pr Pairing) MuxG2(sel frontend.Variable, inputs ...*G2Affine) *G2Affine {
return &ret
}

func (pr Pairing) MuxGt(sel frontend.Variable, inputs ...*GTEl) *GTEl {
func (pr *Pairing) MuxGt(sel frontend.Variable, inputs ...*GTEl) *GTEl {
if len(inputs) == 0 {
return nil
}
Expand Down Expand Up @@ -304,19 +304,19 @@ func (pr Pairing) MuxGt(sel frontend.Variable, inputs ...*GTEl) *GTEl {
}

// IsOnCurve returns a boolean indicating if the G1 point is in the curve.
func (pr Pairing) IsOnCurve(P *G1Affine) frontend.Variable {
func (pr *Pairing) IsOnCurve(P *G1Affine) frontend.Variable {
left, right := pr.g1.computeCurveEquation(P)
diff := pr.curveF.Sub(left, right)
return pr.curveF.IsZero(diff)
}

func (pr Pairing) AssertIsOnG1(P *G1Affine) {
func (pr *Pairing) AssertIsOnG1(P *G1Affine) {
pr.g1.AssertIsOnG1(P)
}

// IsOnG1 returns a boolean indicating if the G1 point is on the curve and in
// the prime subgroup.
func (pr Pairing) IsOnG1(P *G1Affine) frontend.Variable {
func (pr *Pairing) IsOnG1(P *G1Affine) frontend.Variable {
// To check that a point P is on G1, we need to check it is of prime order r.
// This means that we need to check:
// [r]P == 0
Expand All @@ -338,24 +338,24 @@ func (pr Pairing) IsOnG1(P *G1Affine) frontend.Variable {
return pr.api.And(isOnCurve, isInSubgroup)
}

func (pr Pairing) AssertIsOnTwist(Q *G2Affine) {
func (pr *Pairing) AssertIsOnTwist(Q *G2Affine) {
pr.g2.AssertIsOnTwist(Q)
}

// IsOnTwist returns a boolean indicating if the G2 point is in the twist.
func (pr Pairing) IsOnTwist(Q *G2Affine) frontend.Variable {
func (pr *Pairing) IsOnTwist(Q *G2Affine) frontend.Variable {
left, right := pr.g2.computeTwistEquation(Q)
diff := pr.Ext2.Sub(left, right)
return pr.Ext2.IsZero(diff)
}

func (pr Pairing) AssertIsOnG2(Q *G2Affine) {
func (pr *Pairing) AssertIsOnG2(Q *G2Affine) {
pr.g2.AssertIsOnG2(Q)
}

// IsOnG2 returns a boolean indicating if the G2 point is on the curve and in
// the prime subgroup.
func (pr Pairing) IsOnG2(Q *G2Affine) frontend.Variable {
func (pr *Pairing) IsOnG2(Q *G2Affine) frontend.Variable {
// 1 - is Q on curve
isOnCurve := pr.IsOnTwist(Q)
// 2 - is Q in the subgroup
Expand Down Expand Up @@ -383,7 +383,7 @@ var loopCounter = [64]int8{
//
// This function checks that the Qᵢ are in the correct subgroup, but does not
// check Pᵢ. See AssertIsOnG1.
func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
func (pr *Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {

// check input size match
n := len(P)
Expand All @@ -403,7 +403,7 @@ func (pr Pairing) MillerLoop(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
}

// millerLoopLines computes the multi-Miller loop from points in G1 and precomputed lines in G2
func (pr Pairing) millerLoopLines(P []*G1Affine, lines []lineEvaluations, init *GTEl, first bool) (*GTEl, error) {
func (pr *Pairing) millerLoopLines(P []*G1Affine, lines []lineEvaluations, init *GTEl, first bool) (*GTEl, error) {

// check input size match
n := len(P)
Expand Down Expand Up @@ -489,7 +489,7 @@ func (pr Pairing) millerLoopLines(P []*G1Affine, lines []lineEvaluations, init *
// 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.)
func (pr Pairing) FinalExponentiation(e *GTEl) *GTEl {
func (pr *Pairing) FinalExponentiation(e *GTEl) *GTEl {
z := pr.Copy(e)

// Easy part
Expand Down Expand Up @@ -531,7 +531,7 @@ func (pr Pairing) FinalExponentiation(e *GTEl) *GTEl {
// L. Eagen, and is based on a personal communication with A. Novakovic.
//
// [On Proving Pairings]: https://eprint.iacr.org/2024/640.pdf
func (pr Pairing) AssertFinalExponentiationIsOne(x *GTEl) {
func (pr *Pairing) AssertFinalExponentiationIsOne(x *GTEl) {
tower := pr.ToTower(x)

res, err := pr.curveF.NewHint(finalExpHint, 18, tower[0], tower[1], tower[2], tower[3], tower[4], tower[5], tower[6], tower[7], tower[8], tower[9], tower[10], tower[11])
Expand Down Expand Up @@ -587,7 +587,7 @@ func (pr Pairing) AssertFinalExponentiationIsOne(x *GTEl) {
// doubleAndAddStep doubles p1 and adds p2 to the result in affine coordinates.
// Then evaluates the lines going through p1 and p2 or -p2 (line1) and p1 and p1+p2 (line2).
// https://eprint.iacr.org/2022/1162 (Section 6.1)
func (pr Pairing) doubleAndAddStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *lineEvaluation) {
func (pr *Pairing) doubleAndAddStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *lineEvaluation) {

var line1, line2 lineEvaluation
var p g2AffP
Expand Down Expand Up @@ -641,7 +641,7 @@ func (pr Pairing) doubleAndAddStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *l

// doubleStep doubles p1 in affine coordinates, and evaluates the tangent line to p1.
// https://eprint.iacr.org/2022/1162 (Section 6.1)
func (pr Pairing) doubleStep(p1 *g2AffP) (*g2AffP, *lineEvaluation) {
func (pr *Pairing) doubleStep(p1 *g2AffP) (*g2AffP, *lineEvaluation) {

var p g2AffP
var line lineEvaluation
Expand Down Expand Up @@ -676,7 +676,7 @@ func (pr Pairing) doubleStep(p1 *g2AffP) (*g2AffP, *lineEvaluation) {
}

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

var line1, line2 lineEvaluation
var res g2AffP
Expand Down Expand Up @@ -731,7 +731,7 @@ func (pr Pairing) tripleStep(p1 *g2AffP) (*g2AffP, *lineEvaluation, *lineEvaluat
// and multiplies it in 𝔽p¹² by previous.
//
// This method is needed for evmprecompiles/ecpair.
func (pr Pairing) MillerLoopAndMul(P *G1Affine, Q *G2Affine, previous *GTEl) (*GTEl, error) {
func (pr *Pairing) MillerLoopAndMul(P *G1Affine, Q *G2Affine, previous *GTEl) (*GTEl, error) {
res, err := pr.MillerLoop([]*G1Affine{P}, []*G2Affine{Q})
if err != nil {
return nil, fmt.Errorf("miller loop: %w", err)
Expand All @@ -750,14 +750,14 @@ func (pr Pairing) MillerLoopAndMul(P *G1Affine, Q *G2Affine, previous *GTEl) (*G
// This method is needed for evmprecompiles/ecpair.
//
// [On Proving Pairings]: https://eprint.iacr.org/2024/640.pdf
func (pr Pairing) AssertMillerLoopAndFinalExpIsOne(P *G1Affine, Q *G2Affine, previous *GTEl) {
func (pr *Pairing) AssertMillerLoopAndFinalExpIsOne(P *G1Affine, Q *G2Affine, previous *GTEl) {
t2 := pr.millerLoopAndFinalExpResult(P, Q, previous)
pr.AssertIsEqual(t2, pr.Ext12.One())
}

// millerLoopAndFinalExpResult computes the Miller loop between P and Q,
// multiplies it in 𝔽p¹² by previous and returns the result.
func (pr Pairing) millerLoopAndFinalExpResult(P *G1Affine, Q *G2Affine, previous *GTEl) *GTEl {
func (pr *Pairing) millerLoopAndFinalExpResult(P *G1Affine, Q *G2Affine, previous *GTEl) *GTEl {
tower := pr.ToTower(previous)

// hint the non-residue witness
Expand Down Expand Up @@ -840,7 +840,7 @@ func (pr Pairing) millerLoopAndFinalExpResult(P *G1Affine, Q *G2Affine, previous
// This method is needed for evmprecompiles/ecpair.
//
// [On Proving Pairings]: https://eprint.iacr.org/2024/640.pdf
func (pr Pairing) IsMillerLoopAndFinalExpOne(P *G1Affine, Q *G2Affine, previous *GTEl) frontend.Variable {
func (pr *Pairing) IsMillerLoopAndFinalExpOne(P *G1Affine, Q *G2Affine, previous *GTEl) frontend.Variable {
t2 := pr.millerLoopAndFinalExpResult(P, Q, previous)

res := pr.IsEqual(t2, pr.Ext12.One())
Expand Down
Loading
Loading