Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: using non-native Eval for curve arithmetic #1331

Merged
merged 16 commits into from
Dec 4, 2024
Merged

Conversation

yelhousni
Copy link
Contributor

@yelhousni yelhousni commented Nov 27, 2024

Description

Similar to #1312 but for sw_emulated and sw_bw6761 curve arithmetic.

Type of change

  • New feature (non-breaking change which adds functionality)

How has this been tested?

Current tests pass.

How has this been benchmarked?

  • Emulated PLONK recursion (BW6-761 in BN254):
old new diff
21546468 19241163 2305305
  • ECRECOVER precompile:
old new diff
428288 366181 62107
  • ECMUL precompile:
old new diff
261293 221844 39449

Checklist:

  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • I did not modify files generated from templates
  • golangci-lint does not output errors locally
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

@ivokub
Copy link
Collaborator

ivokub commented Dec 4, 2024

Suggested edit:

diff --git a/std/algebra/emulated/sw_bw6761/g1.go b/std/algebra/emulated/sw_bw6761/g1.go
index afdf15d9..02278f42 100644
--- a/std/algebra/emulated/sw_bw6761/g1.go
+++ b/std/algebra/emulated/sw_bw6761/g1.go
@@ -75,7 +75,7 @@ func (g1 *G1) double(p *G1Affine) *G1Affine {
 	mone := g1.curveF.NewElement(-1)
 	xr := g1.curveF.Eval([][]*baseEl{{λ, λ}, {mone, &p.X}}, []int{1, 2})
 
-	// yr = λ(p-xr) - p.y
+	// yr = λ(p.x-xr) - p.y
 	yr := g1.curveF.Eval([][]*baseEl{{λ, &p.X}, {mone, λ, xr}, {mone, &p.Y}}, []int{1, 1, 1})
 
 	return &G1Affine{
diff --git a/std/algebra/emulated/sw_bw6761/g2.go b/std/algebra/emulated/sw_bw6761/g2.go
index e46eb120..0709eb5d 100644
--- a/std/algebra/emulated/sw_bw6761/g2.go
+++ b/std/algebra/emulated/sw_bw6761/g2.go
@@ -151,7 +151,7 @@ func (g2 *G2) double(p *G2Affine) *G2Affine {
 	mone := g2.curveF.NewElement(-1)
 	xr := g2.curveF.Eval([][]*baseEl{{λ, λ}, {mone, &p.P.X}}, []int{1, 2})
 
-	// yr = λ(p-xr) - p.y
+	// yr = λ(p.x-xr) - p.y
 	yr := g2.curveF.Eval([][]*baseEl{{λ, &p.P.X}, {mone, λ, xr}, {mone, &p.P.Y}}, []int{1, 1, 1})
 
 	return &G2Affine{

@ivokub
Copy link
Collaborator

ivokub commented Dec 4, 2024

Suggested edit:

diff --git a/std/algebra/emulated/sw_bw6761/pairing.go b/std/algebra/emulated/sw_bw6761/pairing.go
index 04eec856..03fab1c5 100644
--- a/std/algebra/emulated/sw_bw6761/pairing.go
+++ b/std/algebra/emulated/sw_bw6761/pairing.go
@@ -19,7 +19,6 @@ type Pairing struct {
 	curve  *sw_emulated.Curve[BaseField, ScalarField]
 	g1     *G1
 	g2     *G2
-	g2gen  *G2Affine
 }
 
 type GTEl = fields_bw6761.E6
@@ -63,15 +62,6 @@ func NewPairing(api frontend.API) (*Pairing, error) {
 	}, nil
 }
 
-func (pr Pairing) generators() *G2Affine {
-	if pr.g2gen == nil {
-		_, _, _, g2gen := bw6761.Generators()
-		cg2gen := NewG2AffineFixed(g2gen)
-		pr.g2gen = &cg2gen
-	}
-	return pr.g2gen
-}
-
 // FinalExponentiation computes the exponentiation zᵈ where
 //
 // d = (p⁶-1)/r = (p⁶-1)/Φ₆(p) ⋅ Φ₆(p)/r = (p³-1)(p+1)(p²-p+1)/r
@@ -436,53 +426,6 @@ func (pr Pairing) doubleAndAddStep(p1, p2 *g2AffP, isSub bool) (*g2AffP, *lineEv
 	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
-	mone := pr.curveF.NewElement(-1)
-
-	// 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.Eval([][]*baseEl{{l1, l1}, {mone, &p1.X}, {mone, &p2.X}}, []int{1, 1, 1})
-
-	// 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.Eval([][]*baseEl{{l2, l2}, {mone, &p1.X}, {mone, x3}}, []int{1, 1, 1})
-
-	// compute y4 = λ2(x1 - x4)-y1
-	y4 := pr.curveF.Eval([][]*baseEl{{l2, &p1.X}, {mone, l2, x4}, {mone, &p1.Y}}, []int{1, 1, 1})
-
-	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 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) {

Copy link
Collaborator

@ivokub ivokub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks perfect! I also suggested some edits to make the comments a bit more precise and remove unused methods.

@yelhousni yelhousni merged commit 1ef9953 into master Dec 4, 2024
5 checks passed
@yelhousni yelhousni deleted the perf/bw6-eval branch December 4, 2024 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants