From 0080bbd85ebd7569b77b2f2ef2d02522e49d47da Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Wed, 21 Aug 2024 17:12:03 -0400 Subject: [PATCH 1/6] perf(bn254/pairing): trade some subs for adds --- std/algebra/emulated/sw_bn254/pairing.go | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/std/algebra/emulated/sw_bn254/pairing.go b/std/algebra/emulated/sw_bn254/pairing.go index 61a7e051e..19f754047 100644 --- a/std/algebra/emulated/sw_bn254/pairing.go +++ b/std/algebra/emulated/sw_bn254/pairing.go @@ -548,8 +548,7 @@ func (pr Pairing) doubleAndAddStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *l // compute x3 =λ1²-x1-x2 x3 := pr.Ext2.Square(l1) - x3 = pr.Ext2.Sub(x3, &p1.X) - x3 = pr.Ext2.Sub(x3, &p2.X) + x3 = pr.Ext2.Sub(x3, pr.Ext2.Add(&p1.X, &p2.X)) // omit y3 computation @@ -559,7 +558,7 @@ func (pr Pairing) doubleAndAddStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *l line1.R1 = *pr.Ext2.Sub(&line1.R1, &p1.Y) // compute λ2 = -λ1-2y1/(x3-x1) - n = pr.Ext2.Double(&p1.Y) + n = pr.Ext2.MulByConstElement(&p1.Y, big.NewInt(2)) d = pr.Ext2.Sub(x3, &p1.X) l2 := pr.Ext2.DivUnchecked(n, d) l2 = pr.Ext2.Add(l2, l1) @@ -567,8 +566,7 @@ func (pr Pairing) doubleAndAddStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *l // compute x4 = λ2²-x1-x3 x4 := pr.Ext2.Square(l2) - x4 = pr.Ext2.Sub(x4, &p1.X) - x4 = pr.Ext2.Sub(x4, x3) + x4 = pr.Ext2.Sub(x4, pr.Ext2.Add(&p1.X, x3)) // compute y4 = λ2(x1 - x4)-y1 y4 := pr.Ext2.Sub(&p1.X, x4) @@ -595,15 +593,13 @@ func (pr Pairing) doubleStep(p1 *g2AffP) (*g2AffP, *lineEvaluation) { // λ = 3x²/2y n := pr.Ext2.Square(&p1.X) - three := big.NewInt(3) - n = pr.Ext2.MulByConstElement(n, three) - d := pr.Ext2.Double(&p1.Y) + n = pr.Ext2.MulByConstElement(n, big.NewInt(3)) + d := pr.Ext2.MulByConstElement(&p1.Y, big.NewInt(2)) λ := pr.Ext2.DivUnchecked(n, d) // xr = λ²-2x xr := pr.Ext2.Square(λ) - xr = pr.Ext2.Sub(xr, &p1.X) - xr = pr.Ext2.Sub(xr, &p1.X) + xr = pr.Ext2.Sub(xr, pr.Ext2.MulByConstElement(&p1.X, big.NewInt(2))) // yr = λ(x-xr)-y yr := pr.Ext2.Sub(&p1.X, xr) @@ -631,9 +627,8 @@ func (pr Pairing) addStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation) { λ := pr.Ext2.DivUnchecked(p2ypy, p2xpx) // xr = λ²-x1-x2 - λλ := pr.Ext2.Square(λ) - p2xpx = pr.Ext2.Add(&p1.X, &p2.X) - xr := pr.Ext2.Sub(λλ, p2xpx) + xr := pr.Ext2.Square(λ) + xr = pr.Ext2.Sub(xr, pr.Ext2.Add(&p1.X, &p2.X)) // yr = λ(x1-xr) - y1 pxrx := pr.Ext2.Sub(&p1.X, xr) From cce528b7c3c6487daf0e32bdfa11372138a0a3c9 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Wed, 21 Aug 2024 17:34:15 -0400 Subject: [PATCH 2/6] perf(bn254/pairing): add doubleAndSub --- std/algebra/emulated/sw_bn254/pairing.go | 62 +++++++++++++++++-- .../emulated/sw_bn254/precomputations.go | 9 +-- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/std/algebra/emulated/sw_bn254/pairing.go b/std/algebra/emulated/sw_bn254/pairing.go index 19f754047..d22c33a52 100644 --- a/std/algebra/emulated/sw_bn254/pairing.go +++ b/std/algebra/emulated/sw_bn254/pairing.go @@ -401,7 +401,7 @@ func (pr Pairing) millerLoopLines(P []*G1Affine, lines []lineEvaluations) (*GTEl // The point (x,0) is of order 2. But this function does not check // subgroup membership. yInv[k] = pr.curveF.Inverse(&P[k].Y) - xNegOverY[k] = pr.curveF.MulMod(&P[k].X, yInv[k]) + xNegOverY[k] = pr.curveF.Mul(&P[k].X, yInv[k]) xNegOverY[k] = pr.curveF.Neg(xNegOverY[k]) } @@ -584,6 +584,56 @@ func (pr Pairing) doubleAndAddStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *l return &p, &line1, &line2 } +// doubleAndSubStep doubles p1 and subs 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) doubleAndSubStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *lineEvaluation) { + + var line1, line2 lineEvaluation + var p g2AffP + + // compute λ1 = (y2-y1)/(x2-x1) + n := pr.Ext2.Add(&p1.Y, &p2.Y) + d := pr.Ext2.Sub(&p1.X, &p2.X) + l1 := pr.Ext2.DivUnchecked(n, d) + + // compute x3 =λ1²-x1-x2 + x3 := pr.Ext2.Square(l1) + x3 = pr.Ext2.Sub(x3, pr.Ext2.Add(&p1.X, &p2.X)) + + // omit y3 computation + + // compute line1 + line1.R0 = *l1 + line1.R1 = *pr.Ext2.Mul(l1, &p1.X) + line1.R1 = *pr.Ext2.Sub(&line1.R1, &p1.Y) + + // compute λ2 = -λ1-2y1/(x3-x1) + n = pr.Ext2.MulByConstElement(&p1.Y, big.NewInt(2)) + d = pr.Ext2.Sub(x3, &p1.X) + l2 := pr.Ext2.DivUnchecked(n, d) + l2 = pr.Ext2.Add(l2, l1) + l2 = pr.Ext2.Neg(l2) + + // compute x4 = λ2²-x1-x3 + x4 := pr.Ext2.Square(l2) + x4 = pr.Ext2.Sub(x4, pr.Ext2.Add(&p1.X, x3)) + + // compute y4 = λ2(x1 - x4)-y1 + y4 := pr.Ext2.Sub(&p1.X, x4) + y4 = pr.Ext2.Mul(l2, y4) + y4 = pr.Ext2.Sub(y4, &p1.Y) + + p.X = *x4 + p.Y = *y4 + + // compute line2 + line2.R0 = *l2 + line2.R1 = *pr.Ext2.Mul(l2, &p1.X) + line2.R1 = *pr.Ext2.Sub(&line2.R1, &p1.Y) + + return &p, &line1, &line2 +} + // 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 *g2AffP) (*g2AffP, *lineEvaluation) { @@ -648,12 +698,12 @@ func (pr Pairing) addStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation) { } -// lineCompute computes the line that goes through p1 and p2 but does not compute p1+p2 +// lineCompute computes the line that goes through p1 and -p2 but does not compute p1+p2 func (pr Pairing) lineCompute(p1, p2 *g2AffP) *lineEvaluation { - // compute λ = (y2-y1)/(x2-x1) - qypy := pr.Ext2.Sub(&p2.Y, &p1.Y) - qxpx := pr.Ext2.Sub(&p2.X, &p1.X) + // compute λ = (y2+y1)/(x2-x1) + qypy := pr.Ext2.Add(&p1.Y, &p2.Y) + qxpx := pr.Ext2.Sub(&p1.X, &p2.X) λ := pr.Ext2.DivUnchecked(qypy, qxpx) var line lineEvaluation @@ -722,7 +772,7 @@ func (pr Pairing) millerLoopAndFinalExpResult(P *G1Affine, Q *G2Affine, previous // precomputations yInv := pr.curveF.Inverse(&P.Y) - xNegOverY := pr.curveF.MulMod(&P.X, yInv) + xNegOverY := pr.curveF.Mul(&P.X, yInv) xNegOverY = pr.curveF.Neg(xNegOverY) // init Miller loop accumulator to residueWitnessInv to share the squarings diff --git a/std/algebra/emulated/sw_bn254/precomputations.go b/std/algebra/emulated/sw_bn254/precomputations.go index fe55542f4..ad0a8ae8f 100644 --- a/std/algebra/emulated/sw_bn254/precomputations.go +++ b/std/algebra/emulated/sw_bn254/precomputations.go @@ -33,13 +33,9 @@ func (p *Pairing) computeLines(Q *g2AffP) lineEvaluations { var cLines lineEvaluations Qacc := Q - QNeg := &g2AffP{ - X: Q.X, - Y: *p.Ext2.Neg(&Q.Y), - } n := len(bn254.LoopCounter) Qacc, cLines[0][n-2] = p.doubleStep(Qacc) - cLines[1][n-3] = p.lineCompute(Qacc, QNeg) + cLines[1][n-3] = p.lineCompute(Qacc, Q) Qacc, cLines[0][n-3] = p.addStep(Qacc, Q) for i := n - 4; i >= 0; i-- { switch loopCounter[i] { @@ -48,7 +44,7 @@ func (p *Pairing) computeLines(Q *g2AffP) lineEvaluations { case 1: Qacc, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(Qacc, Q) case -1: - Qacc, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(Qacc, QNeg) + Qacc, cLines[0][i], cLines[1][i] = p.doubleAndSubStep(Qacc, Q) default: return lineEvaluations{} } @@ -64,7 +60,6 @@ func (p *Pairing) computeLines(Q *g2AffP) lineEvaluations { } Q2Y := p.Ext2.MulByNonResidue2Power3(&Q.Y) - Q2Y = p.Ext2.Neg(Q2Y) Q2 := &g2AffP{ X: *p.Ext2.MulByNonResidue2Power2(&Q.X), Y: *Q2Y, From 3a2ea9486bcde45d7acdb1f99642ad752e482d2e Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Wed, 21 Aug 2024 18:05:52 -0400 Subject: [PATCH 3/6] perf(bw6-761/pairing): add doubleAndSub --- std/algebra/emulated/sw_bw6761/pairing.go | 50 +++++++++++++++++++ .../emulated/sw_bw6761/precomputations.go | 12 +---- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/std/algebra/emulated/sw_bw6761/pairing.go b/std/algebra/emulated/sw_bw6761/pairing.go index 47ad91556..693a2c1e1 100644 --- a/std/algebra/emulated/sw_bw6761/pairing.go +++ b/std/algebra/emulated/sw_bw6761/pairing.go @@ -432,6 +432,56 @@ func (pr Pairing) doubleAndAddStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *l return &p, &line1, &line2 } +// doubleAndSubStep doubles p1 and subs 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) doubleAndSubStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *lineEvaluation) { + + var line1, line2 lineEvaluation + var p g2AffP + + // compute λ1 = (y2-y1)/(x2-x1) + n := pr.curveF.Add(&p1.Y, &p2.Y) + d := pr.curveF.Sub(&p1.X, &p2.X) + l1 := pr.curveF.Div(n, d) + + // compute x3 =λ1²-x1-x2 + x3 := pr.curveF.Mul(l1, l1) + x3 = pr.curveF.Sub(x3, pr.curveF.Add(&p1.X, &p2.X)) + + // omit y3 computation + + // compute line1 + line1.R0 = *l1 + line1.R1 = *pr.curveF.Mul(l1, &p1.X) + line1.R1 = *pr.curveF.Sub(&line1.R1, &p1.Y) + + // compute λ2 = -λ1-2y1/(x3-x1) + n = pr.curveF.MulConst(&p1.Y, big.NewInt(2)) + d = pr.curveF.Sub(x3, &p1.X) + l2 := pr.curveF.Div(n, d) + l2 = pr.curveF.Add(l2, l1) + l2 = pr.curveF.Neg(l2) + + // compute x4 = λ2²-x1-x3 + x4 := pr.curveF.Mul(l2, l2) + x4 = pr.curveF.Sub(x4, pr.curveF.Add(&p1.X, x3)) + + // compute y4 = λ2(x1 - x4)-y1 + y4 := pr.curveF.Sub(&p1.X, x4) + y4 = pr.curveF.Mul(l2, y4) + y4 = pr.curveF.Sub(y4, &p1.Y) + + p.X = *x4 + p.Y = *y4 + + // compute line2 + line2.R0 = *l2 + line2.R1 = *pr.curveF.Mul(l2, &p1.X) + line2.R1 = *pr.curveF.Sub(&line2.R1, &p1.Y) + + return &p, &line1, &line2 +} + // 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 *g2AffP) (*g2AffP, *lineEvaluation) { diff --git a/std/algebra/emulated/sw_bw6761/precomputations.go b/std/algebra/emulated/sw_bw6761/precomputations.go index afb406012..b4442b682 100644 --- a/std/algebra/emulated/sw_bw6761/precomputations.go +++ b/std/algebra/emulated/sw_bw6761/precomputations.go @@ -35,25 +35,17 @@ func (p *Pairing) computeLines(Q *g2AffP) lineEvaluations { X: *p.curveF.Mul(&Q.X, &thirdRootOne), Y: *p.curveF.Neg(&Q.Y), } - negQ := &g2AffP{ - X: Q.X, - Y: imQ.Y, - } accQ := &g2AffP{ X: imQ.X, Y: imQ.Y, } - imQneg := &g2AffP{ - X: imQ.X, - Y: Q.Y, - } for i := len(loopCounter2) - 2; i > 0; i-- { switch loopCounter2[i]*3 + loopCounter1[i] { // cases -4, -2, 2, 4 do not occur, given the static LoopCounters case -3: - accQ, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(accQ, imQneg) + accQ, cLines[0][i], cLines[1][i] = p.doubleAndSubStep(accQ, imQ) case -1: - accQ, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(accQ, negQ) + accQ, cLines[0][i], cLines[1][i] = p.doubleAndSubStep(accQ, Q) case 0: accQ, cLines[0][i] = p.doubleStep(accQ) case 1: From 8dab462cbb24166cf3e4c2ea6ad5efcc72b30846 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Wed, 21 Aug 2024 18:43:12 -0400 Subject: [PATCH 4/6] test: update stats --- internal/stats/latest.stats | Bin 1934 -> 1934 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/internal/stats/latest.stats b/internal/stats/latest.stats index dc2f8a08aae29df1dd358d7af74fce31b316bfcf..faeed83a0e97c67251fe2462929beb555952b613 100644 GIT binary patch delta 114 zcmeC<@8h44Ie8mn{N(A(_LKG4WaOuNG5$4liDG~P4#vO5Z}J%b=B&yCi%h=EoIEje z!Q{1U3mC;GpJfrBe1_@t*) Date: Thu, 22 Aug 2024 11:11:48 -0400 Subject: [PATCH 5/6] refactor: apply review suggestions --- std/algebra/emulated/sw_bls12381/pairing.go | 29 +++--- std/algebra/emulated/sw_bn254/pairing.go | 92 +++++-------------- .../emulated/sw_bn254/precomputations.go | 4 +- std/algebra/emulated/sw_bw6761/pairing.go | 18 ++-- .../emulated/sw_bw6761/precomputations.go | 8 +- 5 files changed, 57 insertions(+), 94 deletions(-) diff --git a/std/algebra/emulated/sw_bls12381/pairing.go b/std/algebra/emulated/sw_bls12381/pairing.go index 4bc99671d..7e698b8df 100644 --- a/std/algebra/emulated/sw_bls12381/pairing.go +++ b/std/algebra/emulated/sw_bls12381/pairing.go @@ -442,7 +442,8 @@ func (pr Pairing) millerLoopLines(P []*G1Affine, lines []lineEvaluations) (*GTEl return res, nil } -// doubleAndAddStep doubles p1 and adds p2 to the result in affine coordinates, and evaluates the line in Miller loop +// doubleAndAddStep doubles p1 and adds p2 to the result in affine coordinates. +// Then evaluates the lines going through p1 and 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) { @@ -452,47 +453,47 @@ func (pr Pairing) doubleAndAddStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *l // compute λ1 = (y2-y1)/(x2-x1) n := pr.Ext2.Sub(&p1.Y, &p2.Y) d := pr.Ext2.Sub(&p1.X, &p2.X) - l1 := pr.Ext2.DivUnchecked(n, d) + λ1 := pr.Ext2.DivUnchecked(n, d) // compute x3 =λ1²-x1-x2 - x3 := pr.Ext2.Square(l1) + x3 := pr.Ext2.Square(λ1) x3 = pr.Ext2.Sub(x3, pr.Ext2.Add(&p1.X, &p2.X)) // omit y3 computation // compute line1 - line1.R0 = *l1 - line1.R1 = *pr.Ext2.Mul(l1, &p1.X) + line1.R0 = *λ1 + line1.R1 = *pr.Ext2.Mul(λ1, &p1.X) line1.R1 = *pr.Ext2.Sub(&line1.R1, &p1.Y) // compute λ2 = -λ1-2y1/(x3-x1) n = pr.Ext2.Double(&p1.Y) d = pr.Ext2.Sub(x3, &p1.X) - l2 := pr.Ext2.DivUnchecked(n, d) - l2 = pr.Ext2.Add(l2, l1) - l2 = pr.Ext2.Neg(l2) + λ2 := pr.Ext2.DivUnchecked(n, d) + λ2 = pr.Ext2.Add(λ2, λ1) + λ2 = pr.Ext2.Neg(λ2) // compute x4 = λ2²-x1-x3 - x4 := pr.Ext2.Square(l2) + x4 := pr.Ext2.Square(λ2) x4 = pr.Ext2.Sub(x4, pr.Ext2.Add(&p1.X, x3)) // compute y4 = λ2(x1 - x4)-y1 y4 := pr.Ext2.Sub(&p1.X, x4) - y4 = pr.Ext2.Mul(l2, y4) + y4 = pr.Ext2.Mul(λ2, y4) y4 = pr.Ext2.Sub(y4, &p1.Y) p.X = *x4 p.Y = *y4 // compute line2 - line2.R0 = *l2 - line2.R1 = *pr.Ext2.Mul(l2, &p1.X) + line2.R0 = *λ2 + line2.R1 = *pr.Ext2.Mul(λ2, &p1.X) line2.R1 = *pr.Ext2.Sub(&line2.R1, &p1.Y) return &p, &line1, &line2 } -// doubleStep doubles a point in affine coordinates, and evaluates the line in Miller loop +// 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) { @@ -575,7 +576,7 @@ func (pr Pairing) tripleStep(p1 *g2AffP) (*g2AffP, *lineEvaluation, *lineEvaluat return &res, &line1, &line2 } -// tangentCompute computes the line that goes through p1 and p2 but does not compute p1+p2 +// tangentCompute computes the tangent line to p1, but does not compute [2]p1. func (pr Pairing) tangentCompute(p1 *g2AffP) *lineEvaluation { // λ = 3x²/2y diff --git a/std/algebra/emulated/sw_bn254/pairing.go b/std/algebra/emulated/sw_bn254/pairing.go index d22c33a52..3b3357bde 100644 --- a/std/algebra/emulated/sw_bn254/pairing.go +++ b/std/algebra/emulated/sw_bn254/pairing.go @@ -534,107 +534,63 @@ func (pr Pairing) millerLoopLines(P []*G1Affine, lines []lineEvaluations) (*GTEl return res, nil } -// doubleAndAddStep doubles p1 and adds p2 to the result in affine coordinates, and evaluates the line in Miller loop +// doubleAndAddStep doubles p1 and adds or subs p2 to the result in affine coordinates, based on the isSub boolean. +// Then evaluates the lines going through p1 and p2 or -p2 (line1) and p1 and p1+p2 or 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, isSub bool) (*g2AffP, *lineEvaluation, *lineEvaluation) { var line1, line2 lineEvaluation var p g2AffP - // compute λ1 = (y2-y1)/(x2-x1) - n := pr.Ext2.Sub(&p1.Y, &p2.Y) - d := pr.Ext2.Sub(&p1.X, &p2.X) - l1 := pr.Ext2.DivUnchecked(n, d) - - // compute x3 =λ1²-x1-x2 - x3 := pr.Ext2.Square(l1) - x3 = pr.Ext2.Sub(x3, pr.Ext2.Add(&p1.X, &p2.X)) - - // omit y3 computation - - // compute line1 - line1.R0 = *l1 - line1.R1 = *pr.Ext2.Mul(l1, &p1.X) - line1.R1 = *pr.Ext2.Sub(&line1.R1, &p1.Y) - - // compute λ2 = -λ1-2y1/(x3-x1) - n = pr.Ext2.MulByConstElement(&p1.Y, big.NewInt(2)) - d = pr.Ext2.Sub(x3, &p1.X) - l2 := pr.Ext2.DivUnchecked(n, d) - l2 = pr.Ext2.Add(l2, l1) - l2 = pr.Ext2.Neg(l2) - - // compute x4 = λ2²-x1-x3 - x4 := pr.Ext2.Square(l2) - x4 = pr.Ext2.Sub(x4, pr.Ext2.Add(&p1.X, x3)) - - // compute y4 = λ2(x1 - x4)-y1 - y4 := pr.Ext2.Sub(&p1.X, x4) - y4 = pr.Ext2.Mul(l2, y4) - y4 = pr.Ext2.Sub(y4, &p1.Y) - - p.X = *x4 - p.Y = *y4 - - // compute line2 - line2.R0 = *l2 - line2.R1 = *pr.Ext2.Mul(l2, &p1.X) - line2.R1 = *pr.Ext2.Sub(&line2.R1, &p1.Y) - - return &p, &line1, &line2 -} - -// doubleAndSubStep doubles p1 and subs 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) doubleAndSubStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *lineEvaluation) { - - var line1, line2 lineEvaluation - var p g2AffP - - // compute λ1 = (y2-y1)/(x2-x1) - n := pr.Ext2.Add(&p1.Y, &p2.Y) + // compute λ1 = (y1-y2)/(x1-x2) or λ1 = (y1+y2)/(x1-x2) if isSub is true + var n *fields_bn254.E2 + if isSub { + n = pr.Ext2.Add(&p1.Y, &p2.Y) + } else { + n = pr.Ext2.Sub(&p1.Y, &p2.Y) + } d := pr.Ext2.Sub(&p1.X, &p2.X) - l1 := pr.Ext2.DivUnchecked(n, d) + λ1 := pr.Ext2.DivUnchecked(n, d) // compute x3 =λ1²-x1-x2 - x3 := pr.Ext2.Square(l1) + x3 := pr.Ext2.Square(λ1) x3 = pr.Ext2.Sub(x3, pr.Ext2.Add(&p1.X, &p2.X)) // omit y3 computation // compute line1 - line1.R0 = *l1 - line1.R1 = *pr.Ext2.Mul(l1, &p1.X) + line1.R0 = *λ1 + line1.R1 = *pr.Ext2.Mul(λ1, &p1.X) line1.R1 = *pr.Ext2.Sub(&line1.R1, &p1.Y) // compute λ2 = -λ1-2y1/(x3-x1) n = pr.Ext2.MulByConstElement(&p1.Y, big.NewInt(2)) d = pr.Ext2.Sub(x3, &p1.X) - l2 := pr.Ext2.DivUnchecked(n, d) - l2 = pr.Ext2.Add(l2, l1) - l2 = pr.Ext2.Neg(l2) + λ2 := pr.Ext2.DivUnchecked(n, d) + λ2 = pr.Ext2.Add(λ2, λ1) + λ2 = pr.Ext2.Neg(λ2) // compute x4 = λ2²-x1-x3 - x4 := pr.Ext2.Square(l2) + x4 := pr.Ext2.Square(λ2) x4 = pr.Ext2.Sub(x4, pr.Ext2.Add(&p1.X, x3)) // compute y4 = λ2(x1 - x4)-y1 y4 := pr.Ext2.Sub(&p1.X, x4) - y4 = pr.Ext2.Mul(l2, y4) + y4 = pr.Ext2.Mul(λ2, y4) y4 = pr.Ext2.Sub(y4, &p1.Y) p.X = *x4 p.Y = *y4 // compute line2 - line2.R0 = *l2 - line2.R1 = *pr.Ext2.Mul(l2, &p1.X) + line2.R0 = *λ2 + line2.R1 = *pr.Ext2.Mul(λ2, &p1.X) line2.R1 = *pr.Ext2.Sub(&line2.R1, &p1.Y) return &p, &line1, &line2 } -// doubleStep doubles a point in affine coordinates, and evaluates the line in Miller loop +// 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) { @@ -667,7 +623,7 @@ func (pr Pairing) doubleStep(p1 *g2AffP) (*g2AffP, *lineEvaluation) { } -// addStep adds two points in affine coordinates, and evaluates the line in Miller loop +// addStep adds p1 and p2 in affine coordinates, and evaluates the line through p1 and p2. // https://eprint.iacr.org/2022/1162 (Section 6.1) func (pr Pairing) addStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation) { @@ -698,7 +654,7 @@ func (pr Pairing) addStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation) { } -// lineCompute computes the line that goes through p1 and -p2 but does not compute p1+p2 +// lineCompute computes the line through p1 and p2, but does not compute p1+p2. func (pr Pairing) lineCompute(p1, p2 *g2AffP) *lineEvaluation { // compute λ = (y2+y1)/(x2-x1) diff --git a/std/algebra/emulated/sw_bn254/precomputations.go b/std/algebra/emulated/sw_bn254/precomputations.go index ad0a8ae8f..84f8ffeab 100644 --- a/std/algebra/emulated/sw_bn254/precomputations.go +++ b/std/algebra/emulated/sw_bn254/precomputations.go @@ -42,9 +42,9 @@ func (p *Pairing) computeLines(Q *g2AffP) lineEvaluations { case 0: Qacc, cLines[0][i] = p.doubleStep(Qacc) case 1: - Qacc, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(Qacc, Q) + Qacc, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(Qacc, Q, false) case -1: - Qacc, cLines[0][i], cLines[1][i] = p.doubleAndSubStep(Qacc, Q) + Qacc, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(Qacc, Q, true) default: return lineEvaluations{} } diff --git a/std/algebra/emulated/sw_bw6761/pairing.go b/std/algebra/emulated/sw_bw6761/pairing.go index 693a2c1e1..6c9704bcc 100644 --- a/std/algebra/emulated/sw_bw6761/pairing.go +++ b/std/algebra/emulated/sw_bw6761/pairing.go @@ -383,15 +383,21 @@ func (pr Pairing) millerLoopLines(P []*G1Affine, lines []lineEvaluations) (*GTEl } -// doubleAndAddStep doubles p1 and adds p2 to the result in affine coordinates, and evaluates the line in Miller loop +// doubleAndAddStep doubles p1 and adds or subs p2 to the result in affine coordinates, based on the isSub boolean. +// Then evaluates the lines going through p1 and p2 or -p2 (line1) and p1 and p1+p2 or 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, isSub bool) (*g2AffP, *lineEvaluation, *lineEvaluation) { var line1, line2 lineEvaluation var p g2AffP - // compute λ1 = (y2-y1)/(x2-x1) - n := pr.curveF.Sub(&p1.Y, &p2.Y) + // compute λ1 = (y1-y2)/(x1-x2) or λ1 = (y1+y2)/(x1-x2) if isSub is true + var n *emulated.Element[BaseField] + if isSub { + n = pr.curveF.Add(&p1.Y, &p2.Y) + } else { + n = pr.curveF.Sub(&p1.Y, &p2.Y) + } d := pr.curveF.Sub(&p1.X, &p2.X) l1 := pr.curveF.Div(n, d) @@ -482,7 +488,7 @@ func (pr Pairing) doubleAndSubStep(p1, p2 *g2AffP) (*g2AffP, *lineEvaluation, *l return &p, &line1, &line2 } -// doubleStep doubles a point in affine coordinates, and evaluates the line in Miller loop +// 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) { @@ -515,7 +521,7 @@ func (pr Pairing) doubleStep(p1 *g2AffP) (*g2AffP, *lineEvaluation) { } -// tangentCompute computes the line that goes through p1 and p2 but does not compute p1+p2 +// tangentCompute computes the tangent line to p1, but does not compute [2]p1. func (pr Pairing) tangentCompute(p1 *g2AffP) *lineEvaluation { // λ = 3x²/2y diff --git a/std/algebra/emulated/sw_bw6761/precomputations.go b/std/algebra/emulated/sw_bw6761/precomputations.go index b4442b682..829dd1b2b 100644 --- a/std/algebra/emulated/sw_bw6761/precomputations.go +++ b/std/algebra/emulated/sw_bw6761/precomputations.go @@ -43,15 +43,15 @@ func (p *Pairing) computeLines(Q *g2AffP) lineEvaluations { switch loopCounter2[i]*3 + loopCounter1[i] { // cases -4, -2, 2, 4 do not occur, given the static LoopCounters case -3: - accQ, cLines[0][i], cLines[1][i] = p.doubleAndSubStep(accQ, imQ) + accQ, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(accQ, imQ, true) case -1: - accQ, cLines[0][i], cLines[1][i] = p.doubleAndSubStep(accQ, Q) + accQ, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(accQ, Q, true) case 0: accQ, cLines[0][i] = p.doubleStep(accQ) case 1: - accQ, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(accQ, Q) + accQ, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(accQ, Q, false) case 3: - accQ, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(accQ, imQ) + accQ, cLines[0][i], cLines[1][i] = p.doubleAndAddStep(accQ, imQ, false) default: panic("unknown case for loopCounter") } From 2e6e0fdb330c074caec6d63f49e3e6d78d078f40 Mon Sep 17 00:00:00 2001 From: Youssef El Housni Date: Thu, 22 Aug 2024 11:14:51 -0400 Subject: [PATCH 6/6] test: update stats --- internal/stats/latest.stats | Bin 1934 -> 1934 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/internal/stats/latest.stats b/internal/stats/latest.stats index c156102ed0baab988339cffd4b14a99ef885e30d..3278097e3f3b196e36710aae67d690c6e32bd924 100644 GIT binary patch delta 114 zcmeC<@8h44IXRzY_v969&n9!Q8S?dhV*JDC@sx)F3?`ptUc@LqxqwA{@*<|5$)0TS zlkYOFovg*WU}EO9$@3WPC+9OKO#DB8@+npsh3P(we+^w?AUYWsI2ivHzsY0#o3knp JYM2hQGXMZ*C9nVh delta 108 zcmeC<@8h44IoXYbNA%gEDI*{ zv&+b@kz)L7nC`{^1ssfjOI&mq|K|Kv0*g#$XENdI*JAv`=<&=2qGob0bK+zb#%BQg CT_KzR