diff --git a/src/blockchain/blockchain-and-crypto-currencies/README.md b/src/blockchain/blockchain-and-crypto-currencies/README.md index d3625c3480e..4923afcb988 100644 --- a/src/blockchain/blockchain-and-crypto-currencies/README.md +++ b/src/blockchain/blockchain-and-crypto-currencies/README.md @@ -210,14 +210,76 @@ erc-4337-smart-account-security-pitfalls.md ../smart-contract-security/mutation-testing-with-slither.md {{#endref}} -## References +## ZK Proof / zkVM Guest Integrity -- [https://en.wikipedia.org/wiki/Proof_of_stake](https://en.wikipedia.org/wiki/Proof_of_stake) -- [https://www.mycryptopedia.com/public-key-private-key-explained/](https://www.mycryptopedia.com/public-key-private-key-explained/) -- [https://bitcoin.stackexchange.com/questions/3718/what-are-multi-signature-transactions](https://bitcoin.stackexchange.com/questions/3718/what-are-multi-signature-transactions) -- [https://ethereum.org/en/developers/docs/transactions/](https://ethereum.org/en/developers/docs/transactions/) -- [https://ethereum.org/en/developers/docs/gas/](https://ethereum.org/en/developers/docs/gas/) -- [https://en.bitcoin.it/wiki/Privacy](https://en.bitcoin.it/wiki/Privacy#Forced_address_reuse) +When a prover uses a **zkVM** or an application-specific proof circuit to attest a claim, the verifier is only learning that the **guest program executed as written**. If the guest contains **unsafe deserialization**, **undefined behavior**, or **missing semantic constraints**, a malicious prover may generate a proof that verifies while the **public metrics or claimed invariant are false**. + +### Unsafe deserialization inside proof guests + +- Treat private witness/circuit bytes as **untrusted attacker input** even if they are hidden by the proof. +- Avoid deserializing them with unchecked helpers such as `rkyv::access_unchecked` unless the bytes were already validated out-of-band. +- Enum discriminants, relative pointers, lengths, and indexes loaded from untrusted serialized data must be validated before they influence control flow or memory access. + +Practical audit pattern: + +```rust +let private_circuit_bytes = sp1_zkvm::io::read_vec(); +let ops = unsafe { + rkyv::access_unchecked::>>(&private_circuit_bytes) +}; +``` + +If a field such as `op.kind` is an enum and an attacker can inject an **out-of-range discriminant**, every downstream `match` on that value becomes suspicious. + +### Jump-table / UB counter bypass + +If Rust lowers a large `match` into a **jump table**, an invalid enum discriminant may produce **undefined control flow**. A dangerous pattern is: + +1. One `match` updates **security-critical counters/constraints**. +2. A second `match` performs the **real instruction semantics**. +3. An out-of-range discriminant indexes past the first jump table and lands in code associated with the second one. + +Result: the operation still executes, but the accounting path is skipped. In a zkVM this can forge proofs that report impossible metrics such as fewer gates, fewer expensive operations, or other falsified bounded resources. + +Review checklist: + +- Look for attacker-controlled enums deserialized from witness/private input. +- Inspect repeated `match` statements over the same opcode/kind field. +- Treat `unsafe` + unchecked deserialization + large opcode dispatch as a high-risk combination. +- Reverse engineer the emitted binary when needed; jump-table layout can matter more than the source. + +### Missing semantic constraints in reversible/specialized interpreters + +Do not just validate memory safety; also validate the **semantic rules** that the proof is meant to enforce. + +For reversible/quantum-like instruction sets, ensure operands that must be distinct are actually constrained to be distinct. A Toffoli/CCX-like operation implemented as: + +```rust +let v = cond & self.qubit(op.q_control1) & self.qubit(op.q_control2); +*self.qubit_mut(op.q_target) ^= v; +``` + +becomes unsafe if the guest does not reject: + +```text +op.q_control1 == op.q_control2 == op.q_target +``` + +In that case the transition collapses into: + +```text +q = q ^ (q & q) = 0 +``` + +This creates a **deterministic reset primitive**, breaking reversibility assumptions and enabling cheaper non-intended computations. In proof systems that attest resource usage, this can let attackers satisfy functional checks while bypassing the cost model the verifier believes is being enforced. + +### What to test in ZK systems + +- Fuzz all guest parsers with malformed witness/private-input encodings. +- Assert enum range validation before opcode dispatch. +- Add semantic checks for operand aliasing and other invalid instruction forms. +- Compare reported/public counters against an independent reference implementation. +- Remember that a valid proof can still prove the **wrong statement** if the guest program is buggy. ## DeFi/AMM Exploitation @@ -233,6 +295,16 @@ For multi-asset weighted pools that cache virtual balances and can be poisoned w defi-amm-virtual-balance-cache-exploitation.md {{#endref}} -{{#include ../../banners/hacktricks-training.md}} +## References +- [https://en.wikipedia.org/wiki/Proof_of_stake](https://en.wikipedia.org/wiki/Proof_of_stake) +- [https://www.mycryptopedia.com/public-key-private-key-explained/](https://www.mycryptopedia.com/public-key-private-key-explained/) +- [https://bitcoin.stackexchange.com/questions/3718/what-are-multi-signature-transactions](https://bitcoin.stackexchange.com/questions/3718/what-are-multi-signature-transactions) +- [https://ethereum.org/en/developers/docs/transactions/](https://ethereum.org/en/developers/docs/transactions/) +- [https://ethereum.org/en/developers/docs/gas/](https://ethereum.org/en/developers/docs/gas/) +- [https://en.bitcoin.it/wiki/Privacy](https://en.bitcoin.it/wiki/Privacy#Forced_address_reuse) +- [Trail of Bits - We beat Google's zero-knowledge proof of quantum cryptanalysis](https://blog.trailofbits.com/2026/04/17/we-beat-googles-zero-knowledge-proof-of-quantum-cryptanalysis/) +- [Google patched paper version](https://arxiv.org/abs/2603.28846v2) +- [Trail of Bits proof-of-concept repository](https://github.com/trailofbits/quantum-zk-proof-poc) +{{#include ../../banners/hacktricks-training.md}}