From ffaaea73e1b67358e625343c0d32fc785792b3f6 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Tue, 30 Jul 2024 15:12:09 -0400 Subject: [PATCH] refactor(bls12-381, bls12-377): MillerLoopFixed corresponds to gnark --- ecc/bls12-377/pairing.go | 51 ++++++++++++++++++++++++++++++++--- ecc/bls12-381/pairing.go | 57 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 100 insertions(+), 8 deletions(-) diff --git a/ecc/bls12-377/pairing.go b/ecc/bls12-377/pairing.go index dcb142823..1b95a173f 100644 --- a/ecc/bls12-377/pairing.go +++ b/ecc/bls12-377/pairing.go @@ -384,11 +384,10 @@ func PrecomputeLines(Q G2Affine) (PrecomputedLines [2][len(LoopCounter) - 1]Line accQ.Set(&Q) for i := len(LoopCounter) - 2; i >= 0; i-- { - accQ.doubleStep(&PrecomputedLines[0][i]) if LoopCounter[i] == 0 { - continue + accQ.doubleStep(&PrecomputedLines[0][i]) } else { - accQ.addStep(&PrecomputedLines[1][i], &Q) + accQ.doubleAndAddStep(&PrecomputedLines[0][i], &PrecomputedLines[1][i], &Q) } } return PrecomputedLines @@ -573,3 +572,49 @@ func (p *G2Affine) addStep(evaluations *LineEvaluationAff, a *G2Affine) { p.X.Set(&xr) p.Y.Set(&yr) } + +func (p *G2Affine) doubleAndAddStep(evaluations1, evaluations2 *LineEvaluationAff, a *G2Affine) { + var n, d, l1, x3, l2, x4, y4 fptower.E2 + + // compute λ1 = (y2-y1)/(x2-x1) + n.Sub(&p.Y, &a.Y) + d.Sub(&p.X, &a.X) + l1.Div(&n, &d) + + // compute x3 =λ1²-x1-x2 + x3.Square(&l1) + x3.Sub(&x3, &p.X) + x3.Sub(&x3, &a.X) + + // omit y3 computation + + // compute line1 + evaluations1.R0.Set(&l1) + evaluations1.R1.Mul(&l1, &p.X) + evaluations1.R1.Sub(&evaluations1.R1, &p.Y) + + // compute λ2 = -λ1-2y1/(x3-x1) + n.Double(&p.Y) + d.Sub(&x3, &p.X) + l2.Div(&n, &d) + l2.Add(&l2, &l1) + l2.Neg(&l2) + + // compute x4 = λ2²-x1-x3 + x4.Square(&l2) + x4.Sub(&x4, &p.X) + x4.Sub(&x4, &x3) + + // compute y4 = λ2(x1 - x4)-y1 + y4.Sub(&p.X, &x4) + y4.Mul(&l2, &y4) + y4.Sub(&y4, &p.Y) + + // compute line2 + evaluations2.R0.Set(&l2) + evaluations2.R1.Mul(&l2, &p.X) + evaluations2.R1.Sub(&evaluations2.R1, &p.Y) + + p.X.Set(&x4) + p.Y.Set(&y4) +} diff --git a/ecc/bls12-381/pairing.go b/ecc/bls12-381/pairing.go index b7c1bf66b..be2e8bc74 100644 --- a/ecc/bls12-381/pairing.go +++ b/ecc/bls12-381/pairing.go @@ -386,14 +386,15 @@ func PairingCheckFixedQ(P []G1Affine, lines [][2][len(LoopCounter) - 1]LineEvalu func PrecomputeLines(Q G2Affine) (PrecomputedLines [2][len(LoopCounter) - 1]LineEvaluationAff) { var accQ G2Affine accQ.Set(&Q) - n := len(LoopCounter) - for i := n - 2; i >= 0; i-- { - accQ.doubleStep(&PrecomputedLines[0][i]) + // i = n - 2 + accQ.doubleStep(&PrecomputedLines[0][n-2]) + accQ.addStep(&PrecomputedLines[1][n-2], &Q) + for i := n - 3; i >= 0; i-- { if LoopCounter[i] == 0 { - continue + accQ.doubleStep(&PrecomputedLines[0][i]) } else { - accQ.addStep(&PrecomputedLines[1][i], &Q) + accQ.doubleAndAddStep(&PrecomputedLines[0][i], &PrecomputedLines[1][i], &Q) } } return PrecomputedLines @@ -541,3 +542,49 @@ func (p *G2Affine) addStep(evaluations *LineEvaluationAff, a *G2Affine) { p.X.Set(&xr) p.Y.Set(&yr) } + +func (p *G2Affine) doubleAndAddStep(evaluations1, evaluations2 *LineEvaluationAff, a *G2Affine) { + var n, d, l1, x3, l2, x4, y4 fptower.E2 + + // compute λ1 = (y2-y1)/(x2-x1) + n.Sub(&p.Y, &a.Y) + d.Sub(&p.X, &a.X) + l1.Div(&n, &d) + + // compute x3 =λ1²-x1-x2 + x3.Square(&l1) + x3.Sub(&x3, &p.X) + x3.Sub(&x3, &a.X) + + // omit y3 computation + + // compute line1 + evaluations1.R0.Set(&l1) + evaluations1.R1.Mul(&l1, &p.X) + evaluations1.R1.Sub(&evaluations1.R1, &p.Y) + + // compute λ2 = -λ1-2y1/(x3-x1) + n.Double(&p.Y) + d.Sub(&x3, &p.X) + l2.Div(&n, &d) + l2.Add(&l2, &l1) + l2.Neg(&l2) + + // compute x4 = λ2²-x1-x3 + x4.Square(&l2) + x4.Sub(&x4, &p.X) + x4.Sub(&x4, &x3) + + // compute y4 = λ2(x1 - x4)-y1 + y4.Sub(&p.X, &x4) + y4.Mul(&l2, &y4) + y4.Sub(&y4, &p.Y) + + // compute line2 + evaluations2.R0.Set(&l2) + evaluations2.R1.Mul(&l2, &p.X) + evaluations2.R1.Sub(&evaluations2.R1, &p.Y) + + p.X.Set(&x4) + p.Y.Set(&y4) +}