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
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 |
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 Type | Pubkey Exposed? | Quantum Status | Notes |
| 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
bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) {
secp256k1_ecdsa_signature sig;
int ret = secp256k1_ecdsa_sign(
secp256k1_context_sign, &sig,
hash.begin(), begin(),
secp256k1_nonce_function_rfc6979, NULL
);
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.
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;
uint256 anchor;
uint256 nullifier;
uint256 rk;
GrothProof zkproof;
sig_t spendAuthSig;
};
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;
G2 pi_B;
G1 pi_C;
};
Shor's algorithm breaks:
- The Discrete Logarithm in G1 (254-bit)
- The Discrete Logarithm in G2 (254-bit over Fq2)
- The Computational Diffie-Hellman in GT (target group)
- The Bilinear Diffie-Hellman assumption (BDH)
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
// 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
typedef IncrementalMerkleTree<29, SHA256Compress> SproutMerkleTree;
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
void KDF_Sapling(
unsigned char K[32],
const uint256 &dhsecret,
const uint256 &epk
) {
}
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
Value Commit
AMOUNTS LEAKED
Nullifier Key
GRAPH DEANON
Sprout Legacy (PHGR13)
| Component | Primitive | Quantum Status |
| PHGR13 proof (7xG1+1xG2 = 296B) | BN254 pairing | BROKEN |
| JoinSplit signature | Ed25519 variant | BROKEN |
| Note commitment (cm) | SHA256 | SAFE |
| Merkle tree (depth 29) | SHA256Compress | SAFE |
| Key agreement | Curve25519 ECDH | BROKEN |
| PRF functions | SHA256 (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
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
Quantum Impact:
Grover's speedup for collision finding: ~4x
Effective security: ~128-bit (from 256-bit)
Difficulty adjustment: SELF-CORRECTING (recalibrates automatically)
Network Layer
| Component | Current State | Quantum Relevance |
| Peer-to-peer transport | Plaintext TCP (no TLS) | Already broken classically |
| Tor v3 transport | AES-256 + Curve25519 | AES SAFE; Curve25519 BROKEN |
| DNS seeds | No DNSSEC | Already broken classically |
| Peer authentication | IP-based only | No crypto to break |
| Message integrity | SHA256d checksum (4 bytes) | Corruption detection only |
| # | Vulnerability | Impact | Detectability | Severity |
| 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.
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:
| Primitive | Current Size | PQC Replacement | New Size | Bloat |
| 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
static const unsigned int MAX_BLOCK_SIZE = 200000;
static const unsigned int MAX_TX_SIZE_AFTER_SAPLING = 102000;
// EXCEEDS MAX_TX_SIZE (102 KB) AND NEARLY MAX_BLOCK_SIZE (200 KB)
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
Advantages for PQC Migration
| Advantage | Detail |
| Small chain | Lower total UTXO set makes migration tractable |
| Sapling exists | Shielded infrastructure in place; "only" swap primitives |
| BLAKE2b available | Via libsodium; quantum-safe hash already linked and tested |
| Rust integration | Via librustzcash; modern PQC libraries (Rust-native) integrate naturally |
| Sprout precedent | SHA256Compress Merkle tree proves hash-based commitment pattern works |
| Agile governance | Small community = faster consensus on protocol upgrades |
Disadvantages
| Disadvantage | Detail |
| No SegWit | Cannot use Bitcoin's witness versioning; must use TX version bumps |
| 200 KB block limit | PQC proofs force 10-50x increase; bandwidth/storage/sync impact |
| Groth16 deeply embedded | Proof system touches every Sapling TX; replacement = circuit rewrite |
| Dual codebase | Critical crypto in both C++ and Rust (librustzcash); PQC changes hit both |
| No upstream PQC | Zcash itself hasn't implemented PQC; Zclassic can't inherit the work |
| Trusted setup | Groth16 CRS ceremony; migration to STARKs eliminates this but is massive |
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:
- "Harvest now, decrypt later" attacks mean encrypted data captured today is broken retroactively
- Every shielded transaction on-chain is a future target for deanonymization
- Migration takes years; starting late means exposure during the transition window
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.
| Component | File | Key Lines |
| Private key ops | src/key.h, src/key.cpp | Sign(): 201-214, MakeNewKey(): 159-165 |
| Public key verify | src/pubkey.h, src/pubkey.cpp | Verify(): 18-37, GetID(): 150-154 |
| Groth16 proofs | src/zcash/Proof.hpp | PHGRProof: 179-236, GrothProof size: 18-23 |
| JoinSplit circuit | src/zcash/JoinSplit.hpp | GROTH_PROOF_SIZE: 18-23 |
| Note encryption | src/zcash/NoteEncryption.hpp/.cpp | KDF_Sapling: 45-68, ChaCha20: 143-148 |
| Sapling addresses | src/zcash/Address.hpp | SaplingPaymentAddress: 105-131 |
| PRF functions | src/zcash/prf.h, prf.cpp | PRF_ask: 27-33, PRF_nsk: 35-41 |
| Merkle trees | src/zcash/IncrementalMerkleTree.hpp | PedersenHash: 232-244, SHA256Compress: 216-230 |
| Transaction struct | src/primitives/transaction.h | SpendDescription: 43-85, OutputDescription: 90-130 |
| ZIP32 HD keys | src/zcash/zip32.h | SaplingExtendedSpendingKey: 98-135 |
| Script interpreter | src/script/interpreter.cpp | OP_CHECKSIG: 660-690, SignatureHash: 1053-1172 |
| Consensus limits | src/consensus/consensus.h | MAX_BLOCK_SIZE: 22, MAX_TX_SIZE: 26-27 |
| Equihash PoW (192,7) | src/crypto/equihash.h/.cpp | InitialiseState: 32-45, Validate: 145-188 |
| Equihash param upgrade | src/consensus/upgrades.cpp | UPGRADE_BUBBLES: lines 78-82 (N=192, K=7) |
| BN254 curve | src/snark/libsnark/.../alt_bn128_init.hpp | Field params: 28-49 |
| Chain params | src/chainparams.cpp | Equihash: 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.