ZCL::QUANTUM_AUDIT//v1.0 SENSITIVE CRYPTOGRAPHIC ANALYSIS 2026-02-12 // ZCLASSIC CORE
01001010101110001010100011101010010101 11010010101001110100101010011101001010 00101011101010010101110100101010101001 10101001010111010010101011101001010100 01010110101001011101001010101110100101 10010101110100101010011101001010101001 01101001010101110100101010111010010101 10100101011101001010100111010010101010 01010101001011101001010101110100101010 10101110100101010011101001010101001010

Zclassic

Quantum Threat Analysis
Full Cryptographic Audit
Project: Zclassic (ZCL) — Zcash Fork, Equihash 192,7 (post-Bubbles)
Scope: All cryptographic primitives across all protocol layers
Threat Model: Cryptographically Relevant Quantum Computer (CRQC)
Classification: Shor's Algorithm (asymmetric) + Grover's Algorithm (symmetric)
Date: 2026-02-12 — Analyst: Claude Opus 4.6
I Cryptographic Attack Surface Map

Every cryptographic primitive in Zclassic is classified under quantum threat into three categories:

Category Definition Quantum Impact Algorithm
BROKEN Relies on integer factorization or discrete log (ECC/pairing) Shor's algorithm solves in polynomial time ECDSA, Schnorr, ECDH, Groth16, Pedersen
WEAKENED Relies on symmetric crypto or hash functions Grover's algorithm provides quadratic speedup (halves bit-security) SHA-256, RIPEMD-160, BLAKE2b
SAFE Sufficiently large symmetric primitives, information-theoretic No known quantum advantage beyond Grover ChaCha20-Poly1305-IETF, AES-256, BLAKE2b-512

Complete Primitive Inventory

Component Primitive Size Layer Status
Transaction signing ECDSA / secp256k1 ~72B DER sig Transparent BROKEN
Public key secp256k1 point 33B compressed Transparent BROKEN
Address hashing RIPEMD160(SHA256(pk)) 20B Transparent SAFE
HD key derivation HMAC-SHA512 + EC tweak 64B Transparent BROKEN
Spend authorization Jubjub Schnorr 64B sig Sapling BROKEN
Zero-knowledge proofs Groth16 / BN254 192B Sapling BROKEN
Value commitments Pedersen / Jubjub 32B Sapling BROKEN
Note commitments PedersenHash / Jubjub 32B Sapling BROKEN
Merkle tree (Sapling) PedersenHash 32B per node Sapling BROKEN
Key agreement Curve25519 ECDH 32B shared secret Sapling BROKEN
Note encryption ChaCha20-Poly1305-IETF 580B ciphertext Sapling SAFE
Binding signature Jubjub Schnorr 64B Sapling BROKEN
Nullifier derivation PRF + Jubjub nk 32B Sapling BROKEN
Sprout proofs PHGR13 / BN254 296B (7xG1+1xG2) Sprout BROKEN
Merkle tree (Sprout) SHA256Compress 32B per node Sprout SAFE
Signature hash BLAKE2b (personalized) 32B Consensus SAFE
Proof-of-Work Equihash(192,7) / BLAKE2b 400B solution Mining WEAKENED
Network transport Plaintext TCP Network NO CRYPTO
II Transparent Layer // secp256k1 ECDSA

Attack Vector: Shor's Algorithm on ECDLP

The entire transparent transaction system rests on the hardness of the Elliptic Curve Discrete Logarithm Problem on secp256k1. Shor's algorithm inverts this in polynomial time.

Private Key (k) ——[EC point multiplication]——> Public Key (K = k*G) [CLASSICAL] One-way function. Computationally infeasible to reverse. [QUANTUM] Shor's algorithm: ~2330 logical qubits. O(256^3) gate ops. TRIVIALLY REVERSIBLE.

Key Derivation Chain

Private Key 32 bytes, random scalar on secp256k1 | v secp256k1_ec_pubkey_create() [QUANTUM VULNERABLE] | Public Key 33 bytes compressed (0x02/0x03 + X) | v RIPEMD160(SHA256(pubkey)) [QUANTUM SAFE] | CKeyID 20 bytes (160-bit hash) | v Base58Check(version + CKeyID) [ENCODING ONLY] | Address "t1..." alphanumeric string

Vulnerability by Output Type

Output TypePubkey Exposed?Quantum StatusNotes
P2PKH (never spent from) No — hidden behind HASH160 SAFE Pubkey not on-chain until first spend
P2PKH (has sent a TX) Yes — scriptSig contains pubkey BROKEN Pubkey permanently on-chain after first spend
P2PK Yes — pubkey in scriptPubKey BROKEN Permanently exposed since output creation
P2SH No — hidden behind HASH160 SAFE Until redeemScript is revealed
P2MS (multisig) Yes — pubkeys in scriptPubKey BROKEN All pubkeys exposed at creation

ECDSA Signature Flow

// QUANTUM VULNERABLE: ECDSA signing with secp256k1 bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) { secp256k1_ecdsa_signature sig; // RFC-6979 deterministic nonce (safe classically, irrelevant quantumly) int ret = secp256k1_ecdsa_sign( secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, NULL // <-- Shor's ignores nonce ); secp256k1_ecdsa_signature_serialize_der(...); return true; }
A quantum adversary who obtains any public key from the chain (from a spent P2PKH scriptSig, or any P2PK output) can recover the private key via Shor's algorithm in O(256³) quantum gates using ~2330 logical qubits. This enables theft of all UTXOs controlled by that key.
III Sapling Shielded Layer // Six Fatal Vectors

The Sapling shielded transaction system is the most complex and most vulnerable layer. It contains six independent quantum-vulnerable components, any one of which is sufficient to break the system.

3a. Spend Authorization — Jubjub Schnorr Signatures

SpendDescription { uint256 cv; // 32B value commitment [Jubjub Pedersen] uint256 anchor; // 32B Merkle root [PedersenHash] uint256 nullifier; // 32B nullifier [PRF + Jubjub nk] uint256 rk; // 32B randomized public key [EXPOSED ON-CHAIN] GrothProof zkproof; // 192B Groth16 proof [BN254 pairing] sig_t spendAuthSig; // 64B Schnorr signature [Jubjub curve] }; // TOTAL: ~544 bytes per Sapling spend
ask (spending secret) ——[Jubjub scalar mult]——> ak (spend auth key) | v randomize with alpha | rk = ak + alpha*G [Published in every SpendDescription on-chain] | v Shor's algorithm on Jubjub (~253-bit curve) | RECOVERED: randomized secret key ——> FORGE spend authorization
Unlike transparent P2PKH where the pubkey is hidden until spend, every Sapling spend publishes rk permanently on-chain. All historical shielded spends are retroactively vulnerable to quantum key recovery.

3b. Groth16 Zero-Knowledge Proofs — BN254 Pairing

GrothProof = { G1 pi_A; // 48 bytes — BN254 base curve point G2 pi_B; // 96 bytes — BN254 twist curve point G1 pi_C; // 48 bytes — BN254 base curve point }; // TOTAL: 192 bytes // Verification: e(pi_A, pi_B) = e(alpha, beta) * e(L, gamma) * e(pi_C, delta) // where e: G1 x G2 -> GT is a bilinear map on BN254 (254-bit)

Shor's algorithm breaks:

A quantum adversary can extract the toxic waste (trapdoor) from the Common Reference String, then forge arbitrary proofs for false statements — including proofs that create shielded ZCL from nothing. This enables silent, undetectable, unlimited supply inflation. This is the single most catastrophic quantum vulnerability in Zclassic.

3c. Value Commitments — Pedersen on Jubjub

cv = v * G_value + rcv * G_random // Pedersen commitment on Jubjub // v = transaction value (hidden) // rcv = commitment randomness (hidden) // G_value, G_random = fixed Jubjub generators // QUANTUM ATTACK: Shor's on Jubjub recovers v and rcv from cv // RESULT: All historical transaction amounts become public

3d. Note Commitment Merkle Tree — PedersenHash

// SPROUT: Uses SHA256Compress — QUANTUM SAFE typedef IncrementalMerkleTree<29, SHA256Compress> SproutMerkleTree; // SAPLING: Uses PedersenHash — QUANTUM BROKEN (ECC-based hash) typedef IncrementalMerkleTree<32, PedersenHash> SaplingMerkleTree;
The Sapling Merkle tree uses PedersenHash (an elliptic-curve-based hash on Jubjub) instead of a classical hash function. This is a quantum regression from Sprout, which correctly used SHA256Compress. Shor's algorithm breaks PedersenHash collision resistance, compromising the entire commitment tree integrity.

3e. Nullifier Derivation — Jubjub nk

nsk (nullifier secret) ——[Jubjub scalar mult]——> nk (nullifier key) | v PRF_nf(nk, rho) = nullifier | Recovery of nsk from nk via Shor's allows: - Linking nullifiers to specific notes - Deanonymizing the entire shielded transaction graph - Complete destruction of Sapling privacy

3f. Ephemeral Key Agreement — Curve25519 / Jubjub ECDH

// Key Derivation Function for Sapling note encryption void KDF_Sapling( unsigned char K[32], // Output: 256-bit symmetric key const uint256 &dhsecret, // Input: ECDH shared secret [BROKEN] const uint256 &epk // Input: ephemeral public key ) { // BLAKE2b with personalization "Zcash_SaplingKDF" // Symmetric key is SAFE, but derived from BROKEN ECDH } // Encryption uses ChaCha20-Poly1305-IETF (QUANTUM SAFE cipher) // BUT: key agreement is Curve25519 ECDH (QUANTUM BROKEN) // NET RESULT: All encrypted notes are retroactively decryptable
Every OutputDescription published on-chain contains an ephemeralKey (Jubjub point). A quantum adversary recovers the ephemeral secret key via Shor's, computes the ECDH shared secret, derives the symmetric key, and decrypts all historical encrypted notes — revealing recipient, amount, and memo for every shielded transaction ever made. ChaCha20-Poly1305-IETF is quantum-safe, but its key derivation is not. The entire privacy guarantee collapses.

Sapling Vulnerability Heat Map

Proof Forgery
EXISTENTIAL
Spend Auth
TOTAL THEFT
ECDH Decrypt
FULL DEANON
Value Commit
AMOUNTS LEAKED
Nullifier Key
GRAPH DEANON
Merkle Tree
INTEGRITY
Note Encrypt
CIPHER SAFE
IV Sprout Layer + Proof-of-Work + Network

Sprout Legacy (PHGR13)

ComponentPrimitiveQuantum Status
PHGR13 proof (7xG1+1xG2 = 296B)BN254 pairingBROKEN
JoinSplit signatureEd25519 variantBROKEN
Note commitment (cm)SHA256SAFE
Merkle tree (depth 29)SHA256CompressSAFE
Key agreementCurve25519 ECDHBROKEN
PRF functionsSHA256 (no-padding)SAFE
Sprout has a mixed quantum profile. Its hash-based components (commitments, Merkle tree, PRFs) are quantum-safe. This demonstrates the correct design pattern that Sapling should have followed for its Merkle tree.

Equihash Proof-of-Work

// Personalization: "ZcashPoW" + N(LE32) + K(LE32) // Hash: BLAKE2b (libsodium) // IMPORTANT: Equihash params changed at UPGRADE_BUBBLES (block 585,318) Genesis — Block 585,317 (historical): N = 200 K = 9 CollisionBitLength = N/(K+1) = 20 bits SolutionWidth = 1344 bytes Memory requirement: ~700 MB Block 585,318+ (CURRENT — post-Bubbles upgrade): N = 192 K = 7 CollisionBitLength = N/(K+1) = 24 bits SolutionWidth = 400 bytes Memory requirement: ~2-4 GB // Source: src/consensus/upgrades.cpp lines 78-82 // UPGRADE_BUBBLES: { N = 192, K = 7 } // Source: src/chainparams.cpp line 113 // UPGRADE_BUBBLES activation height = 585318 Quantum Impact: Grover's speedup for collision finding: ~4x Effective security: ~128-bit (from 256-bit) Difficulty adjustment: SELF-CORRECTING (recalibrates automatically)
Equihash PoW
LOW RISK

Network Layer

ComponentCurrent StateQuantum Relevance
Peer-to-peer transportPlaintext TCP (no TLS)Already broken classically
Tor v3 transportAES-256 + Curve25519AES SAFE; Curve25519 BROKEN
DNS seedsNo DNSSECAlready broken classically
Peer authenticationIP-based onlyNo crypto to break
Message integritySHA256d checksum (4 bytes)Corruption detection only
V Severity Ranking // Impact Assessment
#VulnerabilityImpactDetectabilitySeverity
1 Groth16 proof forgery (BN254) Unlimited supply inflation in shielded pool UNDETECTABLE EXISTENTIAL
2 Sapling spend auth forgery (Jubjub) Theft of all shielded funds Detectable (double-spend attempts) CRITICAL
3 Value commitment breaking (Pedersen) Full deanonymization of all amounts PASSIVE — NO TRACE CRITICAL
4 Nullifier key recovery (Jubjub nk) Complete transaction graph deanonymization PASSIVE — NO TRACE CRITICAL
5 ECDH key recovery (Curve25519) Decryption of all encrypted memos and notes PASSIVE — NO TRACE CRITICAL
6 ECDSA key recovery (secp256k1) Theft of transparent funds w/ exposed pubkeys Detectable (unauthorized spends) HIGH
7 PedersenHash Merkle collision Merkle tree integrity compromise Complex to exploit at scale HIGH
8 Equihash mining advantage ~4x mining speedup Self-correcting via difficulty LOW
Vulnerabilities #3, #4, and #5 are passive attacks. A quantum adversary can deanonymize the entire historical shielded transaction graph without making any on-chain transactions. There is no way to detect or prevent this after the fact. Every shielded transaction already recorded on the blockchain is a future target. This is the "harvest now, decrypt later" scenario made real.
VI Post-Quantum Replacement Map

Primitive-Level Replacement

CURRENT PRIMITIVE POST-QUANTUM REPLACEMENT ======================================================================== ECDSA (secp256k1) ---> ML-DSA-65 (FIPS 204 / Dilithium3) Jubjub Schnorr signatures ---> ML-DSA-65 or SLH-DSA (SPHINCS+) Groth16 proofs (BN254) ---> STARKs (hash-based, transparent) Pedersen commitments (Jubjub) ---> SHA3-256 or BLAKE3 commitments PedersenHash (Merkle tree) ---> SHA256 or BLAKE2b (a la Sprout) Curve25519 ECDH ---> ML-KEM-768 (FIPS 203 / Kyber) BIP32 HD derivation (EC) ---> XMSS or hash-based HD scheme

Size Impact Analysis

The engineering reality of post-quantum cryptography — everything gets much larger:

PrimitiveCurrent SizePQC ReplacementNew SizeBloat
ECDSA signature 72 bytes ML-DSA-65 (Dilithium3) 3,293 bytes 46x
ECDSA signature 72 bytes SLH-DSA-128s (SPHINCS+) 7,856 bytes 109x
secp256k1 pubkey 33 bytes ML-DSA-65 pubkey 1,952 bytes 59x
Groth16 proof 192 bytes STARK proof 45,000 – 200,000 bytes 230-1000x
Groth16 proof 192 bytes Lattice-SNARK 50,000 – 100,000 bytes 260-520x
Pedersen commitment 32 bytes SHA3-256 commitment 32 bytes 1x
Curve25519 DH pubkey 32 bytes ML-KEM-768 encaps key 1,184 bytes 37x
Curve25519 ciphertext 32 bytes ML-KEM-768 ciphertext 1,088 bytes 34x

Block/TX Size Constraint Analysis

// CURRENT LIMITS static const unsigned int MAX_BLOCK_SIZE = 200000; // 200 KB static const unsigned int MAX_TX_SIZE_AFTER_SAPLING = 102000; // 102 KB // POST-QUANTUM SAPLING TX ESTIMATE (2 spends + 2 outputs) // Current: 2 * 544 + 2 * 1120 = ~3.3 KB // ML-DSA: 2 * (3293 + 45000) + 2 * (1184 + 45000) = ~188.9 KB // ^^^^^^^^^ // EXCEEDS MAX_TX_SIZE (102 KB) AND NEARLY MAX_BLOCK_SIZE (200 KB) // REQUIRED NEW LIMITS (minimum): // MAX_TX_SIZE = 500,000 (500 KB) // MAX_BLOCK_SIZE = 5,000,000 (5 MB)
VII Strategic Migration Roadmap
Phase 0 — Immediate Risk Mitigation
No Consensus Changes Required
Effort: Low | Impact: High | Fork: None
  • Default wallet to shielded (z-addr) sends — minimize transparent pubkey exposure
  • Address reuse detection — warn when receiving to address with on-chain pubkey
  • UTXO migration tooling — help users consolidate to fresh never-spent addresses
  • Publish quantum risk documentation for each output type
  • Inventory all exposed public keys in the UTXO set — quantify at-risk ZCL
Phase 1 — Hash-Based Transparent Hardening
New TX_HASH_LOCKED Output Type
Effort: Moderate | Impact: Medium | Fork: Soft Fork (TX v5)
  • New output type: TX_MERKLEROOT — commit to script tree hash, not public key
  • Public key only revealed at spend time (short exposure window)
  • Tagged hashing with BLAKE2b (already available via libsodium)
  • No SegWit dependency — adapted for Zclassic's native script system
Phase 2 — Sapling Merkle Tree Migration
Replace PedersenHash with BLAKE2b
Effort: Moderate | Impact: High | Fork: Hard Fork
  • Replace quantum-vulnerable PedersenHash with BLAKE2b or SHA256 for the note commitment tree
  • Maintain depth-32 tree (same 232 note capacity)
  • Dual-tree transition: run old + new Merkle trees during migration window
  • Users migrate shielded notes from old tree to new tree before cutoff
  • Lowest effort, highest value change — Sprout already proves this pattern works
Phase 3 — Post-Quantum Key Exchange
Replace ECDH with ML-KEM (Kyber)
Effort: High | Impact: High | Fork: Hard Fork
  • Replace Curve25519/Jubjub ECDH in OutputDescription with ML-KEM-768
  • Adapt KDF_Sapling: inputs change from ECDH secret to KEM shared secret
  • OutputDescription grows ~1 KB per output (ML-KEM-768 ciphertext)
  • Old notes remain decryptable; new notes use PQC key exchange
  • Protects forward secrecy — even with classical signatures, eavesdroppers can't decrypt
Phase 4 — Post-Quantum Signatures
Replace ECDSA + Jubjub Schnorr with ML-DSA
Effort: Very High | Impact: Critical | Fork: Hard Fork
  • Transparent: Replace ECDSA with ML-DSA-65 (pubkey: 1952B, sig: 3293B)
  • Sapling spend auth: Replace Jubjub Schnorr with ML-DSA
  • Binding signature: Replace Jubjub binding sig with ML-DSA
  • Increase MAX_TX_SIZE to 500+ KB, MAX_BLOCK_SIZE to 5+ MB
  • Option: hybrid ECDSA+ML-DSA dual signatures during transition period
Phase 5 — Post-Quantum Proof System
Replace Groth16/BN254 with Hash-Based Proofs
Effort: Extreme | Impact: Existential | Fork: Hard Fork
  • Recommended: STARKs — hash-based, no trusted setup, quantum-resistant
  • Proof size: ~45-200 KB (vs 192 bytes) — verification ~10-100x slower
  • Eliminates the toxic waste / trusted setup ceremony simultaneously
  • Alternative: Lattice-based SNARKs (~50-100 KB, faster, but less mature)
  • Reject: Bulletproofs+ (still based on discrete log — not quantum-safe)
  • Complete circuit rewrite required — largest engineering effort of all phases
VIII Zclassic Position Assessment

Advantages for PQC Migration

AdvantageDetail
Small chainLower total UTXO set makes migration tractable
Sapling existsShielded infrastructure in place; "only" swap primitives
BLAKE2b availableVia libsodium; quantum-safe hash already linked and tested
Rust integrationVia librustzcash; modern PQC libraries (Rust-native) integrate naturally
Sprout precedentSHA256Compress Merkle tree proves hash-based commitment pattern works
Agile governanceSmall community = faster consensus on protocol upgrades

Disadvantages

DisadvantageDetail
No SegWitCannot use Bitcoin's witness versioning; must use TX version bumps
200 KB block limitPQC proofs force 10-50x increase; bandwidth/storage/sync impact
Groth16 deeply embeddedProof system touches every Sapling TX; replacement = circuit rewrite
Dual codebaseCritical crypto in both C++ and Rust (librustzcash); PQC changes hit both
No upstream PQCZcash itself hasn't implemented PQC; Zclassic can't inherit the work
Trusted setupGroth16 CRS ceremony; migration to STARKs eliminates this but is massive
IX Executive Summary
A Cryptographically Relevant Quantum Computer (CRQC) breaks every authentication and privacy mechanism in Zclassic's Sapling layer simultaneously. The most dangerous attack is silent supply inflation via forged Groth16 proofs — undetectable, unlimited, and irreversible.

The Timeline

Conservative estimates place CRQC at 2035-2045. However:

Priority Matrix

URGENCY COMPONENT REPLACEMENT ============================================================================ NOW User education + tooling No code changes needed HIGH PedersenHash Merkle tree BLAKE2b / SHA256 HIGH ECDH key agreement ML-KEM (Kyber) MEDIUM ECDSA / Schnorr signatures ML-DSA (Dilithium) CRITICAL Groth16 proof system STARKs (hash-based) LOW Equihash PoW No change needed

The Bottom Line

Zclassic's shielded pool is a ticking cryptographic time bomb under quantum threat. Not because the symmetric crypto fails, but because every single authentication, commitment, and proof primitive relies on elliptic curve hardness assumptions that Shor's algorithm destroys.

The Groth16 vulnerability is existential: it enables undetectable counterfeiting. The passive deanonymization attacks (value commitments, nullifier keys, ECDH) mean historical privacy is retroactively destroyed the moment a CRQC exists.

The migration path exists but requires sustained, multi-year engineering effort with significant block size and transaction format changes. Starting Phase 0 and Phase 1 immediately is the minimum responsible action.

A Appendix // Critical File Reference
ComponentFileKey Lines
Private key opssrc/key.h, src/key.cppSign(): 201-214, MakeNewKey(): 159-165
Public key verifysrc/pubkey.h, src/pubkey.cppVerify(): 18-37, GetID(): 150-154
Groth16 proofssrc/zcash/Proof.hppPHGRProof: 179-236, GrothProof size: 18-23
JoinSplit circuitsrc/zcash/JoinSplit.hppGROTH_PROOF_SIZE: 18-23
Note encryptionsrc/zcash/NoteEncryption.hpp/.cppKDF_Sapling: 45-68, ChaCha20: 143-148
Sapling addressessrc/zcash/Address.hppSaplingPaymentAddress: 105-131
PRF functionssrc/zcash/prf.h, prf.cppPRF_ask: 27-33, PRF_nsk: 35-41
Merkle treessrc/zcash/IncrementalMerkleTree.hppPedersenHash: 232-244, SHA256Compress: 216-230
Transaction structsrc/primitives/transaction.hSpendDescription: 43-85, OutputDescription: 90-130
ZIP32 HD keyssrc/zcash/zip32.hSaplingExtendedSpendingKey: 98-135
Script interpretersrc/script/interpreter.cppOP_CHECKSIG: 660-690, SignatureHash: 1053-1172
Consensus limitssrc/consensus/consensus.hMAX_BLOCK_SIZE: 22, MAX_TX_SIZE: 26-27
Equihash PoW (192,7)src/crypto/equihash.h/.cppInitialiseState: 32-45, Validate: 145-188
Equihash param upgradesrc/consensus/upgrades.cppUPGRADE_BUBBLES: lines 78-82 (N=192, K=7)
BN254 curvesrc/snark/libsnark/.../alt_bn128_init.hppField params: 28-49
Chain paramssrc/chainparams.cppEquihash: 133, upgrades: 101-116

This document is provided strictly for educational and informational purposes only. It does not constitute financial, investment, or professional security advice.

This analysis is AI-assisted and may contain errors, inaccuracies, omissions, or outdated information. It has not been formally peer-reviewed or audited by a certified third party. This is not a professional security audit, penetration test, or formal verification.

The authors and contributors accept no responsibility or liability for any loss, damage, or consequence arising from the use of, or reliance on, any information presented. Cryptocurrency is inherently risky and may lose all value. Always do your own research (DYOR).

References to third-party projects, algorithms, or standards (NIST FIPS 203/204/205) are for informational context only and do not imply endorsement or affiliation.

Licensed under MIT License. Corrections and peer review welcome via GitHub.