Skip to content

feat(crypto): add native secp256k1 support - #52

Open
Federico2014 wants to merge 1 commit into
developfrom
feature/configurable_secp256k1_jna
Open

feat(crypto): add native secp256k1 support#52
Federico2014 wants to merge 1 commit into
developfrom
feature/configurable_secp256k1_jna

Conversation

@Federico2014

@Federico2014 Federico2014 commented Aug 6, 2026

Copy link
Copy Markdown
Owner

What does this PR do?

Add an optional JNA-backed NativeSecp256k1 implementation for secp256k1 key construction, deterministic signing, public-key recovery, and address recovery.

Add the crypto.useNativeSecp256k1 configuration option and route ECKey signature verification through the native implementation when explicitly enabled. PBFT signature recovery now uses the shared SignUtils routing path.

Add native/ECKey cross-compatibility tests, configuration tests, dependency verification metadata, and an opt-in signing and recovery benchmark.

Why are these changes required?

The existing pure-Java ECKey implementation has significantly higher signing and signature-recovery overhead. Native libsecp256k1 provides a faster implementation while preserving the existing signature format, recovery ID handling, canonical low-S behavior, and recovered TRON addresses.

The feature is disabled by default, so existing nodes retain the original Java implementation unless explicitly configured otherwise.

This PR has been tested by:

  • Unit Tests
  • Manual Testing

The native and Java implementations were cross-tested with deterministic signatures, bidirectional signature recovery, constructor compatibility, high-S signatures, malformed input, and configuration routing.

NativeSecp256k1Test, related configuration tests, checkstyleMain, and checkstyleTest passed.

An opt-in local benchmark with 5,000 iterations measured approximately 32.08x faster signing and 16.57x faster signature-address recovery on an x86_64 Java 8 environment.

Follow up

None.

Extra details

The new configuration defaults to false and is effective only when crypto.engine = "eckey". SM2 behavior is unchanged. If the native library is unavailable, verification remains on ECKey.

This change adds JNA 5.12.1 and com.github.federico2014.besu-native:secp256k1:1.3.11, including Gradle dependency verification metadata.


Summary by cubic

Adds optional native secp256k1 via JNA for signing and public-key/address recovery, toggled by crypto.useNativeSecp256k1 when crypto.engine = "eckey". PBFT signature recovery now goes through SignUtils; startup throws NATIVE_CRYPTO_INIT if native is enabled but unavailable, and the flag is ignored for sm2.

  • New Features

    • Introduced NativeSecp256k1 (deterministic signing, pubkey/address recovery) with ECKey-compatible format and canonical low-S.
    • Centralized routing in SignUtils (setUseNativeSecp256k1), wired via Args, exposed as CommonParameter.useNativeSecp256k1; config keys added to reference.conf and config.conf.
    • Stricter checks for recovery header and r/s size; preserves acceptance of base64 signatures with trailing bytes. Added interop tests and an opt-in local benchmark.
  • Dependencies

    • Added net.java.dev.jna:jna:5.12.1 and com.github.federico2014.besu-native:secp256k1:1.3.11; updated Gradle verification metadata.

Written for commit 174b6a0. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added optional native secp256k1 support for signing, signature verification, and address recovery.
    • Added configuration to enable native cryptography, disabled by default and limited to the compatible cryptographic engine.
    • Automatically falls back to the existing implementation when native support is unavailable.
    • Improved compatibility between native and standard signature handling.
  • Bug Fixes

    • Strengthened validation for malformed signatures, recovery headers, and oversized signature components.
  • Tests

    • Added coverage for configuration, interoperability, invalid inputs, and performance comparisons.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The PR adds a configurable JNA-backed secp256k1 implementation. It supports native signing, public-key recovery, serialization, validation, and address derivation. EC-key verification uses the native backend when configured and available. PBFT recovery now uses SignUtils.

Native secp256k1 integration

Layer / File(s) Summary
Configuration contract
common/src/main/java/..., common/src/main/resources/reference.conf, framework/src/main/resources/config.conf, common/src/main/java/.../TronError.java, common/src/test/..., framework/src/test/...
The useNativeSecp256k1 setting defaults to false. Configuration parsing, runtime error handling, and parameter tests cover enabled and disabled values.
Native secp256k1 backend
crypto/build.gradle, crypto/src/main/java/.../NativeSecp256k1.java, framework/src/test/java/.../NativeSecp256k1*, gradle/verification-metadata.xml
The crypto module adds JNA and native secp256k1 dependencies. NativeSecp256k1 implements key generation, signing, recovery, serialization, availability checks, and input validation. Tests cover interoperability, invalid inputs, recovery headers, high-S signatures, and optional benchmarking.
Runtime routing and PBFT use
crypto/src/main/java/.../SignUtils.java, framework/src/main/java/.../Args.java, consensus/src/main/java/.../PbftBaseMessage.java, framework/src/main/java/.../PbftDataSyncHandler.java, framework/src/test/java/.../ArgsTest.java
SignUtils selects native recovery for eligible EC-key signatures. Args applies and clears the setting, while SM2 does not activate native verification. PBFT signature recovery uses SignUtils.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Args
  participant SignUtils
  participant NativeSecp256k1
  participant PbftDataSyncHandler
  Args->>SignUtils: Apply EC-key native verification setting
  PbftDataSyncHandler->>SignUtils: Recover address from PBFT signature
  SignUtils->>NativeSecp256k1: Recover address when native mode is enabled
  NativeSecp256k1-->>SignUtils: Return recovered address
  SignUtils-->>PbftDataSyncHandler: Return signature address
Loading

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.16% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding optional native secp256k1 support.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/configurable_secp256k1_jna

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
consensus/src/main/java/org/tron/consensus/pbft/message/PbftBaseMessage.java (1)

99-100: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Document the hardcoded engine flag.

The literal true selects the EC-key crypto engine. It preserves the previous ECKey.signatureToAddress behavior, so PBFT recovery stays on EC-key even when the node runs the SM2 engine. That intent is not visible at the call site.

Add a short comment, or extract a named constant such as PBFT_USES_ECKEY_ENGINE. The same literal appears in framework/src/main/java/org/tron/core/net/messagehandler/PbftDataSyncHandler.java at lines 176 to 177.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@consensus/src/main/java/org/tron/consensus/pbft/message/PbftBaseMessage.java`
around lines 99 - 100, The hardcoded crypto-engine flag in PbftBaseMessage
signature recovery is undocumented. Add a short comment or reuse a clearly named
constant such as PBFT_USES_ECKEY_ENGINE at the SignUtils.signatureToAddress
call, and apply the same documentation or constant usage to the corresponding
call in PbftDataSyncHandler so the intentional EC-key behavior remains explicit.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crypto/build.gradle`:
- Line 16: Update the secp256k1 dependency declaration in the crypto Gradle
configuration: either replace
com.github.federico2014.besu-native:secp256k1:1.3.11 with the official upstream
coordinate, or document the fork’s necessity and build provenance, including who
reviewed it, while preserving the verification metadata alignment.

---

Nitpick comments:
In
`@consensus/src/main/java/org/tron/consensus/pbft/message/PbftBaseMessage.java`:
- Around line 99-100: The hardcoded crypto-engine flag in PbftBaseMessage
signature recovery is undocumented. Add a short comment or reuse a clearly named
constant such as PBFT_USES_ECKEY_ENGINE at the SignUtils.signatureToAddress
call, and apply the same documentation or constant usage to the corresponding
call in PbftDataSyncHandler so the intentional EC-key behavior remains explicit.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 26652c53-d3cf-4f18-b34a-210fb360adea

📥 Commits

Reviewing files that changed from the base of the PR and between f87081b and 780fcc6.

📒 Files selected for processing (16)
  • common/src/main/java/org/tron/common/parameter/CommonParameter.java
  • common/src/main/java/org/tron/core/config/args/MiscConfig.java
  • common/src/main/resources/reference.conf
  • common/src/test/java/org/tron/core/config/args/MiscConfigTest.java
  • consensus/src/main/java/org/tron/consensus/pbft/message/PbftBaseMessage.java
  • crypto/build.gradle
  • crypto/src/main/java/org/tron/common/crypto/NativeSecp256k1.java
  • crypto/src/main/java/org/tron/common/crypto/SignUtils.java
  • framework/src/main/java/org/tron/core/config/args/Args.java
  • framework/src/main/java/org/tron/core/net/messagehandler/PbftDataSyncHandler.java
  • framework/src/main/resources/config.conf
  • framework/src/test/java/org/tron/common/ParameterTest.java
  • framework/src/test/java/org/tron/common/crypto/NativeSecp256k1BenchmarkTest.java
  • framework/src/test/java/org/tron/common/crypto/NativeSecp256k1Test.java
  • framework/src/test/java/org/tron/core/config/args/ArgsTest.java
  • gradle/verification-metadata.xml

Comment thread crypto/build.gradle

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 16 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread framework/src/test/java/org/tron/core/config/args/ArgsTest.java Outdated
Comment thread crypto/src/main/java/org/tron/common/crypto/NativeSecp256k1.java
Comment thread framework/src/main/java/org/tron/core/config/args/Args.java
Comment thread crypto/build.gradle
Comment thread framework/src/test/java/org/tron/common/crypto/NativeSecp256k1BenchmarkTest.java Outdated
@Federico2014 Federico2014 linked an issue Aug 7, 2026 that may be closed by this pull request
@Federico2014
Federico2014 force-pushed the feature/configurable_secp256k1_jna branch from 780fcc6 to f9bd0f3 Compare August 7, 2026 08:31
@Federico2014
Federico2014 force-pushed the feature/configurable_secp256k1_jna branch from b2bfe99 to 174b6a0 Compare August 7, 2026 09:25
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.

[Feature] Optimize secp256k1 signature performance

1 participant