crypto: Use the generic ecc::dbl for G2 point doubling - #1635
Merged
Conversation
bn254::dbl duplicated the generic a=0 Jacobian doubling already in ecc::dbl. Both cost 18 Fq multiplications, but bn254::dbl reached the z coordinate via (y+z)² − y² − z², needing a z² that has no other use there, where ecc::dbl takes 2yz directly: same multiplication count, about a dozen fewer modular additions per doubling, and a G2 subgroup check does 63 doublings per pair. lin_func_and_dbl keeps its own copy of the formula, since it needs z² for the line coefficients anyway. Cuts about 0.3% off the ECPAIRING instruction count.
There was a problem hiding this comment.
Pull request overview
Reuses the generic Jacobian doubling implementation for BN254 G2 points, reducing redundant code and modular additions.
Changes:
- Removes the duplicate BN254 G2 doubling formula.
- Makes
ecc::dblusable fromconstexprBN254 helpers.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
lib/evmone_precompiles/pairing/bn254/utils.hpp |
Removes the local G2 doubling implementation. |
lib/evmone_precompiles/ecc.hpp |
Marks generic point doubling constexpr. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1635 +/- ##
==========================================
- Coverage 97.72% 97.71% -0.01%
==========================================
Files 171 171
Lines 15624 15607 -17
Branches 3610 3610
==========================================
- Hits 15268 15251 -17
Misses 269 269
Partials 87 87
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
bn254::dblrepeated the generic a=0 Jacobian doubling thatecc::dblalreadyimplements. The x and y steps are the same formula under different names; only z
differed, computed as
(y+z)² − y² − z²and so needing az²with no other usethere, where
ecc::dbltakes2yzdirectly.Both cost 18 Fq multiplications — an Fq² squaring is 2 Fq muls against 4 for a
multiplication, so the z coordinate is 4 Fq muls either way. The saving is in
additions: 7 sqr + 1 mul + 18 Fq² add/sub becomes 5 sqr + 2 mul + 14, about a dozen
fewer modular additions per doubling, and a G2 subgroup check does 63 doublings per
pair (57 through the
n_dbl<k>chain, 5 explicit inmul_by_X, 1 for_2px).lin_func_and_dblkeeps its own copy of the formula — it needsz²for the linecoefficients anyway, so the
(y+z)²form is the right one there.Worth about 0.3% of the ECPAIRING instruction count.
Notes for review
Equivalence. The two are the same polynomial identity, so this is not
input-dependent:
S ≡ d = 4xy²,M ≡ e = 3x², and the rest follows. Checkedagainst the deleted formula over 2000 random Fq² triples plus the edge cases
z = 0(infinity),y = 0,x = 0, all-zero,z = 1, and purely imaginarycoordinates — identical output in every case, including the same Jacobian
representative rather than merely the same affine point.
The
constexpris hygiene, not a requirement. It builds without it. The bn254callers (
n_dbl,mul_by_X,g2_subgroup_check) are declaredconstexprandnothing constant-evaluates them, so leaving
ecc::dblnon-constexpr is IFNDR thatcompilers accept. Adding it is the smaller of the two honest fixes; dropping
constexprfrom those three callers instead would also be defensible.bn254::adddeliberately stays, anddblis not symmetric with it.ecc::add<E2>does not compile: its infinity and doubling guards (
ecc.hpp:194p == 0,:300assert(r != 0 || h == 0),:301if (h == 0 && r == 0)) all compare a fieldelement against zero, and
Fq²has no such comparison —ExtFieldElemhas only thedefaulted
ExtFieldElem == ExtFieldElem, and0cannot convert to it because theconsteval constructor wants
DEGREE == 2coefficients. The a=0dblbranch, bycontrast, is entirely branch-free, which is why it substitutes cleanly.
That is one line from being fixable (
operator==(const ExtFieldElem&, zero_t)), but itshould not be:
bn254::adddocuments that its inputs are never infinity, equal, ornegations of each other, and
mul_by_X's addchain guarantees it — so unifying wouldimport an assert plus three dead branches onto a path taken ~20 times per pair.
Unqualified
add(...)in bn254 keeps resolving tobn254::addregardless, since anon-template beats a template in overload resolution.
🤖 Generated with Claude Code