Skip to content

feat(crypto): add post-quantum signature support for nile#41

Open
Federico2014 wants to merge 17 commits into
release_v4.8.2_build1from
feature/pqc-signature-v4.8.2-build1
Open

feat(crypto): add post-quantum signature support for nile#41
Federico2014 wants to merge 17 commits into
release_v4.8.2_build1from
feature/pqc-signature-v4.8.2-build1

Conversation

@Federico2014

@Federico2014 Federico2014 commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Summary

Adds post-quantum (PQ) signature support to TRON across protocol, crypto, transaction/block validation, TVM precompiles, witness configuration, consensus signing, relay handshakes, governance flags, and tests.

Two PQ schemes are supported, each independently gated by a committee proposal:

  • FN_DSA_512 / Falcon-512 (variable-length signature, max 667 B, pubkey 896 B)
  • ML_DSA_44 / Dilithium-2 (fixed-length signature 2420 B, pubkey 1312 B)

Protocol changes

  • Adds PQScheme enum: UNKNOWN_PQ_SCHEME, FN_DSA_512, ML_DSA_44.
  • Adds PQAuthSig { scheme, public_key, signature } as the shared PQ authentication envelope.
  • Adds repeated pq_auth_sig to Transaction so ECDSA and PQ signatures coexist for account permission threshold checks.
  • Adds pq_auth_sig to BlockHeader; legacy witness_signature and PQ pq_auth_sig are mutually exclusive.
  • Adds pq_auth_sig to HelloMessage for relay/fast-forward authentication by PQ witnesses.

Address derivation

  • PQ addresses: 0x41 || deriveHash(scheme, public_key)[12..32], matching the ECDSA shape.
  • Both schemes use Keccak-256 as the fingerprint hash.
  • PQSchemeRegistry.computeAddress(scheme, publicKey) is the single entry point.

Crypto module (crypto)

  • FNDSA512: Falcon-512 sign/verify; variable-length signatures validated against the canonical [SIGNATURE_MIN_LENGTH, SIGNATURE_MAX_LENGTH] range.
  • MLDSA44: ML-DSA-44 sign/verify; fixed-length 2420-byte signatures.
  • PQSignature, PQSchemeRegistry, PqKeypair: shared PQ abstraction layer.
  • PQSchemeRegistry centralises key lengths, signature lengths, seed handling, address derivation, sign, verify, and block-size wire-size computation (computePQAuthSigWireSize).

Governance and activation

  • Adds ALLOW_FN_DSA_512 (proposal id 99) and ALLOW_ML_DSA_44 (proposal id 100).
  • Both proposals are fork-gated on VERSION_4_8_2.
  • Runtime checks reject PQ signatures and precompile calls when the scheme is not yet active.

Witness configuration

  • PQ witness keys are configured via localPqWitness.keys — a list of paths to JSON key files (relative paths resolve against the working directory); each file holds one keypair, keeping the long key material out of config.conf.
  • Each JSON key file names a scheme and may contain any combination of the following material fields — privateKey takes priority at load time; seed is retained as a backup field when both are present:
    • seedFN_DSA_512: 96 hex chars / 48 B (accepted with a drift warning — Falcon keygen is FFT-based and not bit-stable across JVMs or CPU architectures); ML_DSA_44: 64 hex chars / 32 B (deterministic).
    • privateKeyFN_DSA_512 must also supply publicKey (BouncyCastle exposes no API to derive it from the private key); ML_DSA_44 supplies privateKey only — publicKey is derived automatically, but may optionally be included for verification (if present it must match the derived value, otherwise the node rejects the file).
    • address — informational field written by pq-key new, ignored at load time.
  • PqKeyFile (Jackson-bound) is the JSON shape.
  • PQ-only witnesses derive their witness address from the configured PQ public key when no explicit localPqWitness.accountAddress is set.
  • A node can host a mix of ECDSA and PQ SRs simultaneously.

Consensus and block production

  • Consensus miners carry optional PQ key material and sign blocks with the configured PQ scheme.
  • Block production fails fast if a PQ miner is configured for a scheme that is not yet active on-chain.
  • generateBlock pre-reserves the exact proto3 wire size of pq_auth_sig (via PQSchemeRegistry.computePQAuthSigWireSize) before the transaction packing loop, preventing PQ SR blocks from exceeding the receiver-side maxBlockSize check in BlockMsgHandler.

Transaction validation

  • TransactionCapsule validates mixed ECDSA + PQ signatures against the same account permission threshold.
  • PQ signer identity is derived from the in-band public key and matched against Permission.keys[].address.
  • Duplicate signers are rejected across ECDSA and PQ paths.
  • Shielded-transfer validation rejects transparent/PQ signatures on shielded-from transactions.

Block validation

  • Block signature validation supports both legacy ECDSA and PQ schemes.
  • The derived PQ address must match the on-chain witness permission address.

Bandwidth

  • PQ pq_auth_sig bytes are subtracted from net bandwidth as signature overhead (same treatment as ECDSA signature bytes).

Transaction and pending pool limits

  • Per-block PQ transaction cap: 1000 (PQ_TRANS_IN_BLOCK_COUNTS).
  • Configurable pending pool cap: node.pqTransInPendingMaxCounts (default 1000).

TVM precompiles

Five new precompiles covering single verify, batch verify, and mixed multi-sign for both PQ schemes:

Address Name Description
0x16 VerifyFnDsa512 Single Falcon-512 verify
0x17 BatchValidateFnDsa512 Batch Falcon-512 verify, bitmap result, MAX_SIZE=16
0x18 VerifyMlDsa44 Single ML-DSA-44 verify
0x19 BatchValidateMlDsa44 Batch ML-DSA-44 verify, bitmap result, MAX_SIZE=16
0x1a ValidateMultiPQSig Unified ECDSA + PQ permission threshold verify, MAX_SIZE=5

Energy values are calibrated via JMH benchmarks (warmup 5×2s, measurement 10×3s, 2 forks, 20 samples) using ECRecover.execute() — precompile 0x01, 3000 energy, 816.9 µs — as the reference unit. All benchmarks call contract.execute(input) to cover the full precompile path (ABI decode, slot scan, address derivation, verify):

Precompile Per-call operation Measured (µs) Energy
0x16 full path: validate + slot scan + verify() 44.8 170
0x17 per entry full path: ABI + computeAddress() + verify() 57.5 220
0x18 full path: validate + verify() 114.2 420
0x19 per entry full path: ABI + computeAddress() + verify() 126.6 470
0x1a FN-DSA entry same operation as 0x17 per entry 220
0x1a ML-DSA entry same operation as 0x19 per entry 470

ECRecover baseline: 816.9 µs → 3000 energy (CV 1.9%); all PQ values rounded up to the nearest 10. 0x1a ValidateMultiPQSig.execute() requires chain DB and cannot be benchmarked in isolation — its per-entry crypto work is identical to 0x17/0x19 respectively, so those values are reused.

These values are proposed based on this benchmark run and subject to community review before mainnet activation.

Relay / fast-forward support

  • RelayService signs and verifies HelloMessage using either legacy signatures or PQAuthSig.
  • PQ hello-message verification checks scheme registration, activation, key/signature lengths, address binding, and cryptographic validity.

Toolkit (plugins)

  • New Toolkit.jar pq-key new command generates a post-quantum key JSON file.
  • Default scheme: FN_DSA_512; default output directory: Wallet/.
  • Generated file contains all material fields in one place:
    {
      "scheme": "FN_DSA_512",
      "seed": "<96 hex chars>",
      "privateKey": "<2560 hex chars>",
      "publicKey": "<1792 hex chars>",
      "address": "T..."
    }
    ML_DSA_44 files follow the same structure with scheme-appropriate lengths (seed 64 hex, privateKey 5120 hex, publicKey 2624 hex).
  • File is written with 0600 permissions (owner read/write only).
  • --json flag prints a machine-readable summary (address, scheme, file).

Example module (example:pqc-example)

  • New Gradle sub-module example:pqc-example (package org.tron.example.pqc).
  • PQWitnessNode: in-process PQ witness node with deterministic keypairs.
  • PQFullNode: fullnode that dials PQWitnessNode via P2P and validates PQ-signed blocks.
  • PQClient: broadcasts a single PQ-signed transfer transaction.
  • PQTxSender: continuous multi-scheme (FN-DSA-512, ML-DSA-44, ECDSA) transfer and TRC20 load generator.
  • PQWitnessNode.writeWitnessConfig emits the full key file format (seed, privateKey, publicKey, address), matching the pq-key new output.
  • Run via ./gradlew :example:pqc-example:run -PmainClass=org.tron.example.pqc.PQWitnessNode.

Compatibility

  • Pre-activation behavior is legacy-only; PQ fields are rejected when no scheme is active.
  • UNKNOWN_PQ_SCHEME is reserved and never treated as a valid signing scheme.
  • Existing ECDSA transaction and block signing paths remain fully supported.

Tests

  • Unit tests: Falcon-512 and ML-DSA-44 sign/verify, KAT regression, PQSchemeRegistry, PQSignature.
  • TVM tests: single, batch, and unified multi-sign PQ precompiles.
  • Transaction and block capsule tests for PQ authentication.
  • Witness config, proposal, relay, bandwidth, JSON, and account-permission tests.

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ae4358b4-dc64-4359-af36-0aef340e2f00

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/pqc-signature-v4.8.2-build1

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 and usage tips.

@Federico2014 Federico2014 changed the title feat(crypto): add post-quantum signature support feat(crypto): add post-quantum signature support for nile Jun 17, 2026
@Federico2014 Federico2014 changed the title feat(crypto): add post-quantum signature support for nile feat(crypto): add post-quantum signature support for Nile Jun 17, 2026

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

5 issues found across 81 files

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

Re-trigger cubic

Comment thread consensus/src/main/java/org/tron/consensus/base/Param.java
Comment thread common/src/main/java/org/tron/core/config/args/CommitteeConfig.java
Comment thread crypto/src/main/java/org/tron/common/crypto/pqc/PQSignature.java
Comment thread example/pqc-example/build.gradle
@Federico2014 Federico2014 force-pushed the feature/pqc-signature-v4.8.2-build1 branch from e28e6b4 to f77f97c Compare June 17, 2026 07:58
@Federico2014 Federico2014 changed the title feat(crypto): add post-quantum signature support for Nile feat(crypto): add post-quantum signature support for nile Jun 17, 2026
@Federico2014 Federico2014 force-pushed the feature/pqc-signature-v4.8.2-build1 branch from 59f5a22 to 2e0a76b Compare June 17, 2026 08:14
Little-Peony and others added 5 commits June 17, 2026 16:54
- Consolidate PQ scheme validation into isPqSchemeAllowed (warns on unregistered scheme, returns false); drop the redundant PQSchemeRegistry.contains() pre-checks in BlockCapsule/TransactionCapsule/Manager/RelayService and unify wording to "not allowed".

- Rename RelayService keySize -> ecdsaKeySize for clarity.

- Reject a single account authorising both an ECDSA and a PQ witness key (LocalWitnesses.checkWitnessAddressConflict, invoked from Args after merging witnesses), with unit tests.
@Federico2014 Federico2014 force-pushed the feature/pqc-signature-v4.8.2-build1 branch from 2e0a76b to 42c4b53 Compare June 17, 2026 09:24
@Federico2014 Federico2014 force-pushed the feature/pqc-signature-v4.8.2-build1 branch from 2e216bb to d1cf710 Compare June 17, 2026 09:50
@Federico2014 Federico2014 force-pushed the feature/pqc-signature-v4.8.2-build1 branch from 974ab77 to a02783b Compare June 17, 2026 10:50
@Federico2014 Federico2014 force-pushed the feature/pqc-signature-v4.8.2-build1 branch from c27c474 to a9e4172 Compare June 17, 2026 11:50

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

1 issue found across 7 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread plugins/src/main/java/common/org/tron/plugins/PqKeyNew.java Outdated
@Federico2014 Federico2014 force-pushed the feature/pqc-signature-v4.8.2-build1 branch from 1f3514d to 2e27377 Compare June 18, 2026 03:59
@Federico2014 Federico2014 force-pushed the feature/pqc-signature-v4.8.2-build1 branch from 2e27377 to 92d2fa4 Compare June 18, 2026 04:29

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

2 issues found across 1 file (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java Outdated
Comment thread actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java Outdated
@Federico2014 Federico2014 force-pushed the feature/pqc-signature-v4.8.2-build1 branch from 0e9bbe3 to 3e3056b Compare June 18, 2026 14:09

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

1 issue found across 5 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread framework/src/test/java/org/tron/common/runtime/vm/ValidateMultiPQSigTest.java Outdated
@Federico2014 Federico2014 force-pushed the feature/pqc-signature-v4.8.2-build1 branch from 30203d8 to c29f847 Compare June 18, 2026 15:54
@Federico2014 Federico2014 force-pushed the feature/pqc-signature-v4.8.2-build1 branch from c29f847 to bc5736b Compare June 19, 2026 03:35

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

1 issue found across 3 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread framework/src/main/java/org/tron/core/db/Manager.java
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