Summary
Introduce an optional JNA-backed native secp256k1 implementation for key construction, deterministic signing, public-key recovery, and signature-address recovery while retaining the existing pure-Java ECKey implementation as the default.
Problem
Motivation
java-tron currently performs secp256k1 signing and signature recovery through the pure-Java ECKey implementation. These operations are used across transaction processing, block production, and PBFT signature validation, so their cost directly affects node throughput and block-processing latency.
The broader cryptographic optimization analysis in tronprotocol/java-tron#6374 compared java-tron with Besu's native secp256k1 implementation. On Ubuntu x86_64, native EcRecover and secp256k1 verification were approximately 18x faster than java-tron. The same issue also identified native libraries as a useful optimization path for other computationally intensive cryptographic primitives.
A preliminary proof-of-concept benchmark produced the following local results on an x86_64 Java 8 environment with 5,000 measured iterations:
| Operation |
ECKey |
NativeSecp256k1 |
Speedup |
| Deterministic signing |
2,531,811 ns/op |
78,912 ns/op |
32.08x |
| Signature-address recovery |
1,394,938 ns/op |
84,174 ns/op |
16.57x |
Current State
ECKey uses the existing Java/Bouncy Castle implementation for secp256k1 operations.
- There is no production API for explicitly performing native deterministic signing.
- Signature recovery paths cannot be switched between Java and native implementations through node configuration.
- Some PBFT verification paths call
ECKey directly instead of using the shared signature routing abstraction.
Limitations or Risks
- JNA introduces platform-specific native dependencies and a different failure model from pure Java code.
- A native crash can terminate the JVM, so native acceleration in consensus-sensitive paths must remain operationally controllable.
- Signing and recovery results must remain byte-for-byte compatible with
ECKey; any difference could affect address recovery or consensus behavior.
- Availability must be verified across the supported x86_64/JDK 8 and aarch64/JDK 17 build environments.
Proposed Solution
Proposed Design
Add NativeSecp256k1, backed by bitcoin-core's libsecp256k1 through JNA, with the following behavior:
- Provide constructors compatible with common
ECKey usage: default key generation, caller-provided SecureRandom, and caller-provided private-key bytes.
- Provide an explicit production signing API that returns
ECKey.ECDSASignature and preserves deterministic signing, recovery IDs, and canonical low-S encoding.
- Provide native public-key and TRON-address recovery for both Base64 signatures and
ECDSASignature components.
- Validate message hashes, private-key ranges, signature component sizes, and recovery headers before invoking native code.
- Clear temporary private-key byte arrays after native operations.
- Preserve historical signature compatibility, including accepted recovery headers and high-S recovery behavior.
Add an opt-in configuration switch:
crypto {
engine = "eckey"
useNativeSecp256k1 = false
}
The switch affects signature verification/address recovery only. Native signing remains an explicit API choice so enabling verification does not silently change existing key-generation or signing behavior.
When native secp256k1 is requested but unavailable, java-tron keeps the Java ECKey verification path. The switch is effective only when crypto.engine = "eckey"; SM2 behavior remains unchanged.
Key Changes
- Add the native secp256k1 implementation and explicit signing API in the
crypto module.
- Route configurable ECKey signature recovery through
SignUtils.
- Initialize the effective runtime selection from
Args and reset it during configuration cleanup.
- Route PBFT signature checks through
SignUtils instead of direct ECKey calls.
- Add JNA and native secp256k1 dependencies with Gradle dependency verification metadata.
- Add Java/native interoperability tests and an opt-in local benchmark.
Test Specification
- Verify that Java and native deterministic signatures are byte-for-byte and Base64 identical.
- Cross-check Java signatures with native recovery and native signatures with Java recovery across multiple private keys and message hashes.
- Verify constructor-generated public keys, addresses, and signatures against
ECKey.
- Verify compatibility for high-S signatures and Base64 signatures with historically accepted trailing bytes.
- Reject invalid hashes, private keys, oversized signature components, and invalid recovery headers without truncation.
- Verify configuration behavior for
eckey, SM2, unavailable native libraries, and configuration cleanup.
- Run focused PBFT and crypto regression tests.
- Benchmark signing and signature-address recovery with warmup on supported x86_64 and aarch64 environments.
Impact
- Reduces secp256k1 signing and signature-recovery latency when native acceleration is used.
- Improves high-volume transaction and PBFT signature-processing performance.
- Does not change signature wire formats, recovered addresses, or consensus rules.
- Does not require a hard fork because the feature is a local implementation choice with identical outputs.
- Introduces native-library operational risk, mitigated by default-disabled configuration and retention of the Java implementation.
Compatibility
- Breaking Change: No
- Default Behavior Change: No; native verification is disabled by default
- Migration Required: No
- Configuration Required: Only for operators who explicitly opt in
References
Additional Notes
- Do you have ideas regarding implementation? Yes; the proposed native JNA design is described above.
- Are you willing to implement this feature? Yes.
Summary
Introduce an optional JNA-backed native secp256k1 implementation for key construction, deterministic signing, public-key recovery, and signature-address recovery while retaining the existing pure-Java
ECKeyimplementation as the default.Problem
Motivation
java-tron currently performs secp256k1 signing and signature recovery through the pure-Java
ECKeyimplementation. These operations are used across transaction processing, block production, and PBFT signature validation, so their cost directly affects node throughput and block-processing latency.The broader cryptographic optimization analysis in tronprotocol/java-tron#6374 compared java-tron with Besu's native secp256k1 implementation. On Ubuntu x86_64, native
EcRecoverand secp256k1 verification were approximately 18x faster than java-tron. The same issue also identified native libraries as a useful optimization path for other computationally intensive cryptographic primitives.A preliminary proof-of-concept benchmark produced the following local results on an x86_64 Java 8 environment with 5,000 measured iterations:
Current State
ECKeyuses the existing Java/Bouncy Castle implementation for secp256k1 operations.ECKeydirectly instead of using the shared signature routing abstraction.Limitations or Risks
ECKey; any difference could affect address recovery or consensus behavior.Proposed Solution
Proposed Design
Add
NativeSecp256k1, backed by bitcoin-core's libsecp256k1 through JNA, with the following behavior:ECKeyusage: default key generation, caller-providedSecureRandom, and caller-provided private-key bytes.ECKey.ECDSASignatureand preserves deterministic signing, recovery IDs, and canonical low-S encoding.ECDSASignaturecomponents.Add an opt-in configuration switch:
The switch affects signature verification/address recovery only. Native signing remains an explicit API choice so enabling verification does not silently change existing key-generation or signing behavior.
When native secp256k1 is requested but unavailable, java-tron keeps the Java
ECKeyverification path. The switch is effective only whencrypto.engine = "eckey"; SM2 behavior remains unchanged.Key Changes
cryptomodule.SignUtils.Argsand reset it during configuration cleanup.SignUtilsinstead of directECKeycalls.Test Specification
ECKey.eckey, SM2, unavailable native libraries, and configuration cleanup.Impact
Compatibility
References
Additional Notes