Skip to content

Reuse a modular power when initializing generic sqrt_ratio constants - #2455

Open
carstenartur wants to merge 1 commit into
bcgit:mainfrom
carstenartur:perf/hash2curve-constants-upstream
Open

carstenartur wants to merge 1 commit into
bcgit:mainfrom
carstenartur:perf/hash2curve-constants-upstream

Conversation

@carstenartur

Copy link
Copy Markdown

Since c2 = 2*c3 + 1, derive c7 and c6 from z^c3 instead of computing two independent powers (RFC 9380 F.2.1.1). Preserve the exact constants and leave the per-call sqrtRatio algorithm unchanged.

Cover direct-power equality, zero exponents and negative/unreduced bases, repeated root equations, and the reduced exponentiation count.

AI-assisted implementation; benchmark infrastructure is kept in the research fork rather than included in this upstream candidate.

Reuse a modular power when initializing generic sqrt_ratio constants

Change

Avoid two independent modular powers in the GenericSqrtRatioCalculator constructor. Since c2 = 2*c3 + 1, compute:

t  = z^c3 mod q
c7 = t*z mod q
c6 = t*c7 mod q

These are exactly the constants from RFC 9380 F.2.1.1. One modular exponentiation replaces two, with two modular multiplications. The identity includes exponent zero and negative/unreduced bases without inversion. The per-call sqrtRatio method is unchanged. No API, cache, randomness, security-parameter or dependency changes are introduced.

This is one commit on ab16374d37c7e18c4090eb8838ebbd72a92593f2, with only three production/test files. Research workflows and benchmarks stay in the fork.

Public API measurements

The real HashToEllipticCurve.getInstance(profile, dst).hashToCurve(message) path was measured with 64 rotating deterministic 32-byte messages. The two libraries have identical class names and differ only in the calculator class.

Profile Less time, Java 21 Less time, Java 25
P-256 10.92% 12.06%
P-384 15.09% 16.53%
P-521 16.29% 15.71%
Equal-profile geometric comparison 14.13% 14.79%

All six primary JMH intervals are separated. Factory-only time is about 46% lower; all six reused-instance intervals overlap. This is a warm-JVM initialization/first-use improvement, NOT a steady-state, cold-start, all-curve or whole-application speedup.

JMH 1.37: 2 forks, 3 warmups and 5 measurements of 500ms, one thread, GC profiler; all cases and 180 primary samples per JVM retained. JVMs ran on separate hosted runners, so this is not a controlled comparison of Java versions.

Full results and raw-artifact identifiers | Fixed plan and runnable harness

Validation

The complete default repository test :core:checkstyleMain run passed with 3,602 JUnit cases, zero failures/errors/skips, and zero core main-source Checkstyle findings. It exercised the same production and test blobs as this patch. A separate job checked out exact candidate 3d56837c3fe6c4a30fc7639b806958649e143210 and passed all 181 hash-to-curve cases and core main-source style. Artifact hashes, actual XML, zero exit receipts and terminal build success were verified: full validation.

Added tests compare actual constants against the original powers, cover edge cases, check repeated root equations/QR flags and the reduced exponentiation count. The count test fails on the original constructor; a deliberately corrupted constant is detected. Existing RFC-vector tests are unchanged. The API experiment also checks 201 exact points, fresh/reused equivalence and reference outputs before each trial.

AI assistance

ChatGPT assisted with implementation, tests and benchmark preparation. The algebra, code and executable evidence were reviewed, and an additional automated Copilot review reported no findings. Upstream maintainer review is requested. No increased-security, constant-time BigInteger or autonomous mathematical-discovery claim is made.

Since c2 = 2*c3 + 1, derive c7 and c6 from z^c3 instead of computing
two independent powers (RFC 9380 F.2.1.1). Preserve the exact constants
and leave the per-call sqrtRatio algorithm unchanged.

Cover direct-power equality, zero exponents and negative/unreduced
bases, repeated root equations, and the reduced exponentiation count.

AI-assisted implementation; benchmark infrastructure is kept in the
research fork rather than included in this upstream candidate.
@carstenartur
carstenartur marked this pull request as ready for review September 19, 2026 16:17
Copilot AI lite review requested due to automatic review settings September 19, 2026 16:17

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.

Copilot review overview

🟢 Approval recommended

The changes and accompanying tests fully address the optimization while preserving existing behavior.

Review effort: Lite
Findings: None

What changed in this PR

Optimizes generic sqrt-ratio initialization by deriving c6 and c7 from one modular exponentiation while preserving runtime behavior.

Changes:

  • Reuses z^c3 to calculate both constants.
  • Adds correctness, edge-case, behavior, and exponentiation-count tests.
  • Registers the new test suite.
File Description
core/​src/​main/​java/​org/​bouncycastle/​crypto/​hash2curve/​impl/​GenericSqrtRatioCalculator.java Shares modular exponentiation during constant initialization.
core/​src/​test/​java/​org/​bouncycastle/​crypto/​hash2curve/​test/​impl/​GenericSqrtRatioConstantsTest.java Verifies constants, edge cases, behavior, and operation count.
core/​src/​test/​java/​org/​bouncycastle/​crypto/​hash2curve/​test/​AllTests.java Includes the new test class.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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