AgentSkillsCN

Pqc Crypto Review

Pqc加密审查

SKILL.md

Skill: Post-Quantum Cryptography Review (PQC)

Scope: Smart contracts and backend code touching cryptography (signatures, hashing, merkle proofs)

When to activate: Files modified in contracts/contracts/, services/*crypto*, verification/, or any code with:

  • Keccak256, SHA-256, or other hash functions
  • ECDSA, BLS, or other signatures
  • Merkle tree proofs
  • Key material or randomness

Current Cryptographic Inventory

What We Use Today

code
✅ Keccak-256 (merkle proofs in CronosSettlementAnchor.sol)
❌ ECDSA (not used yet; good!)
❌ BLS (not used yet; good!)
❌ RSA (not used; good!)

Quantum Vulnerability Timeline

code
ECDSA/secp256k1:   ⚠️  BREAK RISK ~2030-2040 (Shor's algorithm)
Keccak-256:        ⚠️  COLLISION RISK ~2025-2030 (faster than classical)
BLS (if added):    ⚠️  BREAK RISK ~2030-2040

Security Checklist (Apply to Every Crypto-Touching PR)

1. Identify Cryptographic Primitives

When reviewing code, answer:

  • What hash functions are used? (Keccak256, SHA-2, SHA-3, etc.)
  • What signatures are used? (ECDSA, Ed25519, BLS, etc.)
  • What key material exists? (private keys, secrets, nonces)
  • What randomness sources exist? (block.timestamp, block.number, external oracle)

Example:

solidity
// ❌ BAD: CronosSettlementAnchor._verifyProof uses Keccak256
bytes32 leaf = keccak256(abi.encodePacked(withdrawalId, recipient, amount));
// This leaf hash is VULNERABLE TO:
// - Preimage attacks (after ~15 years at quantum scale)
// - Collision attacks (after ~7 years at quantum scale)

2. Assess Quantum Breakage Risk

For each primitive, determine:

PrimitiveAlgorithmTimelineBreakage CostMitigation Path
Merkle (Keccak)Hash-based2025-2030Medium (proofs invalid)Dual-tree (Keccak + SPHINCS+)
ECDSA (if added)Elliptic curve2030-2040High (all sigs invalid)ECDSA + Dilithium hybrid
BLS (if added)Pairing2030-2040High (all sigs invalid)Dilithium + legacy BLS
RNG (if added)PRNGVariesLow-MediumSeed upgrade strategy

3. Flag Implicit Assumptions

Ask these questions about each crypto operation:

  • Is the hash collision probability documented? (Should assume 2^-128 at best)
  • Is the merkle proof collision-resistant? (Can two different leaves hash to same value?)
  • Does the code assume ECDSA won't be broken? (Implicit 20+ year assumption)
  • Is there a key rotation strategy? (If keys are hardcoded, NO rotation = disaster)
  • Can cryptography be upgraded later? (Or is upgrade path locked out?)

4. Recommend Concrete PQ Actions

For Keccak-256 merkle proofs (applies NOW):

code
CURRENT RISK: High (merkle roots are immutable; can't be re-computed post-quantum)
SOLUTION: Implement DUAL_MERKLE_TREE strategy

Phase 2.B (now):
  - Store merkle roots: BOTH Keccak-256 AND SHA-3-256
  - Verify proofs against BOTH roots (AND gate, not OR)
  - Increases gas ~15%, but prevents quantum forgery

Phase 3+ (parallel):
  - Add SPHINCS+ root alongside SHA-3
  - Governance votes on timeline to enforce SPHINCS+ proofs
  - Keep Keccak verification as fallback for legacy proofs

For Future ECDSA (if added):

code
RISK: Medium (signatures expire in ~2030-2040, not immediate)
SOLUTION: Hybrid ECDSA + Dilithium NOW (while ECDSA still works)

Phase 2.C:
  - Add Dilithium signature verification alongside ECDSA
  - Require BOTH signatures for critical operations (governance, key rotation)
  - Cost: ~2x signature verification, ~1400 bytes per sig

Phase 3+:
  - Governance deprecates ECDSA-only signatures
  - All new keys use Dilithium
  - Old ECDSA keys can still verify existing proofs (backward compat)

Code Patterns to Flag

🚨 ANTI-PATTERN: Immutable Hash

solidity
// ❌ BAD: Merkle root stored immutably with Keccak256
bytes32 public immutable merkleRoot = keccak256(...);

// PROBLEM: After quantum break, root is forged-proof; can't migrate to PQC

FIX:

solidity
// ✅ GOOD: Dual-tree with version tracking
struct MerkleRoot {
    uint256 version;    // 1=Keccak, 2=SHA-3, 3=SPHINCS+
    bytes32 root;
    uint256 committedAt;
}

mapping(uint256 => MerkleRoot[]) public roots; // batch => version => root

🚨 ANTI-PATTERN: Unversioned Proofs

solidity
// ❌ BAD: Proof format has no version; can't distinguish ECDSA from Dilithium later
function verifySignature(bytes signature, bytes32 digest) public {
    // Which algorithm? ECDSA or Dilithium? Ambiguous!
}

FIX:

solidity
// ✅ GOOD: Enum-versioned proof type
enum SignatureType { ECDSA_V1, DILITHIUM_V1 }

function verifySignature(
    SignatureType sigType,
    bytes signature,
    bytes32 digest
) public {
    if (sigType == SignatureType.ECDSA_V1) {
        // ECDSA logic
    } else if (sigType == SignatureType.DILITHIUM_V1) {
        // Dilithium logic
    }
}

NIST PQC Finalists (Reference)

Signatures

  • Dilithium (NIST FIPS 204): Fast, small, proven security. USE THIS for general signatures.
  • Falcon (NIST FIPS 196): Smallest, latency-optimal. USE for bandwidth-constrained chains.
  • SPHINCS+ (NIST SP 800-208): Stateless, conservative, proven. USE for merkle trees + emergency fallback.

Key Encapsulation

  • Kyber (NIST FIPS 203): Most battle-tested. USE if we add encryption/KEX.

Gas Costs (Rough Estimates on EVM)

code
ECDSA signature verify:     ~2000 gas
Dilithium verify:           ~50,000 gas (expensive; consider off-chain)
SPHINCS+ verify:            ~100,000+ gas (not suitable for on-chain; use off-chain)
Merkle proof verify (hash):  ~1000 gas per level

Workflow: Code Review with PQC Lens

When reviewing any crypto-touching code:

  1. Identify all crypto primitives (hashes, signatures, keys, RNG)
  2. Check quantum retirement dates (use timeline table above)
  3. Assess immutability (can crypto be changed post-deployment?)
  4. Recommend version tracking (enum or uint8 to distinguish algorithms)
  5. Sketch PQC roadmap (when/how to migrate, phased or co-exist?)
  6. Flag unsalvageable decisions (immutable hashes = locked forever)

Example Critique:

code
Code: CronosSettlementAnchor.sol, _verifyProof()

Current State:
  ✅ Uses Keccak-256 (not ECDSA, so signature breakage not a risk)
  ⚠️  Merkle root stored immutably
  ⚠️  No version on proof format; can't distinguish future PQC proofs

Recommendation:
  - Phase 2.B: Add second root storage for SHA-3-256 (dual-tree)
  - Require both Keccak + SHA-3 verification (AND gate)
  - Add `proofVersion` enum to distinguish proof types
  - Design gov-controlled migration: maintain Keccak for legacy, add SPHINCS+ for new

Timeline:
  - Immediate (2-3 weeks): Dual storage + version tracking
  - Phase 2.C: Implement SHA-3 dual verification
  - Phase 3+: Governance migration plan to SPHINCS+

When to Escalate

Escalate to Post-Quantum Cryptography Specialist if:

  • New signature scheme is proposed (ECDSA, BLS, etc.)
  • Immutable crypto parameters discovered
  • Multi-signature or threshold crypto needed
  • Off-chain → on-chain proof migration required
  • Contract upgrade prevents future crypto migration

References