Skip to content

crypto: Use the generic ecc::dbl for G2 point doubling - #1635

Merged
chfast merged 1 commit into
masterfrom
crypto/dedup-g2-doubling
Aug 10, 2026
Merged

crypto: Use the generic ecc::dbl for G2 point doubling#1635
chfast merged 1 commit into
masterfrom
crypto/dedup-g2-doubling

Conversation

@chfast

@chfast chfast commented Aug 10, 2026

Copy link
Copy Markdown
Member

bn254::dbl repeated the generic a=0 Jacobian doubling that ecc::dbl already
implements. The x and y steps are the same formula under different names; only z
differed, computed as (y+z)² − y² − z² and so needing a with no other use
there, where ecc::dbl takes 2yz directly.

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 in mul_by_X, 1 for _2px).

lin_func_and_dbl keeps its own copy of the formula — it needs for the line
coefficients 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. Checked
    against 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 imaginary
    coordinates — identical output in every case, including the same Jacobian
    representative rather than merely the same affine point.

  • The constexpr is hygiene, not a requirement. It builds without it. The bn254
    callers (n_dbl, mul_by_X, g2_subgroup_check) are declared constexpr and
    nothing constant-evaluates them, so leaving ecc::dbl non-constexpr is IFNDR that
    compilers accept. Adding it is the smaller of the two honest fixes; dropping
    constexpr from those three callers instead would also be defensible.

  • bn254::add deliberately stays, and dbl is not symmetric with it. ecc::add<E2>
    does not compile: its infinity and doubling guards (ecc.hpp:194 p == 0,
    :300 assert(r != 0 || h == 0), :301 if (h == 0 && r == 0)) all compare a field
    element against zero, and Fq² has no such comparison — ExtFieldElem has only the
    defaulted ExtFieldElem == ExtFieldElem, and 0 cannot convert to it because the
    consteval constructor wants DEGREE == 2 coefficients. The a=0 dbl branch, by
    contrast, is entirely branch-free, which is why it substitutes cleanly.

    That is one line from being fixable (operator==(const ExtFieldElem&, zero_t)), but it
    should not be: bn254::add documents that its inputs are never infinity, equal, or
    negations of each other, and mul_by_X's addchain guarantees it — so unifying would
    import an assert plus three dead branches onto a path taken ~20 times per pair.

    Unqualified add(...) in bn254 keeps resolving to bn254::add regardless, since a
    non-template beats a template in overload resolution.

🤖 Generated with Claude Code

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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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::dbl usable from constexpr BN254 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

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.71%. Comparing base (ce6ef36) to head (f492676).

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              
Flag Coverage Δ
eest-develop 88.62% <ø> (-0.04%) ⬇️
eest-develop-gmp 26.53% <ø> (-0.09%) ⬇️
eest-legacy 17.15% <ø> (+0.01%) ⬆️
eest-libsecp256k1 28.83% <ø> (-0.08%) ⬇️
eest-stable 88.62% <ø> (-0.04%) ⬇️
evmone-unittests 93.42% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
core 96.10% <ø> (-0.02%) ⬇️
tooling 91.92% <ø> (ø)
tests 99.80% <ø> (ø)
Files with missing lines Coverage Δ
lib/evmone_precompiles/ecc.hpp 97.24% <ø> (ø)
lib/evmone_precompiles/pairing/bn254/utils.hpp 100.00% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@chfast
chfast merged commit 9888163 into master Aug 10, 2026
24 checks passed
@chfast
chfast deleted the crypto/dedup-g2-doubling branch August 10, 2026 21:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants