Zcash Protocol Specification Version 2021.1.16 [Overwinter+Sapling+Blossom+Heartwood+Canopy] Daira Hopwood † Sean Bowe † — Taylor Hornby † — Nathan Wilcox † January 11, 2021 1 Abstract. Zcash is an implementation of the Decentralized Anonymous Payment scheme Zerocash, with security fixes and improvements to performance and functionality. It bridges the existing transparent payment scheme used by Bitcoin with a shielded payment scheme secured by zero-knowledge succinct non-interactive arguments of knowledge (zk-SNARKs). It attempted to address the problem of mining centralization by use of the Equihash memory-hard proof-of-work algorithm. This specification defines the Zcash consensus protocol at launch, and after each of the upgrades codenamed Overwinter, Sapling, Blossom, Heartwood, and Canopy. It is a work in progress. Protocol differences from Zerocash and Bitcoin are also explained. Keywords: anonymity, applications, cryptographic protocols, electronic commerce and payment, financial privacy, proof of work, zero knowledge. Contents 1 1 Introduction 7 1.1 Caution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.2 High-level Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 † Electric Coin Company 1 Jubjub bird image credit: Peter Newell 1902; Daira Hopwood 2018. 1

2 Notation 9 3 Concepts 12 3.1 Payment Addresses and Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 3.2 Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.2.1 Note Plaintexts and Memo Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3.3 The Block Chain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.4 Transactions and Treestates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.5 JoinSplit Transfers and Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.6 Spend Transfers, Output Transfers, and their Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.7 Note Commitment Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.8 Nullifier Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.9 Block Subsidy, Funding Streams, and Founders’ Reward . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.10 Coinbase Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.11 Mainnet and Testnet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4 Abstract Protocol 19 4.1 Abstract Cryptographic Schemes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.1.1 Hash Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.1.2 Pseudo Random Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.1.3 Symmetric Encryption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.1.4 Key Agreement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.1.5 Key Derivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.1.6 Signature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 4.1.6.1 Signature with Re-Randomizable Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 4.1.6.2 Signature with Signing Key to Validating Key Monomorphism . . . . . . . . . . . . . 24 4.1.7 Commitment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 4.1.8 Represented Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4.1.9 Hash Extractor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4.1.10 Group Hash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.1.11 Represented Pairing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.1.12 Zero-Knowledge Proving System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 4.2 Key Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 4.2.1 Sprout Key Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 4.2.2 Sapling Key Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 4.3 JoinSplit Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4.4 Spend Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.5 Output Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.6 Sending Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 4.6.1 Sending Notes (Sprout) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 4.6.2 Sending Notes (Sapling) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 4.7 Dummy Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4.7.1 Dummy Notes (Sprout) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4.7.2 Dummy Notes (Sapling) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 4.8 Merkle Path Validity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 2

4.9 SIGHASH Transaction Hashing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 4.10 Non-malleability (Sprout) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 4.11 Balance (Sprout) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 4.12 Balance and Binding Signature (Sapling) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 4.13 Spend Authorization Signature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 4.14 Note Commitments and Nullifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 4.15 Zk-SNARK Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 4.15.1 JoinSplit Statement (Sprout) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 4.15.2 Spend Statement (Sapling) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 4.15.3 Output Statement (Sapling) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 4.16 In-band secret distribution (Sprout) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 4.16.1 Encryption (Sprout) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 4.16.2 Decryption (Sprout) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 4.17 In-band secret distribution (Sapling) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 4.17.1 Encryption (Sapling) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 4.17.2 Decryption using an Incoming Viewing Key (Sapling) . . . . . . . . . . . . . . . . . . . . . . . . 48 4.17.3 Decryption using a Full Viewing Key (Sapling) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 4.18 Block Chain Scanning (Sprout) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4.19 Block Chain Scanning (Sapling) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 5 Concrete Protocol 53 5.1 Caution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 5.2 Integers, Bit Sequences, and Endianness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 5.3 Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 5.4 Concrete Cryptographic Schemes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 5.4.1 Hash Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 5.4.1.1 SHA-256, SHA-256d, SHA256Compress, and SHA-512 Hash Functions . . . . . . . . . . 55 5.4.1.2 BLAKE2 Hash Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 5.4.1.3 Merkle Tree Hash Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 5.4.1.4 hSig Hash Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 5.4.1.5 CRHivk Hash Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 5.4.1.6 DiversifyHash Hash Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 5.4.1.7 Pedersen Hash Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 5.4.1.8 Mixing Pedersen Hash Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 5.4.1.9 Equihash Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 5.4.2 Pseudo Random Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 5.4.3 Symmetric Encryption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 5.4.4 Key Agreement And Derivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 5.4.4.1 Sprout Key Agreement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 5.4.4.2 Sprout Key Derivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 5.4.4.3 Sapling Key Agreement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 5.4.4.4 Sapling Key Derivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 5.4.5 Ed25519 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 5.4.6 RedDSA and RedJubjub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 5.4.6.1 Spend Authorization Signature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 3

5.4.6.2 Binding Signature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 5.4.7 Commitment schemes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 5.4.7.1 Sprout Note Commitments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 5.4.7.2 Windowed Pedersen commitments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 5.4.7.3 Homomorphic Pedersen commitments . . . . . . . . . . . . . . . . . . . . . . . . . . 69 5.4.8 Represented Groups and Pairings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 5.4.8.1 BN-254 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 5.4.8.2 BLS12-381 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 5.4.8.3 Jubjub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 5.4.8.4 Hash Extractor for Jubjub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 5.4.8.5 Group Hash into Jubjub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 5.4.9 Zero-Knowledge Proving Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 5.4.9.1 BCTV14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 5.4.9.2 Groth16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 5.5 Encodings of Note Plaintexts and Memo Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 5.6 Encodings of Addresses and Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 5.6.1 Transparent Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 5.6.2 Transparent Private Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 5.6.3 Sprout Payment Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 5.6.4 Sapling Payment Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 5.6.5 Sprout Incoming Viewing Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 5.6.6 Sapling Incoming Viewing Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 5.6.7 Sapling Full Viewing Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 5.6.8 Sprout Spending Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 5.6.9 Sapling Spending Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 5.7 BCTV14 zk-SNARK Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 5.8 Groth16 zk-SNARK Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 5.9 Randomness Beacon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 6 Network Upgrades 83 7 Consensus Changes from Bitcoin 85 7.1 Transaction Encoding and Consensus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 7.2 JoinSplit Description Encoding and Consensus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 7.3 Spend Description Encoding and Consensus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 7.4 Output Description Encoding and Consensus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 7.5 Block Header Encoding and Consensus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 7.6 Proof of Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 7.6.1 Equihash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 7.6.2 Difficulty filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 7.6.3 Difficulty adjustment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 7.6.4 nBits conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 7.6.5 Definition of Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 7.7 Calculation of Block Subsidy, Funding Streams, and Founders’ Reward . . . . . . . . . . . . . . . . . 95 7.8 Payment of Founders’ Reward . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 4

7.9 Payment of Funding Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 7.9.1 ZIP 214 Funding Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 7.10 Changes to the Script System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 7.11 Bitcoin Improvement Proposals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 8 Differences from the Zerocash paper 100 8.1 Transaction Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 8.2 Memo Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 8.3 Unification of Mints and Pours . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 8.4 Faerie Gold attack and fix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 8.5 Internal hash collision attack and fix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 8.6 Changes to PRF inputs and truncation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 8.7 In-band secret distribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 8.8 Omission in Zerocash security proof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 8.9 Miscellaneous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 9 Acknowledgements 106 10 Change History 107 11 References 127 Appendices 137 A Circuit Design 137 A.1 Quadratic Constraint Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 A.2 Elliptic curve background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 A.3 Circuit Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 A.3.1 Operations on individual bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 A.3.1.1 Boolean constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 A.3.1.2 Conditional equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 A.3.1.3 Selection constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 A.3.1.4 Nonzero constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 A.3.1.5 Exclusive-or constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 A.3.2 Operations on multiple bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 A.3.2.1 [Un]packing modulo 𝑟S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 A.3.2.2 Range check . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 A.3.3 Elliptic curve operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 A.3.3.1 Checking that Affine-ctEdwards coordinates are on the curve . . . . . . . . . . . . . 142 A.3.3.2 ctEdwards [de]compression and validation . . . . . . . . . . . . . . . . . . . . . . . . 142 A.3.3.3 ctEdwards ↔ Montgomery conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 A.3.3.4 Affine-Montgomery arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 A.3.3.5 Affine-ctEdwards arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 A.3.3.6 Affine-ctEdwards nonsmall-order check . . . . . . . . . . . . . . . . . . . . . . . . . 145 A.3.3.7 Fixed-base Affine-ctEdwards scalar multiplication . . . . . . . . . . . . . . . . . . . . 145 A.3.3.8 Variable-base Affine-ctEdwards scalar multiplication . . . . . . . . . . . . . . . . . . 146 A.3.3.9 Pedersen hash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 5

A.3.3.10 Mixing Pedersen hash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 A.3.4 Merkle path check . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 A.3.5 Windowed Pedersen Commitment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 A.3.6 Homomorphic Pedersen Commitment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 A.3.7 BLAKE2s hashes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 A.4 The Sapling Spend circuit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 A.5 The Sapling Output circuit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 B Batching Optimizations 157 B.1 RedDSA batch validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 B.2 Groth16 batch verification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 B.3 Ed25519 batch validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 List of Theorems and Lemmata 161 Index 161 6

1 Introduction Zcash is an implementation of the Decentralized Anonymous Payment scheme Zerocash [BCGGMTV2014], with security fixes and improvements to performance and functionality. It bridges the existing transparent payment scheme used by Bitcoin [Nakamoto2008] with a shielded payment scheme secured by zero-knowledge succinct non-interactive arguments of knowledge (zk-SNARKs). Changes from the original Zerocash are explained in § 8 ‘Differences from the Zerocash paper’ on p. 100, and highlighted in magenta throughout the document. Changes specific to the Overwinter upgrade are highlighted in blue. Changes specific to the Sapling upgrade following Overwinter are highlighted in green. Changes specific to the Blossom upgrade following Sapling are highlighted in red. Changes specific to the Heartwood upgrade following Blossom are highlighted in orange. Changes specific to the Canopy upgrade following Heartwood are highlighted in purple. All of these are also changes from Zerocash. The name Sprout is used for the Zcash protocol prior to Sapling (both before and after Overwinter), and in particular its shielded protocol. Technical terms for concepts that play an important rôle in Zcash are written in slanted text . Italics are used for emphasis and for references between sections of the document. The key words MUST, MUST NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this docu- ment are to be interpreted as described in [RFC-2119] when they appear in ALL CAPS. These words may also appear in this document in lower case as plain English words, absent their normative meanings. This specification is structured as follows: • Notation — definitions of notation used throughout the document; • Concepts — the principal abstractions needed to understand the protocol; • Abstract Protocol — a high-level description of the protocol in terms of ideal cryptographic components; • Concrete Protocol — how the functions and encodings of the abstract protocol are instantiated; • Network Upgrades — the strategy for upgrading the Zcash protocol. • Consensus Changes from Bitcoin — how Zcash differs from Bitcoin at the consensus layer, including the Proof of Work; • Differences from the Zerocash protocol — a summary of changes from the protocol in [BCGGMTV2014]. • Appendix: Circuit Design — details of how the Sapling circuit is defined as a quadratic constraint program. • Appendix: Batching Optimizations — improvements to the efficiency of validating multiple signatures and verifying multiple proofs. 1.1 Caution Zcash security depends on consensus. Should a program interacting with the Zcash network diverge from con- sensus, its security will be weakened or destroyed. The cause of the divergence doesn’t matter: it could be a bug in your program, it could be an error in this documentation which you implemented as described, or it could be that you do everything right but other software on the network behaves unexpectedly. The specific cause will not matter to the users of your software whose wealth is lost. Having said that, a specification of intended behaviour is essential for security analysis, understanding of the protocol, and maintenance of Zcash and related software. If you find any mistake in this specification, please file an issue at https://github.com/zcash/zips/issues or contact <[email protected]>. 7

1.2 High-level Overview The following overview is intended to give a concise summary of the ideas behind the protocol, for an audience already familiar with block chain-based cryptocurrencies such as Bitcoin. It is imprecise in some aspects and is not part of the normative protocol specification. This overview applies to both Sprout and Sapling, differences in the cryptographic constructions used notwithstanding. Value in Zcash is either transparent or shielded . Transfers of transparent value work essentially as in Bitcoin and have the same privacy properties. Shielded value is carried by notes 2 , which specify an amount and (indirectly) a shielded payment address, which is a destination to which notes can be sent. As in Bitcoin, this is associated with a private key that can be used to spend notes sent to the address; in Zcash this is called a spending key . To each note there is cryptographically associated a note commitment . Once the transaction creating a note has been mined, the note is associated with a fixed note position in a tree of note commitments, and with a nullifier 2 unique to that note. Computing the nullifier requires the associated private spending key (or the nullifier deriving key for Sapling notes). It is infeasible to correlate the note commitment or note position with the corresponding nullifier without knowledge of at least this key. An unspent valid note, at a given point on the block chain, is one for which the note commitment has been publically revealed on the block chain prior to that point, but the nullifier has not. A transaction can contain transparent inputs, outputs, and scripts, which all work as in Bitcoin [Bitcoin-Protocol]. It also includes JoinSplit descriptions, Spend descriptions, and Output descriptions. Together these describe shielded transfers which take in shielded input notes, and/or produce shielded output notes. (For Sprout, each JoinSplit description handles up to two shielded inputs and up to two shielded outputs. For Sapling, each shielded input or shielded output has its own description.) It is also possible for value to be transferred between the transparent and shielded domains. The nullifiers of the input notes are revealed (preventing them from being spent again) and the commitments of the output notes are revealed (allowing them to be spent in future). A transaction also includes computationally sound zk-SNARK proofs and signatures, which prove that all of the following hold except with insignificant probability: For each shielded input , • [Sapling onward] there is a revealed value commitment to the same value as the input note; • if the value is nonzero, some revealed note commitment exists for this note; • the prover knew the proof authorizing key of the note; • the nullifier and note commitment are computed correctly. and for each shielded output , • [Sapling onward] there is a revealed value commitment to the same value as the output note; • the note commitment is computed correctly; • it is infeasible to cause the nullifier of the output note to collide with the nullifier of any other note. For Sprout, the JoinSplit statement also includes an explicit balance check. For Sapling, the value commitments corresponding to the inputs and outputs are checked to balance (together with any net transparent input or output) outside the zk-SNARK . In addition, various measures (differing between Sprout and Sapling) are used to ensure that the transaction cannot be modified by a party not authorized to do so. Outside the zk-SNARK , it is checked that the nullifiers for the input notes had not already been revealed (i.e. they had not already been spent). 2 In Zerocash [BCGGMTV2014], notes were called “coins”, and nullifiers were called “serial numbers”. 8

A shielded payment address includes a transmission key for a “key-private” asymmetric encryption scheme. Key-private means that ciphertexts do not reveal information about which key they were encrypted to, except to a holder of the corresponding private key , which in this context is called the receiving key . This facility is used to communicate encrypted output notes on the block chain to their intended recipient, who can use the receiving key to scan the block chain for notes addressed to them and then decrypt those notes. In Sapling, for each spending key there is a full viewing key that allows recognizing both incoming and outgoing notes without having spend authority. This is implemented by an additional ciphertext in each Output description. The basis of the privacy properties of Zcash is that when a note is spent, the spender only proves that some commitment for it had been revealed, without revealing which one. This implies that a spent note cannot be linked to the transaction in which it was created. That is, from an adversary’s point of view the set of possibilities for a given note input to a transaction —its note traceability set — includes all previous notes that the adversary does not control or know to have been spent. 3 This contrasts with other proposals for private payment systems, such as CoinJoin [Bitcoin-CoinJoin] or CryptoNote [vanSaberh2014], that are based on mixing of a limited number of transactions and that therefore have smaller note traceability sets. The nullifiers are necessary to prevent double-spending: each note on the block chain only has one valid nullifier , and so attempting to spend a note twice would reveal the nullifier twice, which would cause the second transaction to be rejected. 2 Notation B means the type of bit values, i.e. {0, 1}. BY means the type of byte values, i.e. {0 .. 255}. N means the type of nonnegative integers. N+ means the type of positive integers. Z means the type of integers. Q means the type of rationals. 𝑥 𝑇 is used to specify that 𝑥 has type 𝑇 . A cartesian product type is denoted by 𝑆 × 𝑇 , and a function type by ◦ ◦ 𝑆 → 𝑇 . An argument to a function can determine other argument or result types. R The type of a randomized algorithm is denoted by 𝑆 → 𝑇 . The domain of a randomized algorithm may be (), R indicating that it requires no arguments. Given 𝑓 𝑆 → 𝑇 and 𝑠 𝑆, sampling a variable 𝑥 𝑇 from the output of 𝑓 ◦ ◦ ◦ ◦ ◦ ◦ R applied to 𝑠 is denoted by 𝑥 ← 𝑓 (𝑠). Initial arguments to a function or randomized algorithm may be written as subscripts, e.g. if 𝑥 ◦ ◦ 𝑋, 𝑦 ◦ ◦ 𝑌 , and 𝑓 𝑋 × 𝑌 → 𝑍, then an invocation of 𝑓 (𝑥, 𝑦) can also be written 𝑓𝑥 (𝑦). ◦ ◦ {𝑥 𝑇 | 𝑝𝑥 } means the subset of 𝑥 from 𝑇 for which 𝑝𝑥 (a boolean expression depending on 𝑥) holds. ◦ ◦ 𝑇 ⊆ 𝑈 indicates that 𝑇 is an inclusive subset or subtype of 𝑈 . 𝑆 ∪ 𝑇 means the set union of 𝑆 and 𝑇 . 𝑆 ∩ 𝑇 means the set intersection of 𝑆 and 𝑇 , i.e. {𝑥 𝑆 | 𝑥 ∈ 𝑇 }. ◦ ◦ 𝑆 ∖ 𝑇 means the set difference obtained by removing elements in 𝑇 from 𝑆, i.e. {𝑥 𝑆 | 𝑥 ∈ / 𝑇 }. ◦ ◦ 𝑥 𝑇 ↦→ 𝑒𝑥 𝑈 means the function of type 𝑇 → 𝑈 mapping formal parameter 𝑥 to 𝑒𝑥 (an expression depending ◦ ◦ ◦ ◦ on 𝑥). The types 𝑇 and 𝑈 are always explicit. 𝑥 𝑇 ↦↛∈ 𝑉 𝑒𝑥 𝑈 means 𝑥 𝑇 ↦→ 𝑒𝑥 𝑈 ∪ 𝑉 restricted to the domain {𝑥 𝑇 | 𝑒𝑥 ̸∈ 𝑉 } and range 𝑈 . ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ P 𝑇 means the powerset of 𝑇 . (︀ )︀ 𝑇 [ℓ] , where 𝑇 is a type and ℓ is an integer, means the type of sequences of length ℓ with elements in 𝑇 . For example, B[ℓ] means the set of sequences of ℓ bits, and BY[𝑘] means the set of sequences of 𝑘 bytes. 3 We make this claim only for fully shielded transactions. It does not exclude the possibility that an adversary may use data present in the cleartext of a transaction such as the number of inputs and outputs, or metadata-based heuristics such as timing, to make proba- bilistic inferences about transaction linkage. For consequences of this in the case of partially shielded transactions, see [Peterson2017], [Quesnelle2017], and [KYMM2018]. 9

BY[N] means the type of byte sequences of arbitrary length. length(𝑆) means the length of (number of elements in) 𝑆. truncate𝑘 (𝑆) means the sequence formed from the first 𝑘 elements of 𝑆. 0x followed by a string of monospace hexadecimal digits means the corresponding integer converted from hexadec- imal. [0x00]ℓ means the sequence of ℓ zero bytes. “...” means the given string represented as a sequence of bytes in US-ASCII. For example, “abc” represents the byte sequence [ 0x61, 0x62, 0x63 ]. [0]ℓ means the sequence of ℓ zero bits. [1]ℓ means the sequence of ℓ one bits. 𝑎..𝑏, used as a subscript, means the sequence of values with indices 𝑎 through 𝑏 inclusive. For example, anewpk,1..N new new new new means the sequence [apk,1 , apk,2 , ... apk,N ]. (For consistency with the notation in [BCGGMTV2014] and in [BK2016], new this specification uses 1-based indexing and inclusive ranges, notwithstanding the compelling arguments to the contrary made in [EWD-831].) {𝑎 .. 𝑏} means the set or type of integers from 𝑎 through 𝑏 inclusive. [ 𝑓 (𝑥) for 𝑥 from 𝑎 up to 𝑏 ] means the sequence formed by evaluating 𝑓 on each integer from 𝑎 to 𝑏 inclusive, in ascending order. Similarly, [ 𝑓 (𝑥) for 𝑥 from 𝑎 down to 𝑏 ] means the sequence formed by evaluating 𝑓 on each integer from 𝑎 to 𝑏 inclusive, in descending order. 𝑎 || 𝑏 means the concatenation of sequences 𝑎 then 𝑏. concatB (𝑆) means the sequence of bits obtained by concatenating the elements of 𝑆 viewed as bit sequences. If the elements of 𝑆 are byte sequences, they are converted to bit sequences with the most significant bit of each byte first. sorted(𝑆) means the sequence formed by sorting the elements of 𝑆. F𝑛 means the finite field with 𝑛 elements, and F*𝑛 means its group under multiplication (which excludes 0). Where there is a need to make the distinction, we denote the unique representative of 𝑎 F𝑛 in the range {0 .. 𝑛 − 1} ◦ ◦ (or the unique representative of 𝑎 F*𝑛 in the range {1 .. 𝑛 − 1}) as 𝑎 mod 𝑛. Conversely, we denote the element of F𝑛 ◦ ◦ corresponding to an integer 𝑘 Z as 𝑘 (mod 𝑛). We also use the latter notation in the context of an equality 𝑘 = 𝑘 ′ ◦ ◦ (mod 𝑛) as shorthand for 𝑘 mod 𝑛 = 𝑘 ′ mod 𝑛, and similarly 𝑘 ̸= 𝑘 ′ (mod 𝑛) as shorthand for 𝑘 mod 𝑛 ̸= 𝑘 ′ mod 𝑛. (When referring to constants such as 0 and 1 it is usually not necessary to make the distinction between field elements and their representatives, since the meaning is normally clear from context.) F𝑛 [𝑧] means the ring of polynomials over 𝑧 with coefficients in F𝑛 . 𝑎 + 𝑏 means the sum of 𝑎 and 𝑏. This may refer to addition of integers, rationals, finite field elements, or group elements (see § 4.1.8 ‘Represented Group’ on p. 26) according to context. −𝑎 means the value of the appropriate integer, rational, finite field, or group type such that (−𝑎) + 𝑎 = 0 (or when 𝑎 is an element of a group G, (−𝑎) + 𝑎 = 𝒪G ), and 𝑎 − 𝑏 means 𝑎 + (−𝑏). 𝑎 · 𝑏 means the product of multiplying 𝑎 and 𝑏. This may refer to multiplication of integers, rationals, or finite field elements according to context (this notation is not used for group elements). 𝑎 𝑎/𝑏, also written , means the value of the appropriate integer, rational, or finite field type such that (𝑎/𝑏) · 𝑏 = 𝑎. 𝑏 𝑎 mod 𝑞, for 𝑎 N and 𝑞 N+ , means the remainder on dividing 𝑎 by 𝑞. (This usage does not conflict with the notation ◦ ◦ ◦ ◦ above for the unique representative of a field element.) 𝑎 ⊕ 𝑏 means the bitwise-exclusive-or of 𝑎 and 𝑏, and 𝑎 î 𝑏 means the bitwise-and of 𝑎 and 𝑏. These are defined on integers or (equal-length) bit sequences according to context. N ∑︁ N ∏︁ N ⨁︁ 𝑎𝑖 means the sum of 𝑎1..N . 𝑎𝑖 means the product of 𝑎1..N . 𝑎𝑖 means the bitwise exclusive-or of 𝑎1..N . 𝑖=1 𝑖=1 𝑖=1 ∑︀0 ∏︀0 ⨁︀0 When 𝑁 = 0 these yield the appropriate neutral element, i.e. 𝑎 = 0, 𝑖=1 𝑖 𝑎 = 1, and 𝑖=1 𝑖 𝑎 = 0 or the 𝑖=1 𝑖 all-zero bit sequence of length given by the type of 𝑎. 10

√ + {︁ 𝑞−1 }︁ 𝑎 , where 𝑎 F𝑞 , means the positive square root of 𝑎 in F𝑞 , i.e. in the range 0 .. ◦ ◦ . It is only used in cases where 2 the square root must exist. √ ? 𝑎 , where 𝑎 F𝑞 , means an arbitrary square root of 𝑎 in F𝑞 , or ⊥ if no such square root exists. ◦ ◦ 𝑏 ? 𝑥 : 𝑦 means 𝑥 when 𝑏 = 1, or 𝑦 when 𝑏 = 0. 𝑎𝑏 , for 𝑎 an integer or finite field element and 𝑏 Z, means the result of raising 𝑎 to the exponent 𝑏, i.e. ◦ ◦ ⎧ ∏︀ 𝑏 ⎪ ⎨ 𝑎, if 𝑏 ≥ 0 𝑏 𝑖=1 𝑎 := ∏︀−𝑏 1 , otherwise. ⎪ ⎩ 𝑖=1 𝑎 The [𝑘] 𝑃 notation for scalar multiplication in a group is defined in § 4.1.8 ‘Represented Group’ on p. 26. The convention of affixing ⋆ to a variable name is used for variables that denote bit-sequence representations of group elements. The binary relations <, ≤, =, ≥, and > have their conventional meanings on integers and rationals, and are defined lexicographically on sequences of integers. floor(𝑥) means the largest integer ≤ 𝑥. ceiling (𝑥) means the smallest integer ≥ 𝑥. bitlength(𝑥), for 𝑥 N, means the smallest integer ℓ such that 2ℓ > 𝑥. ◦ ◦ The symbol ⊥ is used to indicate unavailable information, or a failed decryption or validity check. The following integer constants will be instantiated in § 5.3 ‘Constants’ on p. 53: MerkleDepthSprout , MerkleDepthSapling , Nold , Nnew , ℓvalue , ℓMerkleSprout , ℓMerkleSapling , ℓhSig , ℓPRFSprout , ℓPRFexpand , ℓPRFnfSapling , ℓrcm , ℓSeed , ℓask , ℓϕ , ℓsk , ℓd , ℓivk , ℓovk , ℓscalar , MAX_MONEY, BlossomActivationHeight, CanopyActivationHeight, ZIP212GracePeriod SlowStartInterval, PreBlossomHalvingInterval, MaxBlockSubsidy, NumFounderAddresses, PoWLimit, PoWAveragingWindow, PoWMedianBlockSpan, PoWDampingFactor, PreBlossomPoWTargetSpacing, and PostBlossomPoWTargetSpacing. The bit sequence constants UncommittedSprout B[ℓMerkleSprout ] and UncommittedSapling B[ℓMerkleSapling ] , and rational con- ◦ ◦ ◦ ◦ stants FoundersFraction, PoWMaxAdjustDown, and PoWMaxAdjustUp will also be defined in that section. We use the abbreviation “ctEdwards” to refer to complete twisted Edwards elliptic curves and coordinates (see § 5.4.8.3 ‘Jubjub’ on p. 73). 11

3 Concepts 3.1 Payment Addresses and Keys Users who wish to receive payments in the Zcash protocol must have a shielded payment address, which is generated from a spending key . The following diagram depicts the relations between key components in Sprout and Sapling. Arrows point from a component to any other component(s) that can be derived from it. Double lines indicate that the same component is used in multiple abstractions. [Sprout] The receiving key skenc , incoming viewing key ivk = (apk , skenc ), and shielded payment address addrpk = (apk , pkenc ) are derived from the spending key ask , as described in § 4.2.1 ‘Sprout Key Components’ on p. 29. [Sapling onward] An expanded spending key is composed of a Spend authorizing key ask, a nullifier private key nsk, and an outgoing viewing key ovk. From these components we can derive an proof authorizing key (ak, nsk), a full viewing key (ak, nk, ovk), an incoming viewing key ivk, and a set of diversified payment addresses addrd = (d, pkd ), as described in § 4.2.2 ‘Sapling Key Components’ on p. 29. The consensus protocol does not depend on how an expanded spending key is constructed. Two methods of doing so are defined: 1. Generate a spending key sk at random and derive the expanded spending key (ask, nsk, ovk) from it, as shown in the diagram above and described in § 4.2.2 ‘Sapling Key Components’ on p. 29. 2. Obtain an extended spending key as specified in [ZIP-32]; this includes a superset of the components of an expanded spending key . This method is used in the context of a Hierarchical Deterministic Wallet . Non-normative note: In zcashd, all Sapling keys and addresses are derived according to [ZIP-32]. The composition of shielded payment addresses, incoming viewing keys, full viewing keys, and spending keys is a cryptographic protocol detail that should not normally be exposed to users. However, user-visible operations should be provided to obtain a shielded payment address or incoming viewing key or full viewing key from a spending key or extended spending key . 12

Users can accept payment from multiple parties with a single shielded payment address and the fact that these payments are destined to the same payee is not revealed on the block chain, even to the paying parties. However if two parties collude to compare a shielded payment address they can trivially determine they are the same. In the case that a payee wishes to prevent this they should create a distinct shielded payment address for each payer. [Sapling onward] Sapling provides a mechanism to allow the efficient creation of diversified payment addresses with the same spending authority. A group of such addresses shares the same full viewing key and incoming viewing key , and so creating as many unlinkable addresses as needed does not increase the cost of scanning the block chain for relevant transactions. Note: It is conventional in cryptography to refer to the key used to encrypt a message in an asymmetric encryption scheme as the “public key ”. However, the public key used as the transmission key component of an address (pkenc or pkd ) need not be publically distributed; it has the same distribution as the shielded payment address itself. As mentioned above, limiting the distribution of the shielded payment address is important for some use cases. This also helps to reduce reliance of the overall protocol on the security of the cryptosystem used for note encryption (see § 4.16 ‘In-band secret distribution (Sprout)’ on p. 46 and § 4.17 ‘In-band secret distribution (Sapling)’ on p. 47), since an adversary would have to know pkenc or some pkd in order to exploit a hypothetical weakness in that cryptosystem. 3.2 Notes A note (denoted n) can be a Sprout note or a Sapling note. In either case it represents that a value v is spendable by the recipient who holds the spending key corresponding to a given shielded payment address. Let MAX_MONEY, ℓPRFSprout , ℓPRFnfSapling , and ℓd be as defined in § 5.3 ‘Constants’ on p. 53. Let NoteCommitSprout be as defined in § 5.4.7.1 ‘Sprout Note Commitments’ on p. 68. Let NoteCommitSapling be as defined in § 5.4.7.2 ‘Windowed Pedersen commitments’ on p. 68. Let KASapling be as defined in § 5.4.4.3 ‘Sapling Key Agreement’ on p. 63. A Sprout note is a tuple (apk , v, ρ, rcm), where: • apk B[ℓPRFSprout ] is the paying key of the recipient’s shielded payment address; ◦ ◦ • v {0 .. MAX_MONEY} is an integer representing the value of the note in zatoshi (1 ZEC = 108 zatoshi ); ◦ ◦ • ρ B[ℓPRFSprout ] is used as input to PRFnf ◦ ◦ ask to derive the nullifier of the note; • rcm NoteCommitSprout .Trapdoor is a random commitment trapdoor as defined in § 4.1.7 ‘Commitment’ on ◦ ◦ p. 25. Let NoteSprout be the type of a Sprout note, i.e. NoteSprout := B[ℓPRFSprout ] × {0 .. MAX_MONEY} × B[ℓPRFSprout ] × NoteCommitSprout .Trapdoor. A Sapling note is a tuple (d, pkd , v, rcm), where: • d B[ℓd ] is the diversifier of the recipient’s shielded payment address; ◦ ◦ • pkd KASapling .PublicPrimeSubgroup is the diversified transmission key of the recipient’s shielded payment ◦ ◦ address; • v {0 .. MAX_MONEY} is an integer representing the value of the note in zatoshi ; ◦ ◦ • rcm NoteCommitSapling .Trapdoor is a random commitment trapdoor as defined in § 4.1.7 ‘Commitment’ on ◦ ◦ p. 25. 13

Let NoteSapling be the type of a Sapling note, i.e. NoteSapling := B[ℓd ] × KASapling .PublicPrimeSubgroup × {0 .. MAX_MONEY} × NoteCommitSapling .Trapdoor. Creation of new notes is described in § 4.6 ‘Sending Notes’ on p. 34. When notes are sent, only a commitment (see § 4.1.7 ‘Commitment’ on p. 25) to the above values is disclosed publically, and added to a data structure called the note commitment tree. This allows the value and recipient to be kept private, while the commitment is used by the zk-SNARK proof when the note is spent, to check that it exists on the block chain. A Sprout note commitment on a note n = (apk , v, ρ, rcm) is computed as NoteCommitmentSprout (n) = NoteCommitSprout rcm (apk , v, ρ), where NoteCommitSprout is instantiated in § 5.4.7.1 ‘Sprout Note Commitments’ on p. 68. Let DiversifyHash be as defined in § 5.4.1.6 ‘DiversifyHash Hash Function’ on p. 57. A Sapling note commitment on a note n = (d, pkd , v, rcm) is computed as gd := DiversifyHash(d) {︃ Sapling ⊥, if gd = ⊥ NoteCommitment (n) := Sapling NoteCommitrcm (reprJ (gd ), reprJ (pkd ), v), otherwise. where NoteCommitSapling is instantiated in § 5.4.7.2 ‘Windowed Pedersen commitments’ on p. 68. Notice that the above definition of a Sapling note does not have a ρ field. There is in fact a ρ value associated with each Sapling note, but this can only be computed once its position in the note commitment tree is known (see § 3.4 ‘Transactions and Treestates’ on p. 15 and § 3.7 ‘Note Commitment Trees’ on p. 17). We refer to the combination of a note and its note position pos, as a positioned note. For a positioned note, we can compute the value ρ as described in § 4.14 ‘Note Commitments and Nullifiers’ on p. 42. A nullifier (denoted nf) is derived from the ρ value of a note and the recipient’s spending key ask or nullifier deriving key nk. This computation uses a Pseudo Random Function (see § 4.1.2 ‘Pseudo Random Functions’ on p. 20), as described in § 4.14 ‘Note Commitments and Nullifiers’ on p. 42. A note is spent by proving knowledge of (ρ, ask ) or (ρ, ak, nsk) in zero knowledge while publically disclosing its nullifier nf, allowing nf to be used to prevent double-spending. In the case of Sapling, a spend authorization signature is also required, in order to demonstrate knowledge of ask. 3.2.1 Note Plaintexts and Memo Fields Transmitted notes are stored on the block chain in encrypted form, together with a representation of the note commitment cm. new The note plaintexts in each JoinSplit description are encrypted to the respective transmission keys pkenc,1..Nnew . Each Sprout note plaintext (denoted np) consists of (leadByte BY, v {0 .. 2ℓvalue −1}, ρ B[ℓPRFSprout ] , rcm NoteCommitSprout .Trapdoor, memo BY[512] ). ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ [Sapling onward] The note plaintext in each Output description is encrypted to the diversified payment address (d, pkd ). 14

Each Sapling note plaintext (denoted np) consists of (leadByte BY, d B[ℓd ] , v {0 .. 2ℓvalue −1}, rseed BY[32] , memo BY[512] ) ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ The fields d and v are as defined in § 3.2 ‘Notes’ on p. 13. The field rseed is described in § 4.6.2 ‘Sending Notes (Sapling)’ on p. 34. memo represents a 512-byte memo field associated with this note. The usage of the memo field is by agreement between the sender and recipient of the note. Encodings are given in § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ on p. 77. The result of encryption forms part of a transmitted note(s) ciphertext . For further details, see § 4.16 ‘In-band secret distribution (Sprout)’ on p. 46 and § 4.17 ‘In-band secret distribution (Sapling)’ on p. 47. 3.3 The Block Chain At a given point in time, each full validator is aware of a set of candidate blocks. These form a tree rooted at the genesis block , where each node in the tree refers to its parent via the hashPrevBlock block header field (see § 7.5 ‘Block Header Encoding and Consensus’ on p. 90). A path from the root toward the leaves of the tree consisting of a sequence of one or more valid blocks consistent with consensus rules, is called a valid block chain. Each block in a block chain has a block height . The block height of the genesis block is 0, and the block height of each subsequent block in the block chain increments by 1. In order to choose the best valid block chain in its view of the overall block tree, a node sums the work, as defined in § 7.6.5 ‘Definition of Work’ on p. 95, of all blocks in each valid block chain, and considers the valid block chain with greatest total work to be best. To break ties between leaf blocks, a node will prefer the block that it received first. The consensus protocol is designed to ensure that for any given block height , the vast majority of nodes should eventually agree on their best valid block chain up to that height. 3.4 Transactions and Treestates Each block contains one or more transactions. Transparent inputs to a transaction insert value into a transparent transaction value pool associated with the transaction, and transparent outputs remove value from this pool. As in Bitcoin, the remaining value in the pool is available to miners as a fee. Consensus rule: The remaining value in the transparent transaction value pool MUST be nonnegative. To each transaction there are associated initial treestates for Sprout and for Sapling. Each treestate consists of: • a note commitment tree (§ 3.7 ‘Note Commitment Trees’ on p. 17); • a nullifier set (§ 3.8 ‘Nullifier Sets’ on p. 18). Validation state associated with transparent inputs and outputs, such as the UTXO (Unspent Transaction Output) set, is not described in this document; it is used in essentially the same way as in Bitcoin. An anchor is a Merkle tree root of a note commitment tree (either the Sprout tree or the Sapling tree). It uniquely identifies a note commitment tree state given the assumed security properties of the Merkle tree’s hash function. Since the nullifier set is always updated together with the note commitment tree, this also identifies a particular state of the associated nullifier set . 15

In a given block chain, for each of Sprout and Sapling, treestates are chained as follows: • The input treestate of the first block is the empty treestate. • The input treestate of the first transaction of a block is the final treestate of the immediately preceding block . • The input treestate of each subsequent transaction in a block is the output treestate of the immediately preceding transaction. • The final treestate of a block is the output treestate of its last transaction. JoinSplit descriptions also have interstitial input and output treestates for Sprout, explained in the following section. There is no equivalent of interstitial treestates for Sapling. 3.5 JoinSplit Transfers and Descriptions A JoinSplit description is data included in a transaction that describes a JoinSplit transfer , i.e. a shielded value transfer. In Sprout, this kind of value transfer was the primary Zcash-specific operation performed by transactions. old A JoinSplit transfer spends Nold notes n1..N old old and transparent input vpub , and creates N new new notes n1..Nnew and trans- new parent output vpub . It is associated with a JoinSplit statement instance (§ 4.15.1 ‘JoinSplit Statement (Sprout)’ on p. 43), for which it provides a zk-SNARK proof . Each transaction has a sequence of JoinSplit descriptions. new old The total vpub value adds to, and the total vpub value subtracts from the transparent transaction value pool of the containing transaction. The anchor of each JoinSplit description in a transaction refers to a Sprout treestate. For each of the Nold shielded inputs, a nullifier is revealed. This allows detection of double-spends as described in § 3.8 ‘Nullifier Sets’ on p. 18. For each JoinSplit description in a transaction, an interstitial output treestate is constructed which adds the note commitments and nullifiers specified in that JoinSplit description to the input treestate referred to by its anchor . This interstitial output treestate is available for use as the anchor of subsequent JoinSplit descriptions in the same transaction. In general, therefore, the set of interstitial treestates associated with a transaction forms a tree in which the parent of each node is determined by its anchor . Interstitial treestates are necessary because when a transaction is constructed, it is not known where it will eventually appear in a mined block . Therefore the anchors that it uses must be independent of its eventual position. Consensus rules: • The input and output values of each JoinSplit transfer MUST balance exactly. • For the first JoinSplit description of a transaction, the anchor MUST be the output Sprout treestate of a previous block . • The anchor of each JoinSplit description in a transaction MUST refer to either some earlier block ’s final Sprout treestate, or to the interstitial output treestate of any prior JoinSplit description in the same transaction. 3.6 Spend Transfers, Output Transfers, and their Descriptions JoinSplit transfers are not used for Sapling notes. Instead, there is a separate Spend transfer for each shielded input , and a separate Output transfer for each shielded output . Spend descriptions and Output descriptions are data included in a transaction that describe Spend transfers and Output transfers, respectively. 16

A Spend transfer spends a note nold . Its Spend description includes a Pedersen value commitment to the value of the note. It is associated with an instance of a Spend statement (§ 4.15.2 ‘Spend Statement (Sapling)’ on p. 44) for which it provides a zk-SNARK proof . An Output transfer creates a note nnew . Similarly, its Output description includes a Pedersen value commitment to the note value. It is associated with an instance of an Output statement (§ 4.15.3 ‘Output Statement (Sapling)’ on p. 45) for which it provides a zk-SNARK proof . Each transaction has a sequence of Spend descriptions and a sequence of Output descriptions. To ensure balance, we use a homomorphic property of Pedersen commitments that allows them to be added and subtracted, as elliptic curve points (§ 5.4.7.3 ‘Homomorphic Pedersen commitments’ on p. 69). The result of adding two Pedersen value commitments, committing to values v1 and v2 , is a new Pedersen value commitment that commits to v1 + v2 . Subtraction works similarly. Therefore, balance can be enforced by adding all of the value commitments for shielded inputs, subtracting all of the value commitments for shielded outputs, and proving by use of a binding signature (as described in § 4.12 ‘Balance and Binding Signature (Sapling)’ on p. 39) that the result commits to a value consistent with the net transparent value change. This approach allows all of the zk-SNARK statements to be independent of each other, potentially increasing opportunities for precomputation. A Spend description includes an anchor , which refers to the output Sapling treestate of a previous block . It also reveals a nullifier , which allows detection of double-spends as described in § 3.8 ‘Nullifier Sets’ on p. 18. Non-normative note: Interstitial treestates are not necessary for Sapling, because a Spend transfer in a given transaction cannot spend any of the shielded outputs of the same transaction. This is not an onerous restriction because, unlike Sprout where each JoinSplit transfer must balance individually, in Sapling it is only necessary for the whole transaction to balance. Consensus rules: • The transaction MUST balance as specified in § 4.12 ‘Balance and Binding Signature (Sapling)’ on p. 39. • The anchor of each Spend description MUST refer to some earlier block ’s final Sapling treestate. 3.7 Note Commitment Trees A note commitment tree is an incremental Merkle tree of fixed depth used to store note commitments that JoinSplit transfers or Spend transfers produce. Just as the unspent transaction output set (UTXO set) used in Bitcoin, it is used to express the existence of value and the capability to spend it. However, unlike the UTXO set, it is not the job of this tree to protect against double-spending, as it is append-only. A root of a note commitment tree is associated with each treestate (§ 3.4 ‘Transactions and Treestates’ on p. 15). Each node in the incremental Merkle tree is associated with a hash value of size ℓMerkleSprout or ℓMerkleSapling bits. The layer numbered ℎ, counting from layer 0 at the root , has 2ℎ nodes with indices 0 to 2ℎ − 1 inclusive. The hash value associated with the node at index 𝑖 in layer ℎ is denoted Mℎ𝑖 . The index of a note’s commitment at the leafmost layer (MerkleDepthSprout,Sapling ) is called its note position. 17

3.8 Nullifier Sets Each full validator maintains a nullifier set logically associated with each treestate. As valid transactions containing JoinSplit transfers or Spend transfers are processed, the nullifiers revealed in JoinSplit descriptions and Spend descriptions are inserted into the nullifier set associated with the new treestate. Nullifiers are enforced to be unique within a valid block chain, in order to prevent double-spends. Consensus rule: A nullifier MUST NOT repeat either within a transaction, or across transactions in a valid block chain. Sprout and Sapling nullifiers are considered disjoint, even if they have the same bit pattern. 3.9 Block Subsidy, Funding Streams, and Founders’ Reward Like Bitcoin, Zcash creates currency when blocks are mined. The value created on mining a block is called the block subsidy . [Pre-Canopy] The block subsidy is composed of a miner subsidy and a Founders’ Reward . [Canopy onward] The block subsidy is composed of a miner subsidy and a series of funding streams. As in Bitcoin, the miner of a block also receives transaction fees. The calculations of the block subsidy , miner subsidy , Founders’ Reward , and funding streams depend on the block height , as defined in § 3.3 ‘The Block Chain’ on p. 15. The calculations are described in § 7.7 ‘Calculation of Block Subsidy, Funding Streams, and Founders’ Reward’ on p. 95. 3.10 Coinbase Transactions The first (and only the first) transaction in a block is a coinbase transaction, which collects and spends any miner subsidy and transaction fees paid by transactions included in this block . [Pre-Canopy] The coinbase transaction MUST also pay the Founders’ Reward as described in § 7.8 ‘Payment of Founders’ Reward’ on p. 96. [Canopy onward] The coinbase transaction MUST also pay the funding streams as described in § 7.9 ‘Payment of Funding Streams’ on p. 98. 3.11 Mainnet and Testnet The production Zcash network, which supports the ZEC token, is called Mainnet . Governance of its protocol is by agreement between the Electric Coin Company and the Zcash Foundation [ECCZF2019]. Subject to errors and omissions, each version of this document intends to describe some version (or planned version) of that agreed protocol. All block hashes given in this section are in RPC byte order (that is, byte-reversed relative to the normal order for a SHA-256 hash). Mainnet genesis block : 00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08 Mainnet Blossom activation block : 00000000020bebb33c1b34b67a982a328ab212a206dacbe561a7cc94aab3e9bb There is also a public test network called Testnet . It supports a TAZ token which is intended to have no monetary value. By convention, Testnet activates network upgrades (as described in § 6 ‘Network Upgrades’ on p. 83) before Mainnet , in order to allow for errors or ambiguities in their specification and implementation to be discovered. The Testnet block chain is subject to being rolled back to a prior block at any time. Testnet genesis block : 05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38 18

Testnet Heartwood activation block : 05688d8a0e9ff7c04f6f05e6d695dc5ab43b9c4803342d77ae360b2b27d2468e We call the smallest units of currency (on either network) zatoshi . On Mainnet , 1 ZEC = 108 zatoshi . On Testnet , 1 TAZ = 108 zatoshi . Other networks using variants of the Zcash protocol may exist, but are not described by this specification. 4 Abstract Protocol 4.1 Abstract Cryptographic Schemes 4.1.1 Hash Functions Let MerkleDepthSprout , ℓMerkleSprout , MerkleDepthSapling , ℓMerkleSapling , ℓivk , ℓd , ℓSeed , ℓPRFSprout , ℓhSig , and Nold be as defined in § 5.3 ‘Constants’ on p. 53. Let J, J(𝑟) , J(𝑟)* , 𝑟J , and ℓJ be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73. The functions MerkleCRHSprout {0 .. MerkleDepthSprout − 1} × B[ℓMerkleSprout ] × B[ℓMerkleSprout ] → B[ℓMerkleSprout ] and (for Sapling), ◦ ◦ MerkleCRHSapling {0 .. MerkleDepthSapling − 1} × B[ℓMerkleSapling ] × B[ℓMerkleSapling ] → B[ℓMerkleSapling ] are hash functions used in ◦ ◦ § 4.8 ‘Merkle Path Validity’ on p. 37. MerkleCRHSapling is collision-resistant on all its arguments, and MerkleCRHSprout is collision-resistant except on its first argument. Both of these functions are instantiated in § 5.4.1.3 ‘Merkle Tree Hash Function’ on p. 56. old hSigCRH B[ℓSeed ] × B[ℓPRFSprout ][N ] × JoinSplitSig.Public → B[ℓhSig ] is a collision-resistant hash function used in § 4.3 ◦ ◦ ‘JoinSplit Descriptions’ on p. 31. It is instantiated in § 5.4.1.4 ‘hSig Hash Function’ on p. 56. EquihashGen (𝑛 N+ ) × N+ × BY[N] × N+ → B[𝑛] is another hash function, used in § 7.6.1 ‘Equihash’ on p. 92 to ◦ ◦ ◦ ◦ generate input to the Equihash solver. The first two arguments, representing the Equihash parameters 𝑛 and 𝑘, are written subscripted. It is instantiated in § 5.4.1.9 ‘Equihash Generator’ on p. 60. CRHivk B[ℓJ ] × B[ℓJ ] → {0 .. 2ℓivk −1} is a collision-resistant hash function used in § 4.2.2 ‘Sapling Key Components’ ◦ ◦ on p. 29 to derive an incoming viewing key for a Sapling shielded payment address. It is also used in the Spend statement (§ 4.15.2 ‘Spend Statement (Sapling)’ on p. 44) to confirm use of the correct keys for the note being spent. It is instantiated in § 5.4.1.5 ‘CRHivk Hash Function’ on p. 57. MixingPedersenHash J × {0 .. 𝑟J − 1} → J is a hash function used in § 4.14 ‘Note Commitments and Nullifiers’ on ◦ ◦ p. 42 to derive the unique ρ value for a Sapling note. It is also used in the Spend statement to confirm use of the correct ρ value as an input to nullifier derivation. It is instantiated in § 5.4.1.8 ‘Mixing Pedersen Hash Function’ on p. 60. DiversifyHash B[ℓd ] → J(𝑟)* is a hash function instantiated in § 5.4.1.6 ‘DiversifyHash Hash Function’ on p. 57, and ◦ ◦ satisfying the Unlinkability security property described in that section. It is used to derive a diversified base from a diversifier in § 4.2.2 ‘Sapling Key Components’ on p. 29. 19

4.1.2 Pseudo Random Functions PRF𝑥 is a Pseudo Random Function keyed by 𝑥. Let ℓask , ℓϕ , ℓhSig , ℓPRFSprout , ℓsk , ℓovk , ℓPRFexpand , ℓPRFnfSapling , Nold , and Nnew be as defined in § 5.3 ‘Constants’ on p. 53. (𝑟) Let ℓJ and J⋆ be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73. Let Sym be as defined in § 5.4.3 ‘Symmetric Encryption’ on p. 62. For Sprout, four independent PRF𝑥 are needed: PRFaddr ◦ ◦ B[ℓask ] × BY → B[ℓPRFSprout ] PRFnf ◦ ◦ B[ℓask ] × B[ℓPRFSprout ] → B[ℓPRFSprout ] PRFpk ◦ ◦ B[ℓask ] × {1..Nold } × B[ℓhSig ] → B[ℓPRFSprout ] PRFρ ◦ ◦ B[ℓϕ ] × {1..Nnew } × B[ℓhSig ] → B[ℓPRFSprout ] These are used in § 4.15.1 ‘JoinSplit Statement (Sprout)’ on p. 43; PRFaddr is also used to derive a shielded payment address from a spending key in § 4.2.1 ‘Sprout Key Components’ on p. 29. For Sapling, three additional PRF𝑥 are needed: PRFexpand ◦ ◦ B[ℓsk ] × BY[N] → BY[ℓPRFexpand /8] PRFock ◦ ◦ BY[ℓovk /8] × BY[ℓJ /8] × BY[ℓJ /8] × BY[ℓJ /8] → Sym.K (𝑟) PRFnfSapling ◦ ◦ J⋆ × B[ℓJ ] → BY[ℓPRFnfSapling /8] PRFexpand is used in the following places: • § 4.2.2 ‘Sapling Key Components’ on p. 29, with inputs [0], [1], [2], and [3, 𝑖 BY]; ◦ ◦ • in the processes of sending and receiving Sapling notes (see § 4.6.2 ‘Sending Notes (Sapling)’ on p. 34 and § 4.17 ‘In-band secret distribution (Sapling)’ on p. 47), with inputs [4] and [5]; • in [ZIP-32], with inputs [0], [1], [2] (intentionally matching § 4.2.2 on p. 29), and [𝑡 {16 .. 22}]. ◦ ◦ PRFock is used in § 4.17 ‘In-band secret distribution (Sapling)’ on p. 47. PRFnfSapling is used in § 4.15.2 ‘Spend Statement (Sapling)’ on p. 44. All of these Pseudo Random Functions are instantiated in § 5.4.2 ‘Pseudo Random Functions’ on p. 61. Security requirements: • Security definitions for Pseudo Random Functions are given in [BDJR2000, section 4]. • In addition to being Pseudo Random Functions, it is required that PRFnf addr ρ 𝑥 , PRF𝑥 , PRF𝑥 , and PRF𝑥 nfSapling be collision-resistant across all 𝑥 — i.e. finding (𝑥, 𝑦) ̸= (𝑥′ , 𝑦 ′ ) such that PRFnf nf ′ 𝑥 (𝑦) = PRF𝑥′ (𝑦 ) should not be feasible, and similarly for PRFaddr and PRFρ and PRFnfSapling . Non-normative note: PRFnf was called PRFsn in Zerocash [BCGGMTV2014]. 4.1.3 Symmetric Encryption Let Sym be an authenticated one-time symmetric encryption scheme with keyspace Sym.K, encrypting plaintexts in Sym.P to produce ciphertexts in Sym.C. Sym.Encrypt Sym.K × Sym.P → Sym.C is the encryption algorithm. ◦ ◦ Sym.Decrypt Sym.K × Sym.C → Sym.P ∪ {⊥} is the decryption algorithm, such that for any K ∈ Sym.K and ◦ ◦ P ∈ Sym.P, Sym.DecryptK (Sym.EncryptK (P)) = P. ⊥ is used to represent the decryption of an invalid ciphertext. 20

Security requirement: Sym must be one-time (INT-CTXT ∧ IND-CPA)-secure [BN2007]. “One-time” here means that an honest protocol participant will almost surely encrypt only one message with a given key; however, the adversary may make many adaptive chosen ciphertext queries for a given key. 4.1.4 Key Agreement A key agreement scheme is a cryptographic protocol in which two parties agree a shared secret, each using their private key and the other party’s public key . A key agreement scheme KA defines a type of public keys KA.Public, a type of private keys KA.Private, and a type of shared secrets KA.SharedSecret. Optionally, it also defines a type KA.PublicPrimeSubgroup ⊆ KA.Public. Optional: Let KA.FormatPrivate B[ℓPRFSprout ] → KA.Private be a function to convert a bit string of length ℓPRFSprout to a ◦ ◦ KA private key . Let KA.DerivePublic KA.Private×KA.Public → KA.Public be a function that derives the KA public key corresponding ◦ ◦ to a given KA private key and base point. Let KA.Agree KA.Private × KA.Public → KA.SharedSecret be the agreement function. ◦ ◦ Optional: Let KA.Base KA.Public be a public base point. ◦ ◦ Note: The range of KA.DerivePublic may be a strict subset of KA.Public. Security requirements: • KA.FormatPrivate must preserve sufficient entropy from its input to be used as a secure KA private key . • The key agreement and the KDF defined in the next section must together satisfy a suitable adaptive security assumption along the lines of [Bernstein2006, section 3] or [ABR1999, Definition 3]. More precise formalization of these requirements is beyond the scope of this specification. 4.1.5 Key Derivation A Key Derivation Function is defined for a particular key agreement scheme and authenticated one-time symmetric encryption scheme; it takes the shared secret produced by the key agreement and additional arguments, and derives a key suitable for the encryption scheme. The inputs to the Key Derivation Function differ between the Sprout and Sapling KDFs: KDFSprout takes as input an output index in {1..Nnew }, the value hSig , the shared Diffie-Hellman secret sharedSecret, the ephemeral public key epk, and the recipient’s public transmission key pkenc . It is suitable for use with KASprout and derives keys for Sym.Encrypt. KDFSprout {1..Nnew } × B[ℓhSig ] × KASprout .SharedSecret × KASprout .Public × KASprout .Public → Sym.K ◦ ◦ KDFSapling takes as input the shared Diffie-Hellman secret sharedSecret and the ephemeral public key epk. (It does not have inputs taking the place of the output index, hSig , or pkenc .) It is suitable for use with KASapling and derives keys for Sym.Encrypt. KDFSapling KASapling .SharedSecret × BY[ℓJ /8] → Sym.K ◦ ◦ 21

Security requirements: • The asymmetric encryption scheme in § 4.16 ‘In-band secret distribution (Sprout)’ on p. 46, constructed from KASprout , KDFSprout and Sym, is required to be IND-CCA2-secure and key-private. • The asymmetric encryption scheme in § 4.17 ‘In-band secret distribution (Sapling)’ on p. 47, constructed from KASapling , KDFSapling and Sym, is required to be IND-CCA2-secure and key-private. Key privacy is defined in [BBDP2001]. 4.1.6 Signature A signature scheme Sig defines: • a type of signing keys Sig.Private; • a type of validating keys Sig.Public; • a type of messages Sig.Message; • a type of signatures Sig.Signature; R • a randomized signing key generation algorithm Sig.GenPrivate () → Sig.Private; ◦ ◦ • an injective validating key derivation algorithm Sig.DerivePublic Sig.Private → Sig.Public; ◦ ◦ R • a randomized signing algorithm Sig.Sign Sig.Private × Sig.Message → ◦ ◦ Sig.Signature; • a validating algorithm Sig.Validate Sig.Public × Sig.Message × Sig.Signature → B; ◦ ◦ R such that for any signing key sk ← Sig.GenPrivate() and corresponding validating key vk = Sig.DerivePublic(sk), and R any 𝑚 Sig.Message and 𝑠 Sig.Signature ← ◦ ◦ ◦ ◦ Sig.Signsk (𝑚), Sig.Validatevk (𝑚, 𝑠) = 1. Zcash uses four signature schemes: • one used for signatures that can be validated by script operations such as OP_CHECKSIG and OP_CHECKMULTISIG as in Bitcoin; • one called JoinSplitSig (instantiated in § 5.4.5 ‘Ed25519’ on p. 63), which is used to sign transactions that contain at least one JoinSplit description; • [Sapling onward] one called SpendAuthSig (instantiated in § 5.4.6.1 ‘Spend Authorization Signature’ on p. 67) which is used to sign authorizations of Spend transfers; • [Sapling onward] one called BindingSig (instantiated in § 5.4.6.2 ‘Binding Signature’ on p. 68), which is used to enforce balance of Spend transfers and Output transfers, and to prevent their replay across transactions. The following security property is needed for JoinSplitSig and BindingSig. Security requirements for SpendAuthSig are defined in the next section, § 4.1.6.1 ‘Signature with Re-Randomizable Keys’ on p. 23. An additional requirement for BindingSig is defined in § 4.1.6.2 ‘Signature with Signing Key to Validating Key Monomorphism’ on p. 24. Security requirement: JoinSplitSig and BindingSig must be Strongly Unforgeable under (non-adaptive) Chosen Message Attack (SU-CMA), as defined for example in [BDEHR2011, Definition 6]. 4 This allows an adversary to obtain signatures on chosen messages, and then requires it to be infeasible for the adversary to forge a previously unseen valid (message, signature) pair without access to the signing key . 4 The scheme defined in that paper was attacked in [LM2017], but this has no impact on the applicability of the definition. 22

Non-normative notes: • We need separate signing key generation and validating key derivation algorithms, rather than the more R conventional combined key pair generation algorithm Sig.Gen () → ◦ ◦ Sig.Private×Sig.Public, to support the key derivation in § 4.2.2 ‘Sapling Key Components’ on p. 29. This also simplifies some aspects of the definitions of signature schemes with additional features in § 4.1.6.1 ‘Signature with Re-Randomizable Keys’ on p. 23 and § 4.1.6.2 ‘Signature with Signing Key to Validating Key Monomorphism’ on p. 24. • A fresh signature key pair is generated for each transaction containing a JoinSplit description. Since each key pair is only used for one signature (see § 4.10 ‘Non-malleability (Sprout)’ on p. 38), a one-time signature scheme would suffice for JoinSplitSig. This is also the reason why only security against non-adaptive chosen message attack is needed. In fact the instantiation of JoinSplitSig uses a scheme designed for security under adaptive attack even when multiple signatures are signed under the same key. • [Sapling onward] The same remarks as above apply to BindingSig, except that the key is derived from the randomness of value commitments. This results in the same distribution as of freshly generated key pairs, for each transaction containing Spend descriptions or Output descriptions. • SU-CMA security requires it to be infeasible for the adversary, not knowing the private key , to forge a distinct signature on a previously seen message. That is, JoinSplit signatures and binding signatures are intended to be nonmalleable in the sense of [BIP-62]. • The terminology used in this specification is that we “validate” signatures, and “verify” zk-SNARK proofs. 4.1.6.1 Signature with Re-Randomizable Keys A signature scheme with re-randomizable keys Sig is a signature scheme that additionally defines: • a type of randomizers Sig.Random; R • a randomizer generator Sig.GenRandom () → Sig.Random; ◦ ◦ • a signing key randomization algorithm Sig.RandomizePrivate Sig.Random × Sig.Private → Sig.Private; ◦ ◦ • a validating key randomization algorithm Sig.RandomizePublic Sig.Random × Sig.Public → Sig.Public; ◦ ◦ • a distinguished “identity” randomizer 𝒪Sig.Random Sig.Random ◦ ◦ such that: • for any 𝛼 Sig.Random, Sig.RandomizePrivate𝛼 Sig.Private → Sig.Private is injective and easily invertible; ◦ ◦ ◦ ◦ • Sig.RandomizePrivate𝒪Sig.Random is the identity function on Sig.Private. • for any sk Sig.Private, ◦ ◦ R Sig.RandomizePrivate(𝛼, sk) : 𝛼 ← Sig.GenRandom() is identically distributed to Sig.GenPrivate(). • for any sk Sig.Private and 𝛼 Sig.Random, ◦ ◦ ◦ ◦ Sig.RandomizePublic(𝛼, Sig.DerivePublic(sk)) = Sig.DerivePublic(Sig.RandomizePrivate(𝛼, sk)). The following security requirement for such signature schemes is based on that given in [FKMSSS2016, section 3]. Note that we require Strong Unforgeability with Re-randomized Keys, not Existential Unforgeability with Re- randomized Keys (the latter is called “Unforgeability under Re-randomized Keys” in [FKMSSS2016, Definition 8]). Unlike the case for JoinSplitSig, we require security under adaptive chosen message attack with multiple messages signed using a given key. (Although each note uses a different re-randomized key pair, the same original key pair can be re-randomized for multiple notes, and also it can happen that multiple transactions spending the same note are revealed to an adversary.) 23

Security requirement: Strong Unforgeability with Re-randomized Keys under adaptive Chosen Message At- tack (SURK-CMA) For any sk Sig.Private, let ◦ ◦ Osk Sig.Message × Sig.Random → Sig.Signature ◦ ◦ be a signing oracle with state 𝑄 P Sig.Message × Sig.Signature initialized to {} that records queried messages (︀ ◦ )︀ ◦ and corresponding signatures. Osk := var 𝑄 ← {} in (𝑚 Sig.Message, 𝛼 Sig.Random) ↦→ ◦ ◦ ◦ ◦ let 𝜎 = Sig.SignSig.RandomizePrivate(𝛼,sk) (𝑚) 𝑄 ← 𝑄 ∪ {(𝑚, 𝜎)} return 𝜎 Sig.Signature. ◦ ◦ R For random sk ← Sig.GenPrivate() and vk = Sig.DerivePublic(sk), it must be infeasible for an adversary given vk and a new instance of Osk to find (𝑚′ , 𝜎 ′ , 𝛼′ ) such that Sig.ValidateSig.RandomizePublic(𝛼′ ,vk) (𝑚′ , 𝜎 ′ ) = 1 and (𝑚′ , 𝜎 ′ ) ̸∈ Osk .𝑄. Non-normative notes: • The randomizer and key arguments to Sig.RandomizePrivate and Sig.RandomizePublic are swapped relative to [FKMSSS2016, section 3]. • The requirement for the identity randomizer 𝒪Sig.Random simplifies the definition of SURK-CMA by removing the need for two oracles (because the oracle for original keys, called O1 in [FKMSSS2016], is a special case of the oracle for randomized keys). R • Since Sig.RandomizePrivate(𝛼, sk) : 𝛼 ← Sig.Random has an identical distribution to Sig.GenPrivate(), and since Sig.DerivePublic is a deterministic function, the combination of a re-randomized validating key and signature(s) under that key do not reveal the key from which it was re-randomized. • Since Sig.RandomizePrivate𝛼 is injective and easily invertible, knowledge of Sig.RandomizePrivate(𝛼, sk) and 𝛼 implies knowledge of sk. 4.1.6.2 Signature with Signing Key to Validating Key Monomorphism A signature scheme with key monomorphism Sig is a signature scheme that additionally defines: • an abelian group on signing keys, with operation ◦ ◦ Sig.Private × Sig.Private → Sig.Private and identity 𝒪 ; • an abelian group on validating keys, with operation ◦ ◦ Sig.Public × Sig.Public → Sig.Public and identity 𝒪 . such that for any sk1..2 Sig.Private, Sig.DerivePublic(sk1 ◦ ◦ sk2 ) = Sig.DerivePublic(sk1 ) Sig.DerivePublic(sk2 ). In other words, Sig.DerivePublic is a monomorphism (that is, an injective homomorphism) from the signing key group to the validating key group. For N N+ , ◦ ◦ N • 𝑖=1 sk𝑖 means sk1 sk2 ··· skN ; N • 𝑖=1 vk𝑖 means vk1 vk2 ··· vkN . 0 0 When N = 0 these yield the appropriate group identity, i.e. 𝑖=1 sk𝑖 = 𝒪 and 𝑖=1 vk𝑖 = 𝒪 . sk means the signing key such that ( sk) sk = 𝒪 , and sk1 sk2 means sk1 ( sk2 ). vk means the validating key such that ( vk) vk = 𝒪 , and vk1 vk2 means vk1 ( vk2 ). With a change of notation from 𝜇 to Sig.DerivePublic, + to , and · to , this is similar to the definition of a “Signature with Secret Key to Public Key Homomorphism” in [DS2016, Definition 13], except for an additional requirement for the homomorphism to be injective. 24

R Security requirement: For any sk1 Sig.Private, and an unknown sk2 ← ◦ ◦ Sig.GenPrivate() chosen independently of sk1 , the distribution of sk1 sk2 is computationally indistinguishable from that of Sig.GenPrivate(). (Since 𝑛 is an abelian group operation, this implies that for 𝑛 N+ , ◦ sk is computationally indistinguishable from 𝑖=1 𝑖 ◦ Sig.GenPrivate() when at least one of sk1..𝑛 is unknown.) 4.1.7 Commitment A commitment scheme is a function that, given a commitment trapdoor generated at random and an input, can be used to commit to the input in such a way that: • no information is revealed about it without the trapdoor (“hiding ”), • given the trapdoor and input, the commitment can be verified to “open” to that input and no other (“binding ”). A commitment scheme COMM defines a type of inputs COMM.Input, a type of commitments COMM.Output, a type R of commitment trapdoors COMM.Trapdoor, and a trapdoor generator COMM.GenTrapdoor () → COMM.Trapdoor.◦ ◦ Let COMM COMM.Trapdoor × COMM.Input → COMM.Output be a function satisfying the following security ◦ ◦ requirements. Security requirements: R • Computational hiding: For all 𝑥, 𝑥′ COMM.Input, the distributions { COMM𝑟 (𝑥) | 𝑟 ← ◦ ◦ COMM.GenTrapdoor() } ′ R and { COMM𝑟 (𝑥 ) | 𝑟 ← COMM.GenTrapdoor() } are computationally indistinguishable. • Computational binding: It is infeasible to find 𝑥, 𝑥′ COMM.Input and 𝑟, 𝑟′ COMM.Trapdoor such that 𝑥 ̸= 𝑥′ ◦ ◦ ◦ ◦ and COMM𝑟 (𝑥) = COMM𝑟′ (𝑥′ ). Notes: • COMM.GenTrapdoor need not produce the uniform distribution on COMM.Trapdoor. In that case, it is incorrect to choose a trapdoor from the latter distribution. • If it were only feasible to find 𝑥 COMM.Input and 𝑟, 𝑟′ COMM.Trapdoor such that 𝑟 ̸= 𝑟′ and COMM𝑟 (𝑥) = ◦ ◦ ◦ ◦ COMM𝑟′ (𝑥), this would not contradict the computational binding security requirement. (In fact, this is feasible for NoteCommitSapling and ValueCommit because trapdoors are equivalent modulo 𝑟J , and the range of a trapdoor for those algorithms is {0 .. 2ℓscalar −1} where 2ℓscalar > 𝑟J .) Let ℓrcm , ℓMerkleSprout , ℓPRFSprout , and ℓvalue be as defined in § 5.3 ‘Constants’ on p. 53. Define NoteCommitSprout .Trapdoor := B[ℓrcm ] and NoteCommitSprout .Output := B[ℓMerkleSprout ] . Sprout uses a note commitment scheme NoteCommitSprout ◦ ◦ NoteCommitSprout .Trapdoor × B[ℓPRFSprout ] × {0 .. 2ℓvalue −1} × B[ℓPRFSprout ] → NoteCommitSprout .Output, instantiated in § 5.4.7.1 ‘Sprout Note Commitments’ on p. 68. Let ℓscalar be as defined in § 5.3 ‘Constants’ on p. 53. Let J(𝑟) and 𝑟J be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73. Define: NoteCommitSapling .Trapdoor := {0 .. 2ℓscalar −1} and NoteCommitSapling .Output := J; ValueCommit.Trapdoor := {0 .. 2ℓscalar −1} and ValueCommit.Output := J. 25

Sapling uses two additional commitment schemes: NoteCommitSapling ◦ ◦ NoteCommitSapling .Trapdoor × B[ℓJ ] × B[ℓJ ] × {0 .. 2ℓvalue −1} → NoteCommitSapling .Output {︁ }︁ 𝑟 −1 𝑟 −1 ValueCommit ◦ ◦ ValueCommit.Trapdoor × − J2 .. J2 → ValueCommit.Output NoteCommitSapling is instantiated in § 5.4.7.2 ‘Windowed Pedersen commitments’ on p. 68, and ValueCommit is instan- tiated in § 5.4.7.3 ‘Homomorphic Pedersen commitments’ on p. 69. Non-normative note: NoteCommitSapling and ValueCommit always return points in the subgroup J(𝑟) . However, we declare the type of these commitment outputs to be J because they are not directly checked to be in the subgroup when ValueCommit outputs appear in Spend descriptions and Output descriptions, or when the cmu field derived from a NoteCommitSapling appears in an Output description. 4.1.8 Represented Group A represented group G consists of: • a subgroup order parameter 𝑟G N+ , which must be prime; ◦ ◦ • a cofactor parameter ℎG N+ ; ◦ ◦ • a group G of order ℎG · 𝑟G , written additively with operation + G × G → G, and additive identity 𝒪G ; ◦ ◦ • a bit-length parameter ℓG N; ◦ ◦ • a representation function reprG G → B[ℓG ] and an abstraction function abstG B[ℓG ] → G ∪ {⊥}, such that ◦ ◦ ◦ ◦ abstG is the left inverse of reprG , i.e. for all 𝑃 ∈ G, abstG (reprG (𝑃 )) = 𝑃 , and for all 𝑆 not in the image of reprG , abstG (𝑆) = ⊥. Define G(𝑟) as the order-𝑟G subgroup of G, which is called a represented subgroup. Note that this includes 𝒪G . For the set of points of order 𝑟G (which excludes 𝒪G ), we write G(𝑟)* . (𝑟) Define G ⋆ := {reprG (𝑃 ) B[ℓG ] | 𝑃 ∈ G(𝑟) }. ◦ ◦ For 𝐺 G we write −𝐺 for the negation of 𝐺, such that (−𝐺) + 𝐺 = 𝒪G . We write 𝐺 − 𝐻 for 𝐺 + (−𝐻). ◦ ◦ ∑︁ We also extend the notation to addition on group elements. For 𝐺 G and 𝑘 Z we write [𝑘] 𝐺 for scalar multiplication on the group, i.e. ◦ ◦ ◦ ◦ ⎧ ∑︀𝑘 ⎨ 𝐺, if 𝑘 ≥ 0 [𝑘] 𝐺 := ∑︀𝑖=1 −𝑘 (−𝐺), otherwise. ⎩ 𝑖=1 For 𝐺 G and 𝑎 F𝑟G , we may also write [𝑎] 𝐺 meaning [𝑎 mod 𝑟G ] 𝐺 as defined above. (This variant is not defined ◦ ◦ ◦ ◦ for fields other than F𝑟G .) 4.1.9 Hash Extractor A hash extractor for a represented group G is a function ExtractG(𝑟) G(𝑟) → 𝑇 for some type 𝑇 , such that ExtractG(𝑟) ◦ ◦ is injective on G(𝑟) (the subgroup of G of order 𝑟G ). Note: Unlike the representation function reprG , ExtractG(𝑟) need not have an efficiently computable left inverse. 26

4.1.10 Group Hash (𝑟) Given a represented subgroup G(𝑟) , a family of group hashes into the subgroup, denoted GroupHashG , consists of: • a type GroupHash.URSType of Uniform Random Strings; • a type GroupHash.Input of inputs; (𝑟) • a function GroupHashG ◦ ◦ GroupHash.URSType × GroupHash.Input → G(𝑟) . In § 5.4.8.5 ‘Group Hash into Jubjub’ on p. 74, we instantiate a family of group hashes into the Jubjub curve defined by § 5.4.8.3 ‘Jubjub’ on p. 73. Security requirement: For a randomly selected URS ◦ ◦ GroupHash.URSType, it must be reasonble to model (𝑟) (restricted to inputs for which it does not return ⊥) as a random oracle. G GroupHashURS Non-normative notes: (𝑟)* • GroupHashJ is used to obtain generators of the Jubjub curve for various purposes: the bases 𝒢 and ℋ used in Sapling key generation, the Pedersen hash defined in § 5.4.1.7 ‘Pedersen Hash Function’ on p. 58, and the commitment schemes defined in § 5.4.7.2 ‘Windowed Pedersen commitments’ on p. 68 and in § 5.4.7.3 ‘Homomorphic Pedersen commitments’ on p. 69. The security property needed for these uses can alternatively be defined in the standard model as follows: (𝑟) Discrete Logarithm Independence: For a randomly selected member GroupHashURS of the family, it is infea- G sible to find a sequence of distinct inputs 𝑚1..𝑛 GroupHash.Input[𝑛] and a sequence of nonzero 𝑥1..𝑛 F*𝑟G [𝑛] ◦ ◦ ◦ ◦ ∑︀𝑛 (︁ (𝑟) )︁ such that = 𝒪G . G 𝑖=1 [𝑥 𝑖 ] GroupHashURS (𝑚 𝑖 ) • Under the Discrete Logarithm assumption on G(𝑟) , a random oracle almost surely satisfies Discrete Logarithm Independence. Discrete Logarithm Independence implies collision resistance , since a collision (𝑚1 , 𝑚2 ) for (𝑟) GroupHashURS trivially gives a discrete logarithm relation with 𝑥1 = 1 and 𝑥2 = −1. G (𝑟)* • GroupHashJ is also used to instantiate DiversifyHash in § 5.4.1.6 ‘DiversifyHash Hash Function’ on p. 57. We do not know how to prove the Unlinkability property defined in that section in the standard model, but in a (𝑟)* model where GroupHashJ (restricted to inputs for which it does not return ⊥) is taken as a random oracle, it is implied by the Decisional Diffie-Hellman assumption on J(𝑟) . • URS is a Uniform Random String ; we choose it verifiably at random (see § 5.9 ‘Randomness Beacon’ on p. 83), after fixing the concrete group hash algorithm to be used. This mitigates the possibility that the group hash algorithm could have been backdoored. 4.1.11 Represented Pairing A represented pairing P consists of: • a group order parameter 𝑟P N+ which must be prime; ◦ ◦ (𝑟) • two represented subgroups P1,2 , both of order 𝑟P ; (𝑟) (𝑟) (𝑟) (𝑟) • a group P𝑇 of order 𝑟P , written multiplicatively with operation · P𝑇 × P𝑇 → P𝑇 and group identity 1P ; ◦ ◦ (𝑟) • three generators 𝒫P1,2,𝑇 of P1,2,𝑇 respectively; (𝑟) (𝑟) (𝑟) • a pairing function 𝑒^P P1 × P2 → P𝑇 satisfying: ◦ ◦ – (Bilinearity) for all 𝑎, 𝑏 F*𝑟 , 𝑃 (𝑟) (𝑟) ◦ ◦ ◦ ◦ P1 , and 𝑄 P2 , 𝑒^P ([𝑎] 𝑃, [𝑏] 𝑄) = 𝑒^P (𝑃, 𝑄)𝑎·𝑏 ; and ◦ ◦ (𝑟)* (𝑟) – (Nondegeneracy) there does not exist 𝑃 ◦ ◦ P1 such that for all 𝑄 P2 , 𝑒^P (𝑃, 𝑄) = 1P . ◦ ◦ 27

4.1.12 Zero-Knowledge Proving System A zero-knowledge proving system is a cryptographic protocol that allows proving a particular statement , dependent on primary and auxiliary inputs, in zero knowledge — that is, without revealing information about the auxiliary inputs other than that implied by the statement . The type of zero-knowledge proving system needed by Zcash is a preprocessing zk-SNARK [BCCGLRT2014]. A preprocessing zk-SNARK instance ZK defines: • a type of zero-knowledge proving keys, ZK.ProvingKey; • a type of zero-knowledge verifying keys, ZK.VerifyingKey; • a type of primary inputs ZK.PrimaryInput; • a type of auxiliary inputs ZK.AuxiliaryInput; • a type of zk-SNARK proofs ZK.Proof; • a type ZK.SatisfyingInputs ⊆ ZK.PrimaryInput × ZK.AuxiliaryInput of inputs satisfying the statement ; R • a randomized key pair generation algorithm ZK.Gen () → ZK.ProvingKey × ZK.VerifyingKey; ◦ ◦ • a proving algorithm ZK.Prove ZK.ProvingKey × ZK.SatisfyingInputs → ZK.Proof; ◦ ◦ • a verifying algorithm ZK.Verify ZK.VerifyingKey × ZK.PrimaryInput × ZK.Proof → B; ◦ ◦ R The security requirements below are supposed to hold with overwhelming probability for (pk, vk) ← ZK.Gen(). Security requirements: • Completeness: An honestly generated proof will convince a verifier: for any (𝑥, 𝑤) ∈ ZK.SatisfyingInputs, if ZK.Provepk (𝑥, 𝑤) outputs 𝜋, then ZK.Verifyvk (𝑥, 𝜋) = 1. • Knowledge Soundness: For any adversary 𝒜 able to find an 𝑥 ZK.PrimaryInput and proof 𝜋 ZK.Proof ◦ ◦ ◦ ◦ such that ZK.Verifyvk (𝑥, 𝜋) = 1, there is an efficient extractor ℰ𝒜 such that if ℰ𝒜 (vk, pk) returns 𝑤, then the probability that (𝑥, 𝑤) ̸∈ ZK.SatisfyingInputs is insignificant. • Statistical Zero Knowledge: An honestly generated proof is statistical zero knowledge. That is, there is a feasible stateful simulator 𝒮 such that, for all stateful distinguishers 𝒟, the following two probabilities are not significantly different: ⃒ ⃒ R R ⎡ ⎤ ⎡ ⎤ ⃒ (pk, vk) ← ZK.Gen() ⃒ (pk, vk) ← 𝒮() ⎢ (𝑥, 𝑤) ∈ ZK.SatisfyingInputs ⃒ ⎢ (𝑥, 𝑤) ∈ ZK.SatisfyingInputs ⃒ ⃒ R ⎥ and Pr⎢ R ⎥ ⃒ ⎥ Pr⎢ ⃒ (𝑥, 𝑤) ← 𝒟(pk, vk) ⃒ (𝑥, 𝑤) ← 𝒟(pk, vk) ⎥ 𝒟(𝜋) = 1 𝒟(𝜋) = 1 ⎣ ⃒ ⎦ ⎣ ⃒ ⎦ R R ⃒ ⃒ ⃒ 𝜋← ZK.Provepk (𝑥, 𝑤) ⃒ 𝜋← 𝒮(𝑥) These definitions are derived from those in [BCTV2014b, Appendix C], adapted to state concrete security for a fixed circuit, rather than asymptotic security for arbitrary circuits. (ZK.Prove corresponds to 𝑃 , ZK.Verify corresponds to 𝑉 , and ZK.SatisfyingInputs corresponds to ℛ𝐶 in the notation of that appendix.) The Knowledge Soundness definition is a way to formalize the property that it is infeasible to find a new proof 𝜋 where ZK.Verifyvk (𝑥, 𝜋) = 1 without knowing an auxiliary input 𝑤 such that (𝑥, 𝑤) ∈ ZK.SatisfyingInputs. Note that Knowledge Soundness implies Soundness — i.e. the property that it is infeasible to find a new proof 𝜋 where ZK.Verifyvk (𝑥, 𝜋) = 1 without there existing an auxiliary input 𝑤 such that (𝑥, 𝑤) ∈ ZK.SatisfyingInputs. Non-normative notes: • The above properties do not include nonmalleability [DSDCOPS2001], and the design of the protocol using the zero-knowledge proving system must take this into account. • The terminology used in this specification is that we “validate” signatures, and “verify” zk-SNARK proofs. 28

Zcash uses two proving systems: • BCTV14 (§ 5.4.9.1 ‘BCTV14’ on p. 75) is used with the BN-254 pairing (§ 5.4.8.1 ‘BN-254’ on p. 70), to prove and verify the Sprout JoinSplit statement (§ 4.15.1 ‘JoinSplit Statement (Sprout)’ on p. 43) before Sapling activa- tion. • Groth16 (§ 5.4.9.2 ‘Groth16’ on p. 76) is used with the BLS12-381 pairing (§ 5.4.8.2 ‘BLS12-381’ on p. 71), to prove and verify the Sapling Spend statement (§ 4.15.2 ‘Spend Statement (Sapling)’ on p. 44) and Output statement (§ 4.15.3 ‘Output Statement (Sapling)’ on p. 45). It is also used to prove and verify the JoinSplit statement after Sapling activation. These specializations are: ZKJoinSplit for the Sprout JoinSplit statement (with BCTV14 and BN-254, or Groth16 and BLS12-381); ZKSpend for the Sapling Spend statement ; and ZKOutput for the Sapling Output statement . We omit key subscripts on ZKJoinSplit.Prove and ZKJoinSplit.Verify, taking them to be either the BCTV14 proving key and verifying key defined in § 5.7 ‘BCTV14 zk-SNARK Parameters’ on p. 82, or the sprout-groth16.params Groth16 proving key and verifying key defined in § 5.8 ‘Groth16 zk-SNARK Parameters’ on p. 83, according to whether the proof appears in a block before or after Sapling activation. We also omit subscripts on ZKSpend.Prove, ZKSpend.Verify, ZKOutput.Prove, and ZKOutput.Verify, taking them to be the relevant Groth16 proving keys and verifying keys defined in § 5.8 ‘Groth16 zk-SNARK Parameters’ on p. 83. 4.2 Key Components 4.2.1 Sprout Key Components Let ℓask be as defined in § 5.3 ‘Constants’ on p. 53. Let PRFaddr be a Pseudo Random Function, instantiated in § 5.4.2 ‘Pseudo Random Functions’ on p. 61. Let KASprout be a key agreement scheme, instantiated in § 5.4.4.1 ‘Sprout Key Agreement’ on p. 62. A new Sprout spending key ask is generated by choosing a bit sequence uniformly at random from B[ℓask ] . apk , skenc and pkenc are derived from ask as follows: apk := PRFaddr ask (0) skenc := KASprout .FormatPrivate(PRFaddr ask (1)) pkenc := KASprout .DerivePublic(skenc , KASprout .Base). 4.2.2 Sapling Key Components Let ℓPRFexpand , ℓsk , ℓovk , and ℓd be as defined in § 5.3 ‘Constants’ on p. 53. Let PRFexpand and PRFock be Pseudo Random Functions instantiated in § 5.4.2 ‘Pseudo Random Functions’ on p. 61. Let KASapling be a key agreement scheme, instantiated in § 5.4.4.3 ‘Sapling Key Agreement’ on p. 63. Let CRHivk be a hash function, instantiated in § 5.4.1.5 ‘CRHivk Hash Function’ on p. 57. Let DiversifyHash be a hash function, instantiated in § 5.4.1.6 ‘DiversifyHash Hash Function’ on p. 57. Let SpendAuthSig, instantiated in § 5.4.6.1 ‘Spend Authorization Signature’ on p. 67, be a signature scheme with re-randomizable keys. (𝑟)* (𝑟) Let reprJ , J(𝑟) , J(𝑟)* , and J⋆ be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73, and let FindGroupHashJ be as defined in § 5.4.8.5 ‘Group Hash into Jubjub’ on p. 74. 29

Let LEBS2OSP (ℓ N) × B[ℓ] → BY[ceiling(ℓ/8)] and LEOS2IP (ℓ N | ℓ mod 8 = 0) × BY[ℓ/8] → {0 .. 2ℓ −1} be as ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ defined in § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53. (𝑟)* Define ℋ := FindGroupHashJ (“Zcash_H_”, “”). Define ToScalar(𝑥 BY[ℓPRFexpand /8] ) := LEOS2IPℓPRFexpand (𝑥) (mod 𝑟J ). ◦ ◦ A new Sapling spending key sk is generated by choosing a bit sequence uniformly at random from B[ℓsk ] . From this spending key , the Spend authorizing key ask F*𝑟J , the proof authorizing key nsk F𝑟J , and the outgoing ◦ ◦ ◦ ◦ viewing key ovk ◦ ◦ BY[ℓovk /8] are derived as follows: ask := ToScalar(PRFexpand sk ([0])) nsk := ToScalar(PRFexpand sk ([1])) ovk := truncate(ℓovk /8) (PRFexpand sk ([2])) If ask = 0, discard this key and repeat with a new sk. ak J(𝑟)* , nk J(𝑟) , and the incoming viewing key ivk {0 .. 2ℓivk −1} are then derived as: ◦ ◦ ◦ ◦ ◦ ◦ ak := SpendAuthSig.DerivePublic(ask) nk := [nsk] ℋ ivk := CRHivk reprJ (ak), reprJ (nk) . (︀ )︀ If ivk = 0, discard this key and repeat with a new sk. As explained in § 3.1 ‘Payment Addresses and Keys’ on p. 12, Sapling allows the efficient creation of multiple di- versified payment addresses with the same spending authority. A group of such addresses shares the same full viewing key and incoming viewing key . To create a new diversified payment address given an incoming viewing key ivk, repeatedly pick a diversifier d uniformly at random from B[ℓd ] until the diversified base gd = DiversifyHash(d) is not ⊥. Then calculate the diversified transmission key pkd : pkd := KASapling .DerivePublic(ivk, gd ). The resulting diversified payment address is (d B[ℓd ] , pkd KASapling .PublicPrimeSubgroup). ◦ ◦ ◦ ◦ For each spending key , there is also a default diversified payment address with a “random-looking” diversifier . This allows an implementation that does not expose diversified addresses as a user-visible feature, to use a default address that cannot be distinguished (without knowledge of the spending key ) from one with a random diversifier as above. Let first (BY → 𝑇 ∪ {⊥}) → 𝑇 ∪ {⊥} be as defined in § 5.4.8.5 ‘Group Hash into Jubjub’ on p. 74. Define: ◦ ◦ {︃ [ℓd ] ⊥, if DiversifyHash(d) = ⊥ CheckDiversifier(d B ) := ◦ ◦ d, otherwise DefaultDiversifier(sk B[ℓsk ] ) := first 𝑖 BY ↦→ CheckDiversifier(truncate(ℓd /8) (PRFexpand ([3, 𝑖]))) J(𝑟)* ∪ {⊥} . ◦ (︀ ◦ ◦ )︀ ◦ ◦ ◦ sk For a random spending key , DefaultDiversifier returns ⊥ with probability approximately 2−256 ; if this happens, discard the key and repeat with a different sk. 30

Notes: • The protocol does not prevent using the diversifier d to produce “vanity ” addresses that start with a meaningful string when encoded in Bech32 (see § 5.6.4 ‘Sapling Payment Addresses’ on p. 80). Users and writers of software that generates addresses should be aware that this provides weaker privacy properties than a randomly chosen diversifier , since a vanity address can obviously be distinguished, and might leak more information than intended as to who created it. • Similarly, address generators MAY encode information in the diversifier that can be recovered by the recipient of a payment to determine which diversified payment address was used. It is RECOMMENDED that such diversifiers be randomly chosen unique values used to index into a database, rather than directly encoding the needed data. Non-normative notes: • Assume that PRFexpand is a PRF with output range BY[ℓPRFexpand /8] , where 2ℓPRFexpand is large compared to 𝑟J . Define 𝑓 B[ℓsk ] × BY[N] → F𝑟J by 𝑓sk (𝑡) := ToScalar(PRFexpand ◦ ◦ sk (𝑡)). Then 𝑓 is also a PRF , since LEOS2IPℓPRFexpand BY[ℓPRFexpand /8] → {0 .. 2ℓPRFexpand −1} is injective; the bias introduced by ◦ ◦ reduction modulo 𝑟J is small because § 5.3 ‘Constants’ on p. 53 defines ℓPRFexpand as 512, while 𝑟J has length 252 R bits. It follows that the distribution of ask, i.e. PRFexpand sk ([0]) : sk ← B[ℓsk ] , is computationally indistinguishable from that of SpendAuthSig.GenPrivate() defined in § 5.4.6.1 ‘Spend Authorization Signature’ on p. 67. R • Similarly, the distribution of nsk, i.e. ToScalar(PRFexpand sk ([1])) : sk ← B[ℓsk ] , is computationally indistinguishable (𝑟) from the uniform distribution on F𝑟J . Since nsk F𝑟J ↦→ reprJ ([nsk] ℋ) J⋆ is bijective, the distribution of ◦ ◦ ◦ ◦ (𝑟) reprJ (nk)will be computationally indistinguishable from uniform on J⋆ (which is the keyspace of PRFnfSapling ). • The zcashd wallet picks diversifiers as in [ZIP-32], rather than using the default diversifier specified above. 4.3 JoinSplit Descriptions A JoinSplit transfer , as specified in § 3.5 ‘JoinSplit Transfers and Descriptions’ on p. 16, is encoded in transactions as a JoinSplit description. Each transaction includes a sequence of zero or more JoinSplit descriptions. When this sequence is non-empty, the transaction also includes encodings of a JoinSplitSig public validating key and signature. Let ℓMerkleSprout , ℓPRFSprout , ℓSeed , Nold , Nnew , and MAX_MONEY be as defined in § 5.3 ‘Constants’ on p. 53. Let hSigCRH be as defined in § 4.1.1 ‘Hash Functions’ on p. 19. Let NoteCommitSprout be as defined in § 4.1.7 ‘Commitment’ on p. 25. Let KASprout be as defined in § 4.1.4 ‘Key Agreement’ on p. 21. Let Sym be as defined in § 4.1.3 ‘Symmetric Encryption’ on p. 20. Let ZKJoinSplit be as defined in § 4.1.12 ‘Zero-Knowledge Proving System’ on p. 28. old new A JoinSplit description consists of (vpub , vpub , rt, nf old 1..N old , cm new enc 1..N , epk, randomSeed, h1..Nold , 𝜋ZKJoinSplit , C1..N ) new new where old • vpub {0 .. MAX_MONEY} is the value that the JoinSplit transfer removes from the transparent transaction ◦ ◦ value pool ; new • vpub {0 .. MAX_MONEY} is the value that the JoinSplit transfer inserts into the transparent transaction value ◦ ◦ pool ; • rt B[ℓMerkleSprout ] is an anchor , as defined in § 3.3 ‘The Block Chain’ on p. 15, for the output treestate of either a ◦ ◦ previous block , or a previous JoinSplit transfer in this transaction. old • nf old 1..N old B[ℓPRFSprout ][N ◦ ◦ ] is the sequence of nullifiers for the input notes; 31

new • cmnew 1..N new NoteCommitSprout .Output[N ◦ ◦ ] is the sequence of note commitments for the output notes; Sprout • epk KA ◦ ◦ .Public is a key agreement public key , used to derive the key for encryption of the transmitted notes ciphertext (§ 4.16 ‘In-band secret distribution (Sprout)’ on p. 46); • randomSeed B[ℓSeed ] is a seed that must be chosen independently at random for each JoinSplit description; ◦ ◦ old • h1..Nold B[ℓPRFSprout ][N ◦ ◦ ] is a sequence of tags that bind hSig to each ask of the input notes; • 𝜋ZKJoinSplit ZKJoinSplit.Proof is a zk proof with primary input (rt, nf old ◦ ◦ 1..N old , cm new new 1..N , vpub , vpub , hSig , h1..Nold ) for new old the JoinSplit statement defined in § 4.15.1 ‘JoinSplit Statement (Sprout)’ on p. 43 (this is a BCTV14 proof before Sapling activation, and a Groth16 proof after Sapling activation); new • Cenc 1..N new Sym.C[N ◦ ◦ ] is a sequence of ciphertext components for the encrypted output notes. The ephemeralKey and encCiphertexts fields together form the transmitted notes ciphertext . The value hSig is also computed from randomSeed, nf old 1..N old , and the joinSplitPubKey of the containing transaction: hSig := hSigCRH(randomSeed, nf old 1..N old , joinSplitPubKey). Consensus rules: old • Elements of a JoinSplit description MUST have the types given above (for example: 0 ≤ vpub ≤ MAX_MONEY new and 0 ≤ vpub ≤ MAX_MONEY). • The proof 𝜋ZKJoinSplit MUST be valid given a primary input formed from the relevant other fields and hSig — i.e. ZKJoinSplit.Verify((rt, nf old 1..N old , cm new old new 1..N , vpub ,vpub , hSig , h1..Nold ), 𝜋ZKJoinSplit ) = 1. new old new • Either vpub or vpub MUST be zero. old • [Canopy onward] vpub MUST be zero. 4.4 Spend Descriptions A Spend transfer , as specified in § 3.6 ‘Spend Transfers, Output Transfers, and their Descriptions’ on p. 16, is encoded in transactions as a Spend description. Each transaction includes a sequence of zero or more Spend descriptions. Each Spend description is authorized by a signature, called the spend authorization signature. Let ℓMerkleSapling and ℓPRFnfSapling be as defined in § 5.3 ‘Constants’ on p. 53. Let ValueCommit.Output be as defined in § 4.1.7 ‘Commitment’ on p. 25. Let SpendAuthSig be as defined in § 4.13 ‘Spend Authorization Signature’ on p. 41. Let ZKSpend be as defined in § 4.1.12 ‘Zero-Knowledge Proving System’ on p. 28. A Spend description consists of (cv, rt, nf, rk, 𝜋ZKSpend , spendAuthSig) where • cv ValueCommit.Output is the value commitment to the value of the input note; ◦ ◦ • rt B[ℓMerkleSapling ] is an anchor , as defined in § 3.3 ‘The Block Chain’ on p. 15, for the output treestate of a previous ◦ ◦ block ; • nf BY[ℓPRFnfSapling /8] is the nullifier for the input note; ◦ ◦ • rk SpendAuthSig.Public is a randomized validating key that should be used to validate spendAuthSig; ◦ ◦ • 𝜋ZKSpend ZKSpend.Proof is a zk-SNARK proof with primary input (cv, rt, nf, rk) for the Spend statement ◦ ◦ defined in § 4.15.2 ‘Spend Statement (Sapling)’ on p. 44; • spendAuthSig SpendAuthSig.Signature is as specified in § 4.13 ‘Spend Authorization Signature’ on p. 41. ◦ ◦ 32

Consensus rules: • Elements of a Spend description MUST be canonical encodings of the types given above. • cv and rk MUST NOT be of small order, i.e. [ℎJ ] cv MUST NOT be 𝒪J and [ℎJ ] rk MUST NOT be 𝒪J . • The proof 𝜋ZKSpend MUST be valid given a primary input formed from the other fields except spendAuthSig — i.e. ZKSpend.Verify((cv, rt, nf, rk), 𝜋ZKSpend ) = 1. • Let SigHash be the SIGHASH transaction hash of this transaction, not associated with an input, as defined in § 4.9 ‘SIGHASH Transaction Hashing’ on p. 37 using SIGHASH_ALL. The spend authorization signature MUST be a valid SpendAuthSig signature over SigHash using rk as the validating key — i.e. SpendAuthSig.Validaterk (SigHash, spendAuthSig) = 1. Non-normative note: The check that rk is not of small order is technically redundant with a check in the Spend circuit , but it is simple and cheap to also check this outside the circuit. 4.5 Output Descriptions An Output transfer , as specified in § 3.6 ‘Spend Transfers, Output Transfers, and their Descriptions’ on p. 16, is encoded in transactions as an Output description. Each transaction includes a sequence of zero or more Output descriptions. There are no signatures associated with Output descriptions. Let ValueCommit.Output be as defined in § 4.1.7 ‘Commitment’ on p. 25. Let ℓMerkleSapling be as defined in § 5.3 ‘Constants’ on p. 53. Let KASapling be as defined in § 4.1.4 ‘Key Agreement’ on p. 21. Let Sym be as defined in § 4.1.3 ‘Symmetric Encryption’ on p. 20. Let ZKOutput be as defined in § 4.1.12 ‘Zero-Knowledge Proving System’ on p. 28. An Output description consists of (cv, cm𝑢 , epk, Cenc , Cout , 𝜋ZKOutput ) where • cv ValueCommit.Output is the value commitment to the value of the output note; ◦ ◦ • cm𝑢 B[ℓMerkleSapling ] is the result of applying ExtractJ(𝑟) (defined in § 5.4.8.4 ‘Hash Extractor for Jubjub’ on p. 74) ◦ ◦ to the note commitment for the output note; • epk KASapling .Public is a key agreement public key , used to derive the key for encryption of the transmitted ◦ ◦ note ciphertext (§ 4.17 ‘In-band secret distribution (Sapling)’ on p. 47); • Cenc Sym.C is a ciphertext component for the encrypted output note; ◦ ◦ • Cout Sym.C is a ciphertext component that allows the holder of a full viewing key to recover the recipient ◦ ◦ diversified transmission key pkd and the ephemeral private key esk (and therefore the entire note plaintext ); • 𝜋ZKOutput ZKOutput.Proof is a zk-SNARK proof with primary input (cv, cm𝑢 , epk) for the Output statement ◦ ◦ defined in § 4.15.3 ‘Output Statement (Sapling)’ on p. 45. Consensus rules: • Elements of an Output description MUST be canonical encodings of the types given above. • cv and epk MUST NOT be of small order, i.e. [ℎJ ] cv MUST NOT be 𝒪J and [ℎJ ] epk MUST NOT be 𝒪J . • The proof 𝜋ZKOutput MUST be valid given a primary input formed from the other fields except Cenc and Cout — i.e. ZKSpend.Verify((cv, cm𝑢 , epk), 𝜋ZKOutput ) = 1. 33

4.6 Sending Notes 4.6.1 Sending Notes (Sprout) In order to send Sprout shielded value, the sender constructs a transaction containing one or more JoinSplit descriptions. This involves first generating a new JoinSplitSig key pair: R joinSplitPrivKey ← JoinSplitSig.GenPrivate() joinSplitPubKey := JoinSplitSig.DerivePublic(joinSplitPrivKey). For each JoinSplit description, the sender chooses randomSeed uniformly at random on B[ℓSeed ] , and selects the input notes. At this point there is sufficient information to compute hSig , as described in the previous section. The sender also chooses ϕ uniformly at random on B[ℓϕ ] . Then it creates each output note with index 𝑖 {1..Nnew }: ◦ ◦ R • Choose uniformly random rcm𝑖 ← NoteCommitSprout .GenTrapdoor(). • Compute ρ𝑖 = PRFρϕ (𝑖, hSig ). • Compute cm𝑖 = NoteCommitSprout rcm𝑖 (apk,𝑖 , v𝑖 , ρ𝑖 ). • Let np𝑖 = (0x00, v𝑖 , ρ𝑖 , rcm𝑖 , memo𝑖 ). np1..Nnew are then encrypted to the recipient transmission keys pkenc,1..Nnew , giving the transmitted notes ciphertext (epk, Cenc 1..N ), as described in § 4.16 ‘In-band secret distribution (Sprout)’ on p. 46. new In order to minimize information leakage, the sender SHOULD randomize the order of the input notes and of the output notes. Other considerations relating to information leakage from the structure of transactions are beyond the scope of this specification. After generating all of the JoinSplit descriptions, the sender obtains dataToBeSigned BY[N] as described in § 4.10 ◦ ◦ ‘Non-malleability (Sprout)’ on p. 38, and signs it with the private JoinSplit signing key : R joinSplitSig ← JoinSplitSig.SignjoinSplitPrivKey (dataToBeSigned) Then the encoded transaction including joinSplitSig is submitted to the network. [Canopy onward] Note: [ZIP-211] specifies that nodes and wallets MUST disable any facilities to send to Sprout addresses. This SHOULD be made clear in user interfaces and API documentation. The facility to send to Sprout addresses is in any case OPTIONAL for a particular node or wallet implementation. 4.6.2 Sending Notes (Sapling) In order to send Sapling shielded value, the sender constructs a transaction containing one or more Output descriptions. Let ValueCommit and NoteCommitSapling be as specified in § 4.1.7 ‘Commitment’ on p. 25. Let KASapling be as defined in § 4.1.4 ‘Key Agreement’ on p. 21. Let DiversifyHash be as defined in § 4.1.1 ‘Hash Functions’ on p. 19. Let reprJ , 𝑟J , and ℎJ be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73. Let ovk be an outgoing viewing key that is intended to be able to decrypt this payment. This may be one of: • the outgoing viewing key for the address (or one of the addresses) from which the payment was sent; • the outgoing viewing key for all payments associated with an “account ”, to be defined in [ZIP-32]; • ⊥, if the sender should not be able to decrypt the payment once it has deleted its own copy. 34

Note: Choosing ovk = ⊥ is useful if the sender prefers to obtain forward secrecy of the payment information with respect to compromise of its own secrets. Let CanopyActivationHeight be as defined in § 5.3 ‘Constants’ on p. 53. Let leadByte be the note plaintext lead byte. This MUST be 0x01 if for the next block , height < CanopyActivationHeight, or 0x02 if height ≥ CanopyActivationHeight. For each Output description, the sender selects a value v {0 .. MAX_MONEY} and a destination Sapling shielded ◦ ◦ payment address (d, pkd ), and then performs the following steps: Check that pkd is of type KASapling .PublicPrimeSubgroup, i.e. it is a valid ctEdwards curve point on the Jubjub curve (as defined in § 5.4.8.3 ‘Jubjub’ on p. 73), and [𝑟J ] pkd = 𝒪J . Calculate gd = DiversifyHash(d) and check that gd ̸= ⊥. R Choose a uniformly random commitment trapdoor rcv ← ValueCommit.GenTrapdoor(). If leadByte = 0x01: R Choose a uniformly random ephemeral private key esk ← KASapling .Private ∖ {0}. R Choose a uniformly random commitment trapdoor rcm ← NoteCommitSapling .GenTrapdoor(). Set rseed := rcm := LEBS2OSP256 (I2LEBSP256 (rcm)). else: R Choose uniformly random rseed ← BY[32] . Derive esk = ToScalar PRFexpand rseed ([4]) . (︀ )︀ Derive rcm = ToScalar PRFexpand rseed ([5]) . (︀ )︀ Calculate cv := ValueCommitrcv (v) cm := NoteCommitSapling rcm (reprJ (gd ), reprJ (pkd ), v) Let np = (leadByte, d, v, rseed, memo). Encrypt np to the recipient diversified transmission key pkd with diversified base gd , and to the outgoing viewing key ovk, giving the transmitted note ciphertext (epk, Cenc , Cout ). This procedure is described in § 4.17.1 ‘Encryption (Sapling)’ on p. 48; it also uses cv and cm to derive the outgoing cipher key , and takes esk as an input. Generate a proof 𝜋ZKOutput for the Output statement in § 4.15.3 ‘Output Statement (Sapling)’ on p. 45. Return (cv, cm, epk, Cenc , Cout , 𝜋ZKOutput ). In order to minimize information leakage, the sender SHOULD randomize the order of Output descriptions in a transaction. Other considerations relating to information leakage from the structure of transactions are beyond the scope of this specification. The encoded transaction is submitted to the network. 4.7 Dummy Notes 4.7.1 Dummy Notes (Sprout) The fields in a JoinSplit description allow for Nold input notes, and Nnew output notes. In practice, we may wish to encode a JoinSplit transfer with fewer input or output notes. This is achieved using dummy notes. Let ℓask and ℓPRFSprout be as defined in § 5.3 ‘Constants’ on p. 53. Let PRFnf be as defined in § 4.1.2 ‘Pseudo Random Functions’ on p. 20. Let NoteCommitSprout be as defined in § 4.1.7 ‘Commitment’ on p. 25. 35

A dummy Sprout input note, with index 𝑖 in the JoinSplit description, is constructed as follows: R [ℓa ] • Generate a new uniformly random spending key aold old sk,𝑖 ← B sk and derive its paying key apk,𝑖 . • Set v𝑖old = 0. R R • Choose uniformly random ρold 𝑖 ← B [ℓPRFSprout ] and rcmold 𝑖 ← NoteCommit Sprout .GenTrapdoor(). • Compute nf old nf old 𝑖 = PRFaold (ρ𝑖 ). sk,𝑖 • Let path𝑖 be a dummy Merkle path for the auxiliary input to the JoinSplit statement (this will not be checked). • When generating the JoinSplit proof , set enforceMerklePath𝑖 to 0. A dummy Sprout output note is constructed as normal but with zero value, and sent to a random shielded payment address. 4.7.2 Dummy Notes (Sapling) In Sapling there is no need to use dummy notes simply in order to fill otherwise unused inputs as in the case of a JoinSplit description; nevertheless it may be useful for privacy to obscure the number of real shielded inputs from Sapling notes. Let ℓsk be as defined in § 5.3 ‘Constants’ on p. 53. Let 𝑟J and reprJ be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73. Let ℋ be as defined in § 4.2.2 ‘Sapling Key Components’ on p. 29. Let PRFnfSapling be as defined in § 4.1.2 ‘Pseudo Random Functions’ on p. 20. Let NoteCommitSapling be as defined in § 4.1.7 ‘Commitment’ on p. 25. A dummy Sapling input note is constructed as follows: R • Choose uniformly random sk ← B[ℓsk ] . • Generate a new diversified payment address (d, pkd ) for sk as described in § 4.2.2 ‘Sapling Key Components’ on p. 29. • Set vold = 0, and set pos = 0. R R • Choose uniformly random rcm ← NoteCommitSapling .GenTrapdoor(). and nsk ← F𝑟J . • Compute nk = [nsk] ℋ and nk⋆ = reprJ (nk). • Compute ρ = cmold = NoteCommitSapling rcm (reprJ (gd ), reprJ (pkd ), vold ). • Compute nf old = PRFnfSapling nk⋆ (reprJ (ρ)). • Construct a dummy Merkle path path for use in the auxiliary input to the Spend statement (this will not be checked, because vold = 0). As in Sprout, a dummy Sapling output note is constructed as normal but with zero value, and sent to a random shielded payment address. 36

4.8 Merkle Path Validity Let MerkleDepth be MerkleDepthSprout for the Sprout note commitment tree, or MerkleDepthSapling for the Sapling note commitment tree. These constants are defined in § 5.3 ‘Constants’ on p. 53. Similarly, let MerkleCRH be MerkleCRHSprout for Sprout, or MerkleCRHSapling for Sapling. The following discussion applies independently to the Sprout and Sapling note commitment trees. Each node in the incremental Merkle tree is associated with a hash value, which is a bit sequence. The layer numbered ℎ, counting from layer 0 at the root , has 2ℎ nodes with indices 0 to 2ℎ − 1 inclusive. Let Mℎ𝑖 be the hash value associated with the node at index 𝑖 in layer ℎ. The nodes at layer MerkleDepth are called leaf nodes. When a note commitment is added to the tree, it occupies the leaf node hash value MMerkleDepth 𝑖 for the next available 𝑖. As-yet unused leaf nodes are associated with a distinguished hash value UncommittedSprout or UncommittedSapling . It is assumed to be infeasible to find a preimage note n such that NoteCommitmentSprout (n) = UncommittedSprout . (No similar assumption is needed for Sapling because we use a representation for UncommittedSapling that cannot occur as an output of NoteCommitmentSapling .) The nodes at layers 0 to MerkleDepth − 1 inclusive are called internal nodes, and are associated with MerkleCRH outputs. Internal nodes are computed from their children in the next layer as follows: for 0 ≤ ℎ < MerkleDepth and 0 ≤ 𝑖 < 2ℎ , Mℎ𝑖 := MerkleCRH(Mℎ+1 ℎ+1 2𝑖 , M2𝑖+1 ). A Merkle path from leaf node MMerkleDepth 𝑖 in the incremental Merkle tree is the sequence [ Mℎsibling(ℎ,𝑖) for ℎ from MerkleDepth down to 1 ] , where (︂ )︂ 𝑖 sibling(ℎ, 𝑖) := floor MerkleDepth−ℎ ⊕1 2 Given such a Merkle path, it is possible to verify that leaf node MMerkleDepth 𝑖 is in a tree with a given root rt = M00 . 4.9 SIGHASH Transaction Hashing Bitcoin and Zcash use signatures and/or non-interactive proofs associated with transaction inputs to authorize spending. Because these signatures or proofs could otherwise be replayed in a different transaction, it is necessary to “bind” them to the transaction for which they are intended. This is done by hashing information about the transaction and (where applicable) the specific input, to give a SIGHASH transaction hash which is then used for the Spend authorization. The means of authorization differs between transparent inputs, inputs to Sprout JoinSplit transfers, and Sapling Spend transfers, but (for a given transaction version) the same SIGHASH transaction hash algorithm is used. In the case of Zcash, the BCTV14 and Groth16 proving systems used are malleable, meaning that there is the potential for an adversary who does not know all of the auxiliary inputs to a proof, to malleate it in order to create a new proof involving related auxiliary inputs [DSDCOPS2001]. This can be understood as similar to a malleability attack on an encryption scheme, in which an adversary can malleate a ciphertext in order to create an encryption of a related plaintext, without knowing the original plaintext. Zcash has been designed to mitigate malleability attacks, as described in § 4.10 ‘Non-malleability (Sprout)’ on p. 38, § 4.12 ‘Balance and Binding Signature (Sapling)’ on p. 39, and § 4.13 ‘Spend Authorization Signature’ on p. 41. 37

To provide additional flexibility when combining Spend authorizations from different sources, Bitcoin defines sev- eral SIGHASH types that cover various parts of a transaction [Bitcoin-SigHash]. One of these types is SIGHASH_ALL, which is used for Zcash-specific signatures, i.e. JoinSplit signatures, spend authorization signatures, and binding signatures. In these cases the SIGHASH transaction hash is not associated with a transparent input , and so the input to hashing excludes all of the scriptSig fields in the non-Zcash-specific parts of the transaction. In Zcash, all SIGHASH types are extended to cover the Zcash-specific fields nJoinSplit, vJoinSplit, and if present joinSplitPubKey. These fields are described in § 7.1 ‘Transaction Encoding and Consensus’ on p. 85. The hash does not cover the field joinSplitSig. After Overwinter activation, all SIGHASH types are also extended to cover transaction fields introduced in that upgrade, and similarly after Sapling activation. The original SIGHASH algorithm defined by Bitcoin suffered from some deficiencies as described in [ZIP-143]; in Zcash these are to be addressed by changing this algorithm as part of the Overwinter upgrade. [Pre-Overwinter] The SIGHASH algorithm used prior to Overwinter activation, i.e. for version 1 and 2 transactions, will be defined in [ZIP-76] (to be written). [Overwinter only, pre-Sapling] The SIGHASH algorithm used after Overwinter activation and before Sapling activation, i.e. for version 3 transactions, is defined in [ZIP-143]. [Sapling onward] The SIGHASH algorithm used after Sapling activation, i.e. for version 4 transactions, is defined in [ZIP-243]. [Blossom onward] The SIGHASH algorithm used after Blossom activation is the same as for Sapling, but using the Blossom consensus branch ID 0x2BB40E60 as defined in [ZIP-206]. [Heartwood onward] The SIGHASH algorithm used after Heartwood activation is the same as for Sapling, but using the Heartwood consensus branch ID 0xF5B9230B as defined in [ZIP-250]. [Canopy onward] The SIGHASH algorithm used after Canopy activation is the same as for Sapling, but using the Canopy consensus branch ID 0xE9FF75A6 as defined in [ZIP-251]. 4.10 Non-malleability (Sprout) Let dataToBeSigned be the hash of the transaction, not associated with an input, using the SIGHASH_ALL SIGHASH type. In order to ensure that a JoinSplit description is cryptographically bound to the transparent inputs and outputs new old corresponding to vpub and vpub , and to the other JoinSplit descriptions in the same transaction, an ephemeral JoinSplitSig key pair is generated for each transaction, and the dataToBeSigned is signed with the private signing key of this key pair. The corresponding public validating key is included in the transaction encoding as joinSplitPubKey. JoinSplitSig is instantiated in § 5.4.5 ‘Ed25519’ on p. 63. If nJoinSplit is zero, the joinSplitPubKey and joinSplitSig fields are omitted. Otherwise, a transaction has a correct JoinSplit signature if and only if JoinSplitSig.ValidatejoinSplitPubKey (dataToBeSigned, joinSplitSig) = 1. Let hSig be computed as specified in § 4.3 ‘JoinSplit Descriptions’ on p. 31. Let PRFpk be as defined in § 4.1.2 ‘Pseudo Random Functions’ on p. 20. For each 𝑖 ∈ {1..Nold }, the creator of a JoinSplit description calculates h𝑖 = PRFpkold (𝑖, hSig ). ask,𝑖 The correctness of h1..Nold is enforced by the JoinSplit statement given in § 4.15.1 ‘JoinSplit Statement (Sprout)’ on p. 43. This ensures that a holder of all of the aold sk,1..N old for every JoinSplit description in the transaction has authorized the use of the private signing key corresponding to joinSplitPubKey to sign this transaction. 38

4.11 Balance (Sprout) In Bitcoin, all inputs to and outputs from a transaction are transparent. The total value of transparent outputs must not exceed the total value of transparent inputs. The net value of transparent inputs minus transparent outputs is transferred to the miner of the block containing the transaction; it is added to the miner subsidy in the coinbase transaction of the block . Zcash Sprout extends this by adding JoinSplit transfers. Each JoinSplit transfer can be seen, from the perspective of the transparent transaction value pool , as an input and an output simultaneously. old new vpub takes value from the transparent transaction value pool and vpub adds value to the transparent transaction old new value pool . As a result, vpub is treated like an output value, whereas vpub is treated like an input value. old As defined in [ZIP-209], the Sprout chain value pool balance for a given block chain is the sum of all vpub field new values for transactions in the block chain, minus the sum of all vpub fields values for transactions in the block chain. Consensus rule: If the Sprout chain value pool balance would become negative in the block chain created as a result of accepting a block , then all nodes MUST reject the block as invalid. Unlike original Zerocash [BCGGMTV2014], Zcash does not have a distinction between Mint and Pour operations. old The addition of vpub to a JoinSplit description subsumes the functionality of both Mint and Pour. Also, a difference in the number of real input notes does not by itself cause two JoinSplit descriptions to be distinguishable. old new As stated in § 4.3 ‘JoinSplit Descriptions’ on p. 31, either vpub or vpub MUST be zero. No generality is lost because, old new if a transaction in which both vpub and vpub were nonzero were allowed, it could be replaced by an equivalent old new one in which min(vpub , vpub ) is subtracted from both of these values. This restriction helps to avoid unnecessary distinctions between transactions according to client implementation. 4.12 Balance and Binding Signature (Sapling) Sapling adds Spend transfers and Output transfers to the transparent and JoinSplit transfers present in Sprout. The net value of Spend transfers minus Output transfers in a transaction is called the balancing value, measured in zatoshi as a signed integer vbalance . vbalance is encoded explicitly in a transaction as the field valueBalance. (Transaction fields are described in § 7.1 ‘Transaction Encoding and Consensus’ on p. 85.) A positive balancing value takes value from the Sapling transaction value pool and adds it to the transparent transaction value pool . A negative balancing value does the reverse. As a result, positive vbalance is treated like an input to the transparent transaction value pool , whereas negative vbalance is treated like an output from that pool. As defined in [ZIP-209], the Sapling chain value pool balance for a given block chain is the negation of the sum of all valueBalance field values for transactions in the block chain. Consensus rule: If the Sapling chain value pool balance would become negative in the block chain created as a result of accepting a block , then all nodes MUST reject the block as invalid. Consistency of vbalance with the value commitments in Spend descriptions and Output descriptions is enforced by the binding signature. This signature has a dual rôle in the Sapling protocol: • To prove that the total value spent by Spend transfers, minus that produced by Output transfers, is consistent with the vbalance field of the transaction; • To prove that the signer knew the randomness used for the Spend and Output value commitments, in order to prevent Output descriptions from being replayed by an adversary in a different transaction. (A Spend description already cannot be replayed due to its spend authorization signature.) 39

Instead of generating a key pair at random, we generate it as a function of the value commitments in the Spend descriptions and Output descriptions of the transaction, and the balancing value. Let J(𝑟) , J(𝑟)* , and 𝑟J be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73. Let ValueCommit, 𝒱, and ℛ be as defined in § 5.4.7.3 ‘Homomorphic Pedersen commitments’ on p. 69: {︁ }︁ 𝑟 −1 𝑟 −1 ValueCommit ValueCommit.Trapdoor × − J2 .. J2 ◦ ◦ → ValueCommit.Output; 𝒱 J(𝑟)* is the value base in ValueCommit; ◦ ◦ ℛ J(𝑟)* is the randomness base in ValueCommit. ◦ ◦ BindingSig, , and are instantiated in § 5.4.6.2 ‘Binding Signature’ on p. 68. These and the derived notation , N N 𝑖=1 , , and 𝑖=1 are specified in § 4.1.6.2 ‘Signature with Signing Key to Validating Key Monomorphism’ on p. 24. Suppose that the transaction has: • 𝑛 Spend descriptions with value commitments cvold old old 1..𝑛 , committing to values v1..𝑛 with randomness rcv1..𝑛 ; • 𝑚 Output descriptions with value commitments cvnew new new 1..𝑚 , committing to values v1..𝑚 with randomness rcv1..𝑚 ; • balancing value vbalance . ∑︀𝑛 ∑︀𝑚 In a correctly constructed transaction, vbalance = vold − 𝑖=1 𝑖 vnew , but validators cannot check this directly 𝑗=1 𝑗 because the values are hidden by the commitments. Instead, validators calculate the transaction binding validating key as: (︃ )︃ (︃ )︃ 𝑛 𝑚 old new ValueCommit0 vbalance . (︀ )︀ bvk := cv𝑖 cv𝑗 𝑖=1 𝑗=1 (This key is not encoded explicitly in the transaction and must be recalculated.) The signer knows rcvold new 1..𝑛 and rcv1..𝑚 , and so can calculate the corresponding signing key as: (︃ )︃ (︃ )︃ 𝑛 𝑚 bsk := rcvold 𝑖 rcvnew 𝑗 . 𝑖=1 𝑗=1 In order to check for implementation faults, the signer SHOULD also check that bvk = BindingSig.DerivePublic(bsk). Let SigHash be the SIGHASH transaction hash as defined in [ZIP-243], not associated with an input, using the SIGHASH type SIGHASH_ALL. A validator checks balance by validating that BindingSig.Validatebvk (SigHash, bindingSig) = 1. We now explain why this works. A binding signature proves knowledge of the discrete logarithm bsk of bvk with respect to ℛ. That is, bvk = [bsk] ℛ. So the value 0 and randomness bsk is an opening of the Pedersen commitment bvk = ValueCommitbsk (0). By the binding property of the Pedersen commitment , it is infeasible to find another opening of this commitment to a different value. Similarly, the binding property of the value commitments in the Spend descriptions and Output descriptions ensures that an adversary cannot find an opening to more than one value for any of those commitments, i.e. we old may assume that v1..𝑛 are determined by cvold new new 1..𝑛 , and that v1..𝑚 are determined by cv1..𝑚 . We may also assume, from Knowledge Soundness of Groth16, that the Spend proofs could not have been generated without knowing rcvold 1..𝑛 (mod 𝑟J ), and the Output proofs could not have been generated without knowing rcvnew 1..𝑚 (mod 𝑟J ). 40

Using the fact that ValueCommitrcv (v) = [v] 𝒱 [rcv] ℛ, the expression for bvk above is equivalent to: [︃(︃ )︃ (︃ )︃ ]︃ [︃(︃ )︃ (︃ )︃]︃ 𝑛 𝑚 𝑛 𝑚 bvk = v𝑖old v𝑗new vbalance 𝒱 rcvold 𝑖 rcvnew 𝑗 ℛ 𝑖=1 𝑗=1 𝑖=1 𝑗=1 (︃ 𝑛 𝑚 )︃ ∑︁ ∑︁ = ValueCommitbsk v𝑖old − v𝑗new −v balance . 𝑖=1 𝑗=1 𝑛 𝑚 Let v* = ∑︁ ∑︁ v𝑖old − v𝑗new − vbalance . 𝑖=1 𝑗=1 * Suppose that v = vbad ̸= 0 (mod 𝑟J ). Then bvk = ValueCommitbsk (vbad ). If the adversary were able to find the discrete logarithm of this bvk with respect to ℛ, say bsk′ (as needed to create a valid binding signature), then (vbad , bsk) and (0, bsk′ ) would be distinct openings of bvk to different values, breaking the binding property of the value commitment scheme. * * The above argument {︁ shows only that }︁ v = 0 (mod 𝑟J ); in order to show that v = 0, we will also demonstrate that it 𝑟J −1 𝑟J −1 does not overflow − 2 .. 2 . old The Spend statements prove that all of v1..𝑛 are in {0 .. 2ℓvalue −1}. Similarly the Output statements prove that all of new ℓvalue balance v1..𝑚 are in {0 .. 2 −1}. v is encoded in the transaction as a signed two’s complement 64-bit integer in the range {−263 .. 263 − 1}. ℓvalue is defined as 64, so v* is in the range {−𝑚 64 63 64 1) + 2)︀63 }. The )︀ · (2 − 1) − 2 + 1 .. 𝑛 · (2 (︀−2000000 maximum transaction size of 2 MB limits 𝑛 to at most floor 384 = 5208 and 𝑚 to at most floor (︀ 2000000 {︁ 948 = 2109, }︁ 𝑟J −1 𝑟J −1 ensuring v* ∈ {−38913406623490299131842 .. 96079866507916199586728} which is a subrange of − 2 .. 2 . Thus checking the binding signature ensures that the transaction balances, without the individual values of the Spend descriptions and Output descriptions being revealed. In addition this proves that the signer, knowing the -sum of the value commitment randomnesses, authorized a transaction with the given SIGHASH transaction hash by signing SigHash. Note: The spender MAY reveal any strict subset of the value commitment randomnesses to other parties that are cooperating to create the transaction. If all of the value commitment randomnesses are revealed, that could allow replaying the Output descriptions of the transaction. Non-normative note: The technique of checking signatures using a validating key derived from a sum of Pedersen commitments is also used in the Mimblewimble protocol [Jedusor2016]. The private key bsk acts as a “synthetic blinding factor ”, in the sense that it is synthesized from the other blinding factors (trapdoors) rcvold new 1..𝑛 and rcv1..𝑚 ; this technique is also used in Bulletproofs [Dalek-notes]. 4.13 Spend Authorization Signature SpendAuthSig is used in Sapling to prove knowledge of the spending key authorizing spending of an input note. It is instantiated in § 5.4.6.1 ‘Spend Authorization Signature’ on p. 67. Knowledge of the spending key could have been proven directly in the Spend statement , similar to the check in § 4.15.1 ‘JoinSplit Statement (Sprout)’ on p. 43 that is part of the JoinSplit statement . The motivation for a separate signature is to allow devices that are limited in memory and computational capacity, such as hardware wallets, to authorize a Sapling shielded Spend. Typically such devices cannot create, and may not be able to verify, zk-SNARK proofs for a statement of the size needed using the BCTV14 or Groth16 proving systems. The validating key of the signature must be revealed in the Spend description so that the signature can be checked by validators. To ensure that the validating key cannot be linked to the shielded payment address or spending key from which the note was spent, we use a signature scheme with re-randomizable keys. The Spend statement proves that this validating key is a re-randomization of the spend authorization address key ak with a randomizer known to the signer. The spend authorization signature is over the SIGHASH transaction hash, so that it cannot be replayed in other transactions. 41

Let SigHash be the SIGHASH transaction hash as defined in [ZIP-243], not associated with an input, using the SIGHASH type SIGHASH_ALL. Let ask be the spend authorization private key as defined in § 4.2.2 ‘Sapling Key Components’ on p. 29. For each Spend description, the signer chooses a fresh spend authorization randomizer 𝛼: R 1. Choose 𝛼 ← SpendAuthSig.GenRandom(). 2. Let rsk = SpendAuthSig.RandomizePrivate(𝛼, ask). 3. Let rk = SpendAuthSig.DerivePublic(rsk). 4. Generate a proof 𝜋ZKSpend of the Spend statement (§ 4.15.2 ‘Spend Statement (Sapling)’ on p. 44), with 𝛼 in the auxiliary input and rk in the primary input . 5. Let spendAuthSig = SpendAuthSig.Signrsk (SigHash). The resulting spendAuthSig and 𝜋ZKSpend are included in the Spend description. Note: If the spender is computationally or memory-limited, step 4 (and only step 4) MAY be delegated to a different party that is capable of performing the zk-SNARK proof . In this case privacy will be lost to that party since it needs ak and the proof authorizing key nsk; this allows also deriving the nk component of the full viewing key . Together ak and nk are sufficient to recognize spent notes and to recognize and decrypt incoming notes. However, the other party will not obtain spending authority for other transactions, since it is not able to create a spend authorization signature by itself. 4.14 Note Commitments and Nullifiers A transaction that contains one or more JoinSplit descriptions or Spend descriptions, when entered into the block chain, appends to the note commitment tree with all constituent note commitments. All of the constituent nullifiers are also entered into the nullifier set of the associated treestate. A transaction is not valid if it would have added a nullifier to the nullifier set that already exists in the set (see § 3.8 ‘Nullifier Sets’ on p. 18). In Sprout, each note has a ρ component. In Sapling, each positioned note has an associated ρ value which is computed from its note commitment cm and note position pos as follows: ρ := MixingPedersenHash(cm, pos). MixingPedersenHash is defined in § 5.4.1.8 ‘Mixing Pedersen Hash Function’ on p. 60. Let PRFnf and PRFnfSapling be as instantiated in § 5.4.2 ‘Pseudo Random Functions’ on p. 61. For a Sprout note, the nullifier is derived as PRFnf ask (ρ), where ask is the spending key associated with the note. For a Sapling note, the nullifier is derived as PRFnfSapling nk⋆ (ρ⋆), where nk⋆ is a representation of the nullifier deriving key associated with the note and ρ⋆ = reprJ (ρ). 42

4.15 Zk-SNARK Statements 4.15.1 JoinSplit Statement (Sprout) Let ℓMerkleSprout , ℓPRFSprout , MerkleDepthSprout , ℓvalue , ℓask , ℓϕ , ℓhSig , Nold , Nnew be as defined in § 5.3 ‘Constants’ on p. 53. Let PRFaddr , PRFnf , PRFpk , and PRFρ be as defined in § 4.1.2 ‘Pseudo Random Functions’ on p. 20. Let NoteCommitSprout be as defined in § 4.1.7 ‘Commitment’ on p. 25, and let NoteSprout and NoteCommitmentSprout be as defined in § 3.2 ‘Notes’ on p. 13. A valid instance of a JoinSplit statement , 𝜋ZKJoinSplit , assures that given a primary input : rt B[ℓMerkleSprout ] , (︀ ◦ ◦ old nf old 1..N ◦ old ◦ B [ℓPRFSprout ][N ] , new cm1..N ◦ NoteCommitSprout .Output[N ] , new new ◦ old ◦ ℓvalue vpub ◦ {0 .. 2 −1}, new ◦ ℓvalue vpub ◦ {0 .. 2 −1}, hSig ◦◦ B[ℓhSig ] , old )︀ h1..Nold ◦◦ B[ℓPRFSprout ][N ] , the prover knows an auxiliary input : Sprout old path1..Nold B[ℓMerkleSprout ][MerkleDepth ][N ] (︀ ◦ ◦ , Sprout old pos1..Nold {0 .. 2MerkleDepth ◦ ◦ −1}[N ] , old old n1..Nold NoteSprout[N ] , ◦ ◦ old aold sk,1..N old B[ℓask ][N ] , ◦ ◦ new new n1..Nnew NoteSprout[N ◦ ◦ ] , [ℓϕ ] ϕ B◦ ◦ , old enforceMerklePath1..Nold B[N ◦ ◦ ] )︀ , where: for each 𝑖 ∈ {1..Nold }: n𝑖old = (aold old old old pk,𝑖 , v𝑖 , ρ𝑖 , rcm𝑖 ); for each 𝑖 ∈ {1..Nnew }: n𝑖new = (anew new new new pk,𝑖 , v𝑖 , ρ𝑖 , rcm𝑖 ) such that the following conditions hold: Merkle path validity for each 𝑖 ∈ {1..Nold } | enforceMerklePath𝑖 = 1: (path𝑖 , pos𝑖 ) is a valid Merkle path (see § 4.8 ‘Merkle Path Validity’ on p. 37) of depth MerkleDepthSprout from NoteCommitmentSprout (n𝑖old ) to the anchor rt. Note: Merkle path validity covers conditions 1. (a) and 1. (d) of the NP statement in [BCGGMTV2014, section 4.2]. Merkle path enforcement for each 𝑖 ∈ {1..Nold }, if v𝑖old ̸= 0 then enforceMerklePath𝑖 = 1. old new old ∑︀N ∑︀N Balance vpub + vold = vpub new 𝑖=1 𝑖 + 𝑖=1 v𝑖new ∈ {0 .. 2ℓvalue −1}. Nullifier integrity for each 𝑖 ∈ {1..Nold }: nf old nf old 𝑖 = PRFaold (ρ𝑖 ). sk,𝑖 Spend authority for each 𝑖 ∈ {1..Nold }: aold addr pk,𝑖 = PRFaold (0). sk,𝑖 old Non-malleability for each 𝑖 ∈ {1..N }: h𝑖 = PRFpkold (𝑖, hSig ). ask,𝑖 Uniqueness of ρnew 𝑖 for each 𝑖 ∈ {1..Nnew }: ρnew 𝑖 = PRFρϕ (𝑖, hSig ). Note commitment integrity for each 𝑖 ∈ {1..Nnew }: cmnew 𝑖 = NoteCommitmentSprout (n𝑖new ). For details of the form and encoding of proofs, see § 5.4.9.1 ‘BCTV14’ on p. 75. 43

4.15.2 Spend Statement (Sapling) Let ℓMerkleSapling , ℓPRFnfSapling , and ℓscalar be as defined in § 5.3 ‘Constants’ on p. 53. Let ValueCommit and NoteCommitSapling be as specified in § 4.1.7 ‘Commitment’ on p. 25. Let SpendAuthSig be as defined in § 5.4.6.1 ‘Spend Authorization Signature’ on p. 67. Let J, J(𝑟) , reprJ , 𝑞J , 𝑟J , and ℎJ be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73. Let ExtractJ(𝑟) J(𝑟) → B[ℓMerkleSapling ] be as defined in § 5.4.8.4 ‘Hash Extractor for Jubjub’ on p. 74. ◦ ◦ Let ℋ be as defined in § 4.2.2 ‘Sapling Key Components’ on p. 29. A valid instance of a Spend statement , 𝜋ZKSpend , assures that given a primary input : rt B[ℓMerkleSapling ] , (︀ ◦ ◦ cvold ValueCommit.Output, ◦ ◦ nf old BY[ℓPRFnfSapling /8] , ◦ ◦ rk SpendAuthSig.Public , ◦ )︀ ◦ the prover knows an auxiliary input : Sapling path B[ℓMerkle ][MerkleDepth ] (︀ ◦ ◦ , Sapling pos {0 .. 2MerkleDepth ◦ ◦ −1}, gd J, ◦ ◦ pkd J, ◦ ◦ old v {0 .. 2ℓvalue −1}, ◦ ◦ rcvold {0 .. 2ℓscalar −1}, ◦ ◦ cmold J, ◦ ◦ rcmold {0 .. 2ℓscalar −1}, ◦ ◦ 𝛼 {0 .. 2ℓscalar −1}, ◦ ◦ ak SpendAuthSig.Public, ◦ ◦ nsk {0 .. 2ℓscalar −1} ◦ )︀ ◦ such that the following conditions hold: Note commitment integrity cmold = NoteCommitSapling old (reprJ (gd ), reprJ (pkd ), v old ). rcm Merkle path validity Either vold = 0; or (path, pos) is a valid Merkle path of depth MerkleDepthSapling , as defined in § 4.8 ‘Merkle Path Validity’ on p. 37, from cm𝑢 = ExtractJ(𝑟) (cmold ) to the anchor rt. Value commitment integrity cvold = ValueCommitrcvold (vold ). Small order checks gd and ak are not of small order, i.e. [ℎJ ] gd ̸= 𝒪J and [ℎJ ] ak ̸= 𝒪J . Nullifier integrity nf old = PRFnfSapling nk⋆ (ρ⋆) where nk⋆ = reprJ ([nsk] ℋ) ρ⋆ = reprJ MixingPedersenHash(cmold , pos) . (︀ )︀ Spend authority rk = SpendAuthSig.RandomizePublic(𝛼, ak). Diversified address integrity pkd = [ivk] gd where ivk ivk = CRH (ak⋆, nk⋆) ak⋆ = reprJ (ak). For details of the form and encoding of Spend statement proofs, see § 5.4.9.2 ‘Groth16’ on p. 76. 44

Notes: • Public and auxiliary inputs MUST be constrained to have the types specified. In particular, see § A.3.3.2 ‘ctEdwards [de]compression and validation’ on p. 142, for required validity checks on compressed repre- sentations of Jubjub curve points. The ValueCommit.Output and SpendAuthSig.Public types also represent points, i.e. J. • In the Merkle path validity check, each layer does not check that its input bit sequence is a canonical encoding (in {0 .. 𝑟S − 1}) of the integer from the previous layer . • It is not checked in the Spend statement that rk is not of small order. However, this is checked outside the Spend statement , as specified in § 4.4 ‘Spend Descriptions’ on p. 32. • It is not checked that rcvold < 𝑟J or that rcmold < 𝑟J . • SpendAuthSig.RandomizePublic(𝛼, ak) = ak+[𝛼] 𝒢. (𝒢 is as defined in § 5.4.6.1 ‘Spend Authorization Signature’ on p. 67.) 4.15.3 Output Statement (Sapling) Let ℓMerkleSapling and ℓscalar be as defined in § 5.3 ‘Constants’ on p. 53. Let ValueCommit and NoteCommitSapling be as specified in § 4.1.7 ‘Commitment’ on p. 25. Let J, reprJ , and ℎJ be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73. A valid instance of an Output statement , 𝜋ZKOutput , assures that given a primary input : (︀ new cv ValueCommit.Output, ◦ ◦ cm𝑢 B)︀[ℓMerkleSapling ] , ◦ ◦ epk J , ◦ ◦ the prover knows an auxiliary input : (gd J,◦ ◦ pk⋆d B[ℓJ ] , ◦ ◦ vnew {0 .. 2ℓvalue −1}, ◦ ◦ rcvnew {0 .. 2ℓscalar −1}, ◦ ◦ rcmnew {0 .. 2ℓscalar −1}, ◦ ◦ esk {0 .. 2ℓscalar −1}) ◦ ◦ such that the following conditions hold: cm𝑢 = ExtractJ(𝑟) NoteCommitSapling new )︀ ) , where g⋆d = reprJ (gd ). (︀ Note commitment integrity rcm new (g⋆d , pk⋆d , v Value commitment integrity cvnew = ValueCommitrcvnew (vnew ). Small order check gd is not of small order, i.e. [ℎJ ] gd ̸= 𝒪J . Ephemeral public key integrity epk = [esk] gd . For details of the form and encoding of Output statement proofs, see § 5.4.9.2 ‘Groth16’ on p. 76. 45

Notes: • Public and auxiliary inputs MUST be constrained to have the types specified. In particular, see § A.3.3.2 ‘ctEdwards [de]compression and validation’ on p. 142, for required validity checks on compressed repre- sentations of Jubjub curve points. The ValueCommit.Output type also represents points, i.e. J. • The validity of pk⋆d is not checked in this circuit. • It is not checked that rcvold < 𝑟J or that rcmold < 𝑟J . 4.16 In-band secret distribution (Sprout) In Sprout, the secrets that need to be transmitted to a recipient of funds in order for them to later spend, are v, ρ, and rcm. A memo field (§ 3.2.1 ‘Note Plaintexts and Memo Fields’ on p. 14) is also transmitted. To transmit these secrets securely to a recipient without requiring an out-of-band communication channel, the transmission key pkenc is used to encrypt them. The recipient’s possession of the associated incoming viewing key ivk is used to reconstruct the original note and memo field . A single ephemeral public key is shared between encryptions of the Nnew shielded outputs in a JoinSplit description. All of the resulting ciphertexts are combined to form a transmitted notes ciphertext . For both encryption and decryption, • let Sym be the scheme instantiated in § 5.4.3 ‘Symmetric Encryption’ on p. 62; • let KDFSprout be the Key Derivation Function instantiated in § 5.4.4.2 ‘Sprout Key Derivation’ on p. 63; • let KASprout be the key agreement scheme instantiated in § 5.4.4.1 ‘Sprout Key Agreement’ on p. 62; • let hSig be the value computed for this JoinSplit description in § 4.3 ‘JoinSplit Descriptions’ on p. 31. 4.16.1 Encryption (Sprout) Let KASprout be the key agreement scheme instantiated in § 5.4.4.1 ‘Sprout Key Agreement’ on p. 62. Let pkenc,1..Nnew be the transmission keys for the intended recipient addresses of each new note. Let np1..Nnew be Sprout note plaintexts defined in § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ on p. 77. Then to encrypt: • Generate a new KASprout (public, private) key pair (epk, esk). • For 𝑖 ∈ {1..Nnew }, – Let Penc 𝑖 be the raw encoding of np𝑖 . – Let sharedSecret𝑖 := KASprout .Agree(esk, pkenc,𝑖 ). – Let Kenc 𝑖 := KDFSprout (𝑖, hSig , sharedSecret𝑖 , epk, pkenc,𝑖 ). – Let Cenc 𝑖 := Sym.EncryptKenc 𝑖 (Penc 𝑖 ). The resulting transmitted notes ciphertext is (epk, Cenc 1..N ). new Note: It is technically possible to replace Cenc𝑖 for a given note with a random (and undecryptable) dummy ciphertext, relying instead on out-of-band transmission of the note to the recipient. In this case the ephemeral key MUST still be generated as a random public key (rather than a random bit sequence) to ensure indistinguishability from other JoinSplit descriptions. This mode of operation raises further security considerations, for example of how to validate a Sprout note received out-of-band, which are not addressed in this document. 46

4.16.2 Decryption (Sprout) Let ivk = (apk , skenc ) be the recipient’s incoming viewing key , and let pkenc be the corresponding transmission key derived from skenc as specified in § 4.2.1 ‘Sprout Key Components’ on p. 29. Let cm1..Nnew be the note commitments of each output coin. Then for each 𝑖 ∈ {1..Nnew }, the recipient will attempt to decrypt that ciphertext component (epk, Cenc 𝑖 ) as follows: let sharedSecret𝑖 = KASprout .Agree(skenc , epk) let Kenc 𝑖 = KDFSprout (𝑖, hSig , sharedSecret𝑖 , epk, pkenc ) return DecryptNoteSprout(Kenc enc 𝑖 , C𝑖 , cm𝑖 , apk ). DecryptNoteSprout(Kenc enc 𝑖 , C𝑖 , cm𝑖 , apk ) is defined as follows: let Penc 𝑖 = Sym.DecryptKenc 𝑖 (Cenc 𝑖 ) if Penc 𝑖 = ⊥, return ⊥ extract np𝑖 = (leadByte𝑖 BY, v𝑖 {0 .. 2ℓvalue −1}, ρ𝑖 B[ℓPRFSprout ] , rcm𝑖 NoteCommitSprout .Trapdoor, memo𝑖 BY[512] ) ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ from Penc 𝑖 if leadByte𝑖 ̸= 0x00 or NoteCommitmentSprout ((apk , v𝑖 , ρ𝑖 , rcm𝑖 )) ̸= cm𝑖 , return ⊥, else return np𝑖 . To test whether a note is unspent in a particular block chain also requires the spending key ask ; the coin is unspent if and only if nf = PRFnf ask (ρ) is not in the nullifier set for that block chain. Notes: • The decryption algorithm corresponds to step 3 (b) i. and ii. (first bullet point) of the Receive algorithm shown in [BCGGMTV2014, Figure 2]. • A note can change from being unspent to spent as a node’s view of the best valid block chain is extended by new transactions. Also, block chain reorganizations can cause a node to switch to a different best valid block chain that does not contain the transaction in which a note was output. See § 8.7 ‘In-band secret distribution’ on p. 104 for further discussion of the security and engineering rationale behind this encryption scheme. 4.17 In-band secret distribution (Sapling) In Sapling, the secrets that need to be transmitted to a recipient of funds in order for them to later spend, are d, v, and rcm. A memo field (§ 3.2.1 ‘Note Plaintexts and Memo Fields’ on p. 14) is also transmitted. To transmit these secrets securely to a recipient without requiring an out-of-band communication channel, the diversified transmission key pkd is used to encrypt them. The recipient’s possession of the associated incoming viewing key ivk is used to reconstruct the original note and memo field . Unlike in a Sprout JoinSplit description, each Sapling shielded output is encrypted by a fresh ephemeral public key . For both encryption and decryption, • let ℓovk be as defined in § 5.3 ‘Constants’ on p. 53; • let Sym be the scheme instantiated in § 5.4.3 ‘Symmetric Encryption’ on p. 62; • let KDFSapling be the Key Derivation Function instantiated in § 5.4.4.4 ‘Sapling Key Derivation’ on p. 63; • let KASapling be the key agreement scheme instantiated in § 5.4.4.3 ‘Sapling Key Agreement’ on p. 63; • let ℓJ and reprJ be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73; • let ExtractJ(𝑟) be as defined in § 5.4.8.4 ‘Hash Extractor for Jubjub’ on p. 74; • let PRFock be as instantiated in § 5.4.2 ‘Pseudo Random Functions’ on p. 61. 47

4.17.1 Encryption (Sapling) Let pkd KASapling .PublicPrimeSubgroup be the diversified transmission key for the intended recipient address of a ◦ ◦ new Sapling note, and let gd KASapling .PublicPrimeSubgroup be the corresponding diversified base computed as ◦ ◦ DiversifyHash(d). Since Sapling note encryption is used only in the context of § 4.6.2 ‘Sending Notes (Sapling)’ on p. 34, we may assume that gd has already been calculated and is not ⊥. Also, the ephemeral private key esk has been chosen. Let ovk BY[ℓovk /8] ∪ {⊥} be as described in § 4.6.2 ‘Sending Notes (Sapling)’ on p. 34, i.e. the outgoing viewing key ◦ ◦ of the shielded payment address from which the note is being spent, or an outgoing viewing key associated with a [ZIP-32] account, or ⊥. Let np = (leadByte, d, v, rseed, memo) be the Sapling note plaintext . np is encoded as defined in § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ on p. 77. Let cv be the value commitment for the new note, and let cm be the note commitment . (These are needed to derive the outgoing cipher key ock in order to produce the Output ciphertext Cout .) Then to encrypt: let Penc be the raw encoding of np let epk = KASapling .DerivePublic(esk, gd ) let ephemeralKey = LEBS2OSPℓJ reprJ (epk) (︀ )︀ let sharedSecret = KASapling .Agree(esk, pkd ) let Kenc = KDFSapling (sharedSecret, ephemeralKey) let Cenc = Sym.EncryptKenc (Penc ) if ovk = ⊥: R R choose random ock ← Sym.K and op ← BY[(ℓJ +256)/8] else: let cv = LEBS2OSPℓJ reprJ (cv) (︀ )︀ let cmu = LEBS2OSP256 ExtractJ(𝑟) (cm) (︀ )︀ let ock = PRFock ovk (cv, cmu, ephemeralKey) let op = LEBS2OSPℓJ +256 reprJ (pkd ) || I2LEBSP256 (esk) (︀ )︀ let Cout = Sym.Encryptock (op) The resulting transmitted note ciphertext is (ephemeralKey, Cenc , Cout ). Note: It is technically possible to replace Cenc for a given note with a random (and undecryptable) dummy ciphertext, relying instead on out-of-band transmission of the note to the recipient. In this case the ephemeral key MUST still be generated as a random public key (rather than a random bit sequence) to ensure indistinguishability from other Output descriptions. This mode of operation raises further security considerations, for example of how to validate a Sapling note received out-of-band, which are not addressed in this document. 4.17.2 Decryption using an Incoming Viewing Key (Sapling) Let ivk {0 .. 2ℓivk −1} be the recipient’s incoming viewing key , as specified in § 4.2.2 ‘Sapling Key Components’ on ◦ ◦ p. 29. Let (ephemeralKey, Cenc , Cout ) be the transmitted note ciphertext from the Output description. Let cmu be that field of the Output description (encoding the 𝑢-coordinate of the note commitment ). Let the constant CanopyActivationHeight be as defined in § 5.3 ‘Constants’ on p. 53. Let height be the block height of the block containing this transaction. 48

The recipient will attempt to decrypt the ephemeralKey and Cenc components of the transmitted note ciphertext as follows: let epk = abstJ (ephemeralKey) if epk = ⊥, return ⊥ let sharedSecret = KASapling .Agree(ivk, epk) let Kenc = KDFSapling (sharedSecret, ephemeralKey) let Penc = Sym.DecryptKenc (Cenc ) if Penc = ⊥, return ⊥ extract np = (leadByte BY, d B[ℓd ] , v {0 .. 2ℓvalue −1}, rseed BY[32] , memo BY[512] ) from Penc ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ [Pre-Canopy] if leadByte ̸= 0x01, return ⊥ [Pre-Canopy] let rcm = rseed [Canopy onward] if height < CanopyActivationHeight + ZIP212GracePeriod and leadByte ̸∈ {0x01, 0x02}, return ⊥ [Canopy onward] if height ≥ CanopyActivationHeight + ZIP212GracePeriod and leadByte ̸= 0x02, return ⊥ {︃ rseed, if leadByte = 0x01 [Canopy onward] let rcm = ToScalar PRFexpand otherwise (︀ )︀ rseed ([5]) , let rcm = LEOS2IP256 (rcm) and gd = DiversifyHash(d) if rcm ≥ 𝑟J or gd = ⊥, return ⊥ [Canopy onward] if leadByte ̸= 0x01: esk = ToScalar PRFexpand (︀ )︀ rseed ([4]) if reprJ KASapling .DerivePublic(esk, gd ) ̸= ephemeralKey, return ⊥ (︀ )︀ let pkd = KASapling .DerivePublic(ivk, gd ) let cm𝑢′ = ExtractJ(𝑟) NoteCommitSapling (reprJ (gd ), reprJ (pkd ), v) . (︀ )︀ rcm if LEBS2OSP256 cm𝑢′ ̸= cmu, return ⊥ (︀ )︀ return np. Notes: • As explained in the note in § 5.4.8.3 ‘Jubjub’ on p. 73, abstJ accepts non-canonical compressed encodings of Jubjub curve points (specifically, point encodings with 𝑢 ˜ = 1 and 𝑣 = 0). Therefore, an implementation MUST use the original ephemeralKey field as encoded in the transaction as input to KDFSapling , and (if Canopy is active and leadByte ̸= 0x01) in the comparison against reprJ KASapling .DerivePublic(esk, gd ) . (︀ )︀ • Normally only transmitted note ciphertexts of transactions in blocks need to be decrypted. In that case, any received Sapling note is necessarily a positioned note, and so its ρ value can immediately be calculated as described in § 4.14 ‘Note Commitments and Nullifiers’ on p. 42. To test whether a Sapling note is unspent in a particular block chain also requires the nullifier deriving key nk⋆; the coin is unspent if and only if nf = PRFnfSapling reprJ (ρ) is not in the nullifier set for that block chain. (︀ )︀ nk⋆ • A note can change from being unspent to spent as a node’s view of the best valid block chain is extended by new transactions. Also, block chain reorganizations can cause a node to switch to a different best valid block chain that does not contain the transaction in which a note was output. • A client MAY attempt to decrypt a transmitted note ciphertext of a transaction in the mempool , using the next block height for height. However, in that case it MUST NOT assume that the transaction will be mined and MUST treat the decrypted information as provisional. It will not be able to calculate the ρ value. 49

4.17.3 Decryption using a Full Viewing Key (Sapling) Let ovk BY[ℓovk /8] be the outgoing viewing key , as specified in § 4.2.2 ‘Sapling Key Components’ on p. 29, that is to ◦ ◦ be used for decryption. (If ovk = ⊥ was used for encryption, the payment is not decryptable by this method.) Let (ephemeralKey, Cenc , Cout ) be the transmitted note ciphertext , and let cv and cmu be those fields of the Output description (encoding the value commitment and the 𝑢-coordinate of the note commitment ). The outgoing viewing key holder will attempt to decrypt the transmitted note ciphertext as follows: let ock = PRFock ovk (cv, cmu, ephemeralKey) let op = Sym.Decryptock (Cout ) if op = ⊥, return ⊥ extract (pk⋆d B[ℓJ ] , esk BY[32] ) from op ◦ ◦ ◦ ◦ let esk = LEOS2IP256 (esk) and pkd = abstJ (pk⋆d ) if esk ≥ 𝑟J , return ⊥ let sharedSecret = KASapling .Agree(esk, pkd ) let Kenc = KDFSapling (sharedSecret, ephemeralKey) let Penc = Sym.DecryptKenc (Cenc ) if Penc = ⊥, return ⊥ extract np = (leadByte BY, d B[ℓd ] , v {0 .. 2ℓvalue −1}, rseed BY[32] , memo BY[512] ) from Penc ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ [Pre-Canopy] if leadByte ̸= 0x01, return ⊥ [Pre-Canopy] let rcm = rseed [Canopy onward] if height < CanopyActivationHeight + ZIP212GracePeriod and leadByte ̸∈ {0x01, 0x02}, return ⊥ [Canopy onward] if height ≥ CanopyActivationHeight + ZIP212GracePeriod and leadByte ̸= 0x02, return ⊥ [Canopy onward] if leadByte ̸= 0x01 and ToScalar PRFexpandrseed ([4]) ̸= esk, return ⊥ (︀ )︀ {︃ rseed, if leadByte = 0x01 [Canopy onward] let rcm = ToScalar PRFexpand otherwise (︀ )︀ rseed ([5]) , let rcm = LEOS2IP256 (rcm) and gd = DiversifyHash(d) if rcm ≥ 𝑟J or gd = ⊥, return ⊥ let cm𝑢′ = ExtractJ(𝑟) NoteCommitSapling (︀ )︀ rcm (reprJ (gd ), reprJ (pkd ), v) if LEBS2OSP256 cm𝑢′ ̸= cmu, return ⊥ (︀ )︀ if reprJ KASapling .DerivePublic(esk, gd ) ̸= ephemeralKey, return ⊥ (︀ )︀ return np. Notes: • As explained in the note in § 5.4.8.3 ‘Jubjub’ on p. 73, abstJ accepts non-canonical compressed encodings of Jubjub curve points (specifically, point encodings with 𝑢 ˜ = 1 and 𝑣 = 0). Therefore, an implementation MUST use the original ephemeralKey field as encoded in the transaction as input to PRFock and KDFSapling , and in the comparison against reprJ KASapling .DerivePublic(esk, gd ) . (︀ )︀ • pk⋆d can also be non-canonical. The decoded point pkd is not checked to be in the subgroup J(𝑟) . • The comments in § 4.17.2 ‘Decryption using an Incoming Viewing Key (Sapling)’ on p. 48 concerning cal- culation of ρ, detection of spent notes, and decryption of transmitted note ciphertexts for transactions in the mempool also apply to notes decrypted by this procedure. 50

Non-normative note: Implementors should pay close attention to the similarities and differences between this procedure and that in § 4.17.2 ‘Decryption using an Incoming Viewing Key (Sapling)’ on p. 48. In particular: • in this procedure, the ephemeral private key esk′ derived from rseed is checked to be identical to that obtained from op (when leadByte ̸= 0x01); • in this procedure, pkd is obtained from op rather than being derived as KASapling .DerivePublic(ivk, gd ); • in this procedure, the check that KASapling .DerivePublic(esk, gd ) = epk is unconditional rather than being dependent on leadByte ̸= 0x01, and it uses the esk obtained from op. 4.18 Block Chain Scanning (Sprout) Let ℓPRFSprout be as defined in § 5.3 ‘Constants’ on p. 53. Let NoteSprout be as defined in § 3.2 ‘Notes’ on p. 13. Let KASprout be as defined in § 5.4.4.1 ‘Sprout Key Agreement’ on p. 62. The following algorithm can be used, given the block chain and a Sprout spending key ask , to obtain each note sent to the corresponding shielded payment address, its memo field field, and its final status (spent or unspent). Let ivk = (apk B[ℓPRFSprout ] , skenc KASprout .Private) be the incoming viewing key corresponding to ask , and let pkenc be ◦ ◦ ◦ ◦ the associated transmission key , as specified in § 4.2.1 ‘Sprout Key Components’ on p. 29. let mutable ReceivedSet P NoteSprout × BY[512] (︀ )︀ ◦ ◦ := {} let mutable SpentSet P NoteSprout := {} ◦ (︀ )︀ ◦ let mutable NullifierMap B[ℓPRFSprout ] → NoteSprout := the empty mapping ◦ ◦ for each transaction tx: for each JoinSplit description in tx: let (epk, Cenc 1..N ) be the transmitted notes ciphertext of the JoinSplit description new for 𝑖 in 1..Nnew : Attempt to decrypt the transmitted notes ciphertext component (epk, Cenc 𝑖 ) using ivk with the algorithm in § 4.16.2 ‘Decryption (Sprout)’ on p. 47. If this succeeds giving np: Extract n and memo BY[512] from np (taking the apk field of the note to be apk from ivk). ◦ ◦ Add (n, memo) to ReceivedSet. Calculate the nullifier nf of n using ask as described in § 3.2 ‘Notes’ on p. 13. Add the mapping nf → n to NullifierMap. let nf 1..Nold be the nullifiers of the JoinSplit description for 𝑖 in 1..Nold : if nf 𝑖 is present in NullifierMap, add NullifierMap(nf 𝑖 ) to SpentSet return (ReceivedSet, SpentSet). 51

4.19 Block Chain Scanning (Sapling) In Sapling, block chain scanning requires only the nk and ivk key components, rather than a spending key as in Sprout. Typically, these components are derived from a full viewing key as described in § 4.2.2 ‘Sapling Key Components’ on p. 29. Let ℓPRFnfSapling be as defined in § 5.3 ‘Constants’ on p. 53. Let NoteSapling be as defined in § 3.2 ‘Notes’ on p. 13. Let KASapling be as defined in § 5.4.4.3 ‘Sapling Key Agreement’ on p. 63. The following algorithm can be used, given the block chain and (nk J(𝑟) , ivk {0 .. 2ℓivk −1}), to obtain each note ◦ ◦ ◦ ◦ sent to the corresponding shielded payment address, its memo field field, and its final status (spent or unspent). let mutable ReceivedSet P NoteSapling × BY[512] (︀ )︀ ◦ ◦ := {} let mutable SpentSet P NoteSapling := {} ◦ (︀ )︀ ◦ let mutable NullifierMap BY[ℓPRFnfSapling /8] → NoteSapling := the empty mapping ◦ ◦ for each transaction tx: for each Output description in tx with note position pos: Attempt to decrypt the transmitted note ciphertext components epk and Cenc using ivk with the algorithm in § 4.17.2 ‘Decryption using an Incoming Viewing Key (Sapling)’ on p. 48. If this succeeds giving np: Extract n and memo BY[512] from np ◦ ◦ Add (n, memo) to ReceivedSet Calculate the nullifier nf of n using nk and pos as described in § 3.2 ‘Notes’ on p. 13. Add the mapping nf → n to NullifierMap. for each Spend description in tx: let nf be the nullifier of the Spend description if nf is present in NullifierMap, add NullifierMap(nf) to SpentSet return (ReceivedSet, SpentSet). Non-normative notes: • The above algorithm does not use the ovk key component, or the Cout transmitted note ciphertext component. When scanning the whole block chain, these are indeed not necessary. The advantage of supporting decryption using ovk as described in § 4.17.3 ‘Decryption using a Full Viewing Key (Sapling)’ on p. 50, is that it allows recovering information about the note plaintexts sent in a transaction from that transaction alone. • When scanning only part of a block chain, it may be useful to augment the above algorithm with decryption of Cout components for each transaction, in order to obtain information about notes that were spent in the scanned period but received outside it. • The above algorithm does not detect notes that were sent “out-of-band” or with incorrect transmitted note ciphertexts. It is possible to detect whether such notes were spent only if their nullifiers are known. 52

5 Concrete Protocol 5.1 Caution TODO: Explain the kind of things that can go wrong with linkage between abstract and concrete protocol. E.g. § 8.5 ‘Internal hash collision attack and fix’ on p. 102 5.2 Integers, Bit Sequences, and Endianness All integers in Zcash-specific encodings are unsigned, have a fixed bit length, and are encoded in little-endian byte order unless otherwise specified. The following functions convert between sequences of bits, sequences of bytes, and integers: • I2LEBSP (ℓ N) × {0 .. 2ℓ −1} → B[ℓ] , such that I2LEBSPℓ (𝑥) is the sequence of ℓ bits representing 𝑥 in ◦ ◦ ◦ ◦ little-endian order; • I2BEBSP (ℓ N) × {0 .. 2ℓ −1} → B[ℓ] such that I2BEBSPℓ (𝑥) is the sequence of ℓ bits representing 𝑥 in ◦ ◦ ◦ ◦ big-endian order. • LEBS2IP (ℓ N) × B[ℓ] → {0 .. 2ℓ −1} such that LEBS2IPℓ (𝑆) is the integer represented in little-endian order ◦ ◦ ◦ ◦ by the bit sequence 𝑆 of length ℓ. • LEOS2IP (ℓ N | ℓ mod 8 = 0) × BY[ℓ/8] → {0 .. 2ℓ −1} such that LEOS2IPℓ (𝑆) is the integer represented in ◦ ◦ ◦ ◦ little-endian order by the byte sequence 𝑆 of length ℓ/8. • LEBS2OSP (ℓ N) × B[ℓ] → BY[ceiling(ℓ/8)] defined as follows: pad the input on the right with 8 · ceiling (ℓ/8) − ℓ ◦ ◦ ◦ ◦ zero bits so that its length is a multiple of 8 bits. Then convert each group of 8 bits to a byte value with the least significant bit first, and concatenate the resulting bytes in the same order as the groups. • LEOS2BSP (ℓ N | ℓ mod 8 = 0) × BY[ceiling(ℓ/8)] → B[ℓ] defined as follows: convert each byte to a group of 8 ◦ ◦ ◦ ◦ bits with the least significant bit first, and concatenate the resulting groups in the same order as the bytes. In bit layout diagrams, each box of the diagram represents a sequence of bits. Diagrams are read from left-to-right, with lines read from top-to-bottom; the breaking of boxes across lines has no significance. The bit length ℓ is given explicitly in each box, except when it is obvious (e.g. for a single bit, or for the notation [0]ℓ representing the sequence of ℓ zero bits, or for the output of LEBS2OSPℓ ). The entire diagram represents the sequence of bytes formed by first concatenating these bit sequences, and then treating each subsequence of 8 bits as a byte with the bits ordered from most significant to least significant. Thus the most significant bit in each byte is toward the left of a diagram. (This convention is used only in descriptions of the Sprout design; in the Sapling additions, bit/byte sequence conversions are always specified explicitly.) Where bit fields are used, the text will clarify their position in each case. 5.3 Constants Define: MerkleDepthSprout N := 29 ◦ ◦ Sapling MerkleDepth ◦ ◦ N := 32 old N ◦ ◦ N := 2 new N ◦ ◦ N := 2 ℓvalue N := 64◦ ◦ ℓMerkleSprout N := 256◦ ◦ 53

ℓMerkleSapling N := 255 ◦ ◦ ℓhSig N := 256 ◦ ◦ ℓPRFSprout N := 256 ◦ ◦ ℓPRFexpand N := 512 ◦ ◦ ℓPRFnfSapling N := 256 ◦ ◦ ℓrcm N := 256 ◦ ◦ ℓSeed N := 256 ◦ ◦ ℓask N := 252 ◦ ◦ ℓϕ N := 252 ◦ ◦ ℓsk N := 256 ◦ ◦ ℓd N := 88 ◦ ◦ ℓivk N := 251 ◦ ◦ ℓovk N := 256 ◦ ◦ ℓscalar N := 252 ◦ ◦ UncommittedSprout B[ℓMerkleSprout ] := [0]ℓMerkleSprout ◦ ◦ UncommittedSapling B[ℓMerkleSapling ] := I2LEBSPℓMerkleSapling (1) ◦ ◦ MAX_MONEY N := 2.1·1015 (zatoshi ) ◦ ◦ {︃ 653600, for Mainnet BlossomActivationHeight N := ◦ ◦ 584000, for Testnet {︃ 1046400, for Mainnet CanopyActivationHeight N := ◦ ◦ 1028500, for Testnet ZIP212GracePeriod N := 32256 ◦ ◦ SlowStartInterval N := 20000 ◦ ◦ PreBlossomHalvingInterval N := 840000 ◦ ◦ MaxBlockSubsidy N := 1.25·109 (zatoshi ) ◦ ◦ NumFounderAddresses N := 48 ◦ ◦ FoundersFraction Q := 15 ◦ ◦ {︃ 2243 − 1, for Mainnet PoWLimit N := ◦ ◦ 2251 − 1, for Testnet PoWAveragingWindow N := 17 ◦ ◦ PoWMedianBlockSpan N := 11 ◦ ◦ 32 PoWMaxAdjustDown Q := ◦ ◦ 100 16 PoWMaxAdjustUp Q := ◦ ◦ 100 PoWDampingFactor N := 4 ◦ ◦ PreBlossomPoWTargetSpacing N := 150 (seconds). ◦ ◦ PostBlossomPoWTargetSpacing N := 75 (seconds). ◦ ◦ 54

5.4 Concrete Cryptographic Schemes 5.4.1 Hash Functions 5.4.1.1 SHA-256, SHA-256d, SHA256Compress, and SHA-512 Hash Functions SHA-256 and SHA-512 are defined by [NIST2015]. Zcash uses the full SHA-256 hash function to instantiate NoteCommitmentSprout . SHA-256 BY[N] → BY[32] ◦ ◦ [NIST2015] strictly speaking only specifies the application of SHA-256 to messages that are bit sequences, producing outputs (“message digests”) that are also bit sequences. In practice, SHA-256 is universally implemented with a byte-sequence interface for messages and outputs, such that the most significant bit of each byte corresponds to the first bit of the associated bit sequence. (In the NIST specification “first” is conflated with “leftmost”.) SHA-256d, defined as a double application of SHA-256, is used to hash block headers: SHA-256d BY[N] → BY[32] ◦ ◦ Zcash also uses the SHA-256 compression function, SHA256Compress. This operates on a single 512-bit block and excludes the padding step specified in [NIST2015, section 5.1]. That is, the input to SHA256Compress is what [NIST2015, section 5.2] refers to as “the message and its padding”. The Initial Hash Value is the same as for full SHA-256. SHA256Compress is used to instantiate several Pseudo Random Functions and MerkleCRHSprout . SHA256Compress B[512] → B[256] ◦ ◦ The ordering of bits within words in the interface to SHA256Compress is consistent with [NIST2015, section 3.1], i.e. big-endian. Ed25519 uses SHA-512: SHA-512 BY[N] → BY[64] ◦ ◦ The comment above concerning bit vs byte-sequence interfaces also applies to SHA-512. 5.4.1.2 BLAKE2 Hash Functions BLAKE2 is defined by [ANWW2013]. Zcash uses both the BLAKE2b and BLAKE2s variants. BLAKE2b-ℓ(𝑝, 𝑥) refers to unkeyed BLAKE2b-ℓ in sequential mode, with an output digest length of ℓ/8 bytes, 16-byte personalization string 𝑝, and input 𝑥. BLAKE2b is used to instantiate hSigCRH, EquihashGen, and KDFSprout . From Overwinter onward, it is used to compute SIGHASH transaction hashes as specified in [ZIP-143], or as in [ZIP-243] after Sapling activation. For Sapling, it is also used to instantiate PRFexpand , PRFock , KDFSapling , and in the RedJubjub signature scheme which instantiates SpendAuthSig and BindingSig. BLAKE2b-ℓ BY[16] × BY[N] → BY[ℓ/8] ◦ ◦ Note: BLAKE2b-ℓ is not the same as BLAKE2b-512 truncated to ℓ bits, because the digest length is encoded in the parameter block. BLAKE2s-ℓ(𝑝, 𝑥) refers to unkeyed BLAKE2s-ℓ in sequential mode, with an output digest length of ℓ/8 bytes, 8-byte personalization string 𝑝, and input 𝑥. (𝑟)* BLAKE2s is used to instantiate PRFnfSapling , CRHivk , and GroupHashJ . 55

BLAKE2s-ℓ BY[8] × BY[N] → BY[ℓ/8] ◦ ◦ 5.4.1.3 Merkle Tree Hash Function MerkleCRHSprout and MerkleCRHSapling are used to hash incremental Merkle tree hash values for Sprout and Sapling respectively. MerkleCRHSprout Hash Function MerkleCRHSprout {0 .. MerkleDepthSprout − 1} × B[ℓMerkleSprout ] × B[ℓMerkleSprout ] → B[ℓMerkleSprout ] is defined as follows: ◦ ◦ (︁ )︁ MerkleCRHSprout (layer, left, right) := SHA256Compress 256-bit left 256-bit right . SHA256Compress is defined in § 5.4.1.1 ‘SHA-256, SHA-256d, SHA256Compress, and SHA-512 Hash Functions’ on p. 55. Security requirement: SHA256Compress must be collision-resistant , and it must be infeasible to find a preimage 𝑥 such that SHA256Compress(𝑥) = [0]256 . Notes: • The layer argument does not affect the output. • SHA256Compress is not the same as the SHA-256 function, which hashes arbitrary-length byte sequences. MerkleCRHSapling Hash Function Let PedersenHash be as specified in § 5.4.1.7 ‘Pedersen Hash Function’ on p. 58. MerkleCRHSapling {0 .. MerkleDepthSapling − 1} × B[ℓMerkleSapling ] × B[ℓMerkleSapling ] → B[ℓMerkleSapling ] is defined as follows: ◦ ◦ MerkleCRHSapling (layer, left, right) := PedersenHash(“Zcash_PH”, 𝑙 || left || right) where 𝑙 = I2LEBSP6 MerkleDepthSapling − 1 − layer . (︀ )︀ Security requirement: PedersenHash must be collision-resistant . Note: The prefix 𝑙 provides domain separation between inputs at different layers of the note commitment tree. NoteCommitSapling , like PedersenHash, is defined in terms of PedersenHashToPoint, but using a prefix that cannot collide with a layer prefix, as noted in § 5.4.7.2 ‘Windowed Pedersen commitments’ on p. 68. 5.4.1.4 hSig Hash Function hSigCRH is used to compute the value hSig in § 4.3 ‘JoinSplit Descriptions’ on p. 31. hSigCRH(randomSeed, nf old 1..N old , joinSplitPubKey) := BLAKE2b-256(“ZcashComputehSig”, hSigInput) where hSigInput := 256-bit randomSeed 256-bit nf old 1 ... 256-bit nf old N old 256-bit joinSplitPubKey . BLAKE2b-256(𝑝, 𝑥) is defined in § 5.4.1.2 ‘BLAKE2 Hash Functions’ on p. 55. Security requirement: BLAKE2b-256(“ZcashComputehSig”, 𝑥) must be collision-resistant on 𝑥. 56

5.4.1.5 CRHivk Hash Function CRHivk is used to derive the incoming viewing key ivk for a Sapling shielded payment address. For its use when generating an address see § 4.2.2 ‘Sapling Key Components’ on p. 29, and for its use in the Spend statement see § 4.15.2 ‘Spend Statement (Sapling)’ on p. 44. It is defined as follows: CRHivk (ak⋆, nk⋆) := LEOS2IP256 (BLAKE2s-256(“Zcashivk”, crhInput)) mod 2ℓivk where crhInput := LEBS2OSP256 (ak⋆) LEBS2OSP256 (nk⋆) BLAKE2b-256(𝑝, 𝑥) is defined in § 5.4.1.2 ‘BLAKE2 Hash Functions’ on p. 55. Security requirement: LEOS2IP256 (BLAKE2s-256(“Zcashivk”, 𝑥)) mod 2ℓivk must be collision-resistant on a 64- byte input 𝑥. Note that this does not follow from collision resistance of BLAKE2s-256 (and the best possible concrete security is that of a 251-bit hash rather than a 256-bit hash), but it is a reasonable assumption given the design, structure, and cryptanalysis to date of BLAKE2s. Non-normative note: BLAKE2s has a variable output digest length feature, but it does not support arbitrary bit lengths, otherwise it would have been used rather than external truncation. However, the protocol-specific personalization string together with truncation achieve essentially the same effect as using that feature. 5.4.1.6 DiversifyHash Hash Function DiversifyHash is used to derive a diversified base from a diversifier in § 4.2.2 ‘Sapling Key Components’ on p. 29. (𝑟)* Let GroupHashJ and 𝑈 be as defined in § 5.4.8.5 ‘Group Hash into Jubjub’ on p. 74. Define (𝑟)* (︀ )︀ DiversifyHash(d) := GroupHashJ𝑈 “Zcash_gd”, LEBS2OSPℓd (d) Security requirement: Unlinkability: Given two randomly selected shielded payment addresses from different spend authorities, and a third shielded payment address which could be derived from either of those authorities, such that the three addresses use different diversifiers, it is not possible to tell which authority the third address was derived from. Non-normative notes: (𝑟)* • Suppose that GroupHashJ (restricted to inputs for which it does not return ⊥) is modelled as a random oracle from diversifiers to points of order 𝑟J on the Jubjub curve. In this model, Unlinkability of DiversifyHash holds under the Decisional Diffie-Hellman assumption on the prime-order subgroup of the Jubjub curve. To prove this, consider the ElGamal encryption scheme [ElGamal1985] on this prime-order subgroup, re- stricted to encrypting plaintexts encoded as the group identity 𝒪J . (ElGamal was originally defined for F*𝑝 but works in any prime-order group.) ElGamal public keys then have the same form as diversified payment (𝑟)* addresses. If we make the assumption above on GroupHashJ , then generating a new diversified payment address from a given address pk, gives the same distribution of (gd ′ , pkd ′ ) pairs as the distribution of ElGamal ciphertexts obtained by encrypting 𝒪J under pk. TODO: check whether this is justified. Then, the definition of key privacy (IK-CPA as defined in [BBDP2001, Definition 1]) for ElGamal corresponds to the definition of Unlinkability for DiversifyHash. (IK-CCA corresponds to the potentially stronger requirement that DiversifyHash remains Unlinkable when given Diffie-Hellman key agreement oracles for each of the candidate diversified payment addresses.) So if ElGamal is key-private, then DiversifyHash is Unlinkable under the same conditions. [BBDP2001, Appendix A] gives a security proof for key privacy (both IK-CPA and IK-CCA) of ElGamal under the Decisional Diffie-Hellman assumption on the relevant group. (In fact the proof needed is the “small modification” described in the last paragraph in which the generator is chosen at random for each key.) 57

• It is assumed (also for the security of other uses of the group hash, such as Pedersen hashes and commitments) that the discrete logarithm of the output group element with respect to any other generator is unknown. This assumption is justified if the group hash acts as a random oracle. Essentially, diversifiers act as handles to unknown random numbers. (The group hash inputs used with different personalizations are in different “namespaces”.) • Informally, the random self-reducibility property of DDH implies that an adversary would gain no advantage from being able to query an oracle for additional (gd , pkd ) pairs with the same spend authority as an existing shielded payment address, since they could also create such pairs on their own. This justifies only considering two shielded payment addresses in the security definition. TODO: FIXME This is not correct, because additional pairs don’t quite follow the same distribution as an address with a valid diversifier. The security definition may need to be more complex to model this properly. • An 88-bit diversifier cannot be considered cryptographically unguessable at a 128-bit security level; also, randomly chosen diversifiers are likely to suffer birthday collisions when the number of choices approaches 244 . If most users are choosing diversifiers randomly (as recommended in § 4.2.2 ‘Sapling Key Components’ on p. 29), then the fact that they may accidentally choose diversifiers that collide (and therefore reveal the fact that they are not derived from the same incoming viewing key ) does not appreciably reduce the anonymity set. In [ZIP-32] an 88-bit Pseudo Random Permutation, keyed differently for each node of the derivation tree, is used to select new diversifiers. This resolves the potential problem, provided that the input to the Pseudo Random Permutation does not repeat for a given node. • If the holder of an incoming viewing key permits an adversary to ask for a new address for that incoming viewing key with a given diversifier , then it can trivially break Unlinkability for the other diversified payment addresses associated with the incoming viewing key (this does not compromise other privacy properties). Implementations SHOULD avoid providing such a “chosen diversifier ” oracle. 5.4.1.7 Pedersen Hash Function PedersenHash is an algebraic hash function with collision resistance (for fixed input length) derived from assumed hardness of the Discrete Logarithm Problem on the Jubjub curve. It is based on the work of David Chaum, Ivan Damgård, Jeroen van de Graaf, Jurjen Bos, George Purdy, Eugène van Heijst and Birgit Pfitzmann in [CDvdG1987], [BCP1988] and [CvHP1991], and of Mihir Bellare, Oded Goldreich, and Shafi Goldwasser in [BGG1995], with optimiza- tions for efficient instantiation in zk-SNARK circuits by Sean Bowe and Daira Hopwood. PedersenHash is used in the definitions of Pedersen commitments (§ 5.4.7.2 ‘Windowed Pedersen commitments’ on p. 68), and of the Pedersen hash for the Sapling incremental Merkle tree (§ 5.4.1.3 ‘MerkleCRHSapling Hash Function’ on p. 56). Let J, J(𝑟) , 𝒪J , 𝑞J , 𝑟J , 𝑎J , and 𝑑J be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73. Let ExtractJ(𝑟) J(𝑟) → B[ℓMerkleSapling ] be as defined in § 5.4.8.4 ‘Hash Extractor for Jubjub’ on p. 74. ◦ ◦ (𝑟)* Let FindGroupHashJ be as defined in § 5.4.8.5 ‘Group Hash into Jubjub’ on p. 74. Let UncommittedSapling be as defined in § 5.3 ‘Constants’ on p. 53. 24·𝑐 − 1 𝑟J − 1 Let 𝑐 be the largest integer such that 4 · ≤ , i.e. 𝑐 := 63. 15 2 Define ℐ BY[8] × N → J(𝑟)* by: ◦ ◦ (𝑟)* (︁ )︁ ℐ𝐷 𝑖 := FindGroupHash J 𝐷, 32-bit 𝑖 − 1 . 58

+ Define PedersenHashToPoint(𝐷 BY[8] , 𝑀 B[N ] ) → J(𝑟) as follows: ◦ ◦ ◦ ◦ Pad 𝑀 to a multiple of 3 bits by appending zero bits, giving 𝑀 ′ . length(𝑀 ′ ) (︁ )︁ Let 𝑛 = ceiling . 3·𝑐 Split 𝑀 ′ into 𝑛 “segments” 𝑀1 .. 𝑛 so that 𝑀 ′ = concatB (𝑀1 .. 𝑛 ), and each of 𝑀1 .. 𝑛−1 is of length 3·𝑐 bits. (𝑀𝑛 may be shorter.) ∑︀𝑛 Return 𝑖=1 [⟨𝑀𝑖 ⟩] ℐ𝐷 𝑖 J(𝑟) . ◦ ◦ 𝑟J − 1 𝑟J − 1 where ⟨∙⟩ B[3·{1 .. 𝑐}] → {− ◦ ◦ .. } ∖ {0} is defined as: 2 2 Let 𝑘𝑖 = length(𝑀𝑖 )/3. Split 𝑀𝑖 into 3-bit “chunks” 𝑚1 .. 𝑘𝑖 so that 𝑀𝑖 = concatB (𝑚1 .. 𝑘𝑖 ). Write each 𝑚𝑗 as [𝑠0𝑗 , 𝑠1𝑗 , 𝑠2𝑗 ], and let enc(𝑚𝑗 ) = (1 − 2·𝑠2𝑗 ) · (1 + 𝑠0𝑗 + 2·𝑠1𝑗 ) Z. ◦ ◦ ∑︀𝑘 𝑖 Let ⟨𝑀𝑖 ⟩ = 𝑗=1 enc(𝑚𝑗 ) · 24·(𝑗−1) . + Finally, define PedersenHash BY[8] × B[N ] → B[ℓMerkleSapling ] by: ◦ ◦ PedersenHash(𝐷, 𝑀 ) := ExtractJ(𝑟) PedersenHashToPoint(𝐷, 𝑀 ) . (︀ )︀ See § A.3.3.9 ‘Pedersen hash’ on p. 147 for rationale and efficient circuit implementation of these functions. Security requirement: PedersenHash and PedersenHashToPoint are required to be collision-resistant between inputs of fixed length, for a given personalization input 𝐷. No other security properties commonly associated with hash functions are needed. Non-normative note: These hash functions are not collision-resistant for variable-length inputs. Theorem 5.4.1. The encoding function ⟨∙⟩ is injective. 𝑘𝑖 ∑︁ 𝑟J − 1 𝑟J − 1 Proof. We first check that the range of enc(𝑚𝑗 ) · 24·(𝑗−1) is a subset of the allowable range {− .. } ∖ {0}. 2 2 𝑗=1 𝑐 24·𝑐 − 1 ∑︁ The range of this expression is a subset of {−Δ .. Δ} ∖ {0} where Δ = 4 · 24·(𝑖−1) = 4 · . 15 𝑖=1 When 𝑐 = 63, we have 24·𝑐 − 1 4· = 0x444444444444444444444444444444444444444444444444444444444444444 15 𝑟J − 1 = 0x73EDA753299D7D483339D80809A1D8053341049E6640841684B872F6B7B965B 2 ∑︀𝑘 𝑖 so the required condition is met. This implies that there is no “wrap around” and so 𝑗=1 enc(𝑚𝑗 ) · 24·(𝑗−1) may be treated as an integer expression. enc is injective. In order to prove that ⟨∙⟩ is injective, consider ⟨∙⟩Δ B[3·{1 .. 𝑐}] → {0 .. 2·Δ} such that ⟨𝑀𝑖 ⟩Δ = ⟨𝑀𝑖 ⟩+Δ. ◦ ◦ ∑︀𝑘 enc (𝑚𝑗 ) · 24·(𝑗−1) where enc′ (𝑚𝑗 ) = enc(𝑚𝑗 ) + 4 is in ′ Δ 𝑖 With 𝑘𝑖 and 𝑚𝑗 defined as above, we have ⟨𝑀𝑖 ⟩ = 𝑗=1 {0 .. 8} and enc′ is injective. Express this sum in hexadecimal; then each 𝑚𝑗 affects only one hex digit, and it is easy to see that ⟨∙⟩Δ is injective. Therefore so is ⟨∙⟩. Since the security proof from [BGG1995, Appendix A] depends only on the encoding being injective and its range not including zero, the proof can be adapted straightforwardly to show that PedersenHashToPoint is collision-resistant under the same assumptions and security bounds. Because ExtractJ(𝑟) is injective, it follows that PedersenHash is equally collision-resistant . 59

Theorem 5.4.2. UncommittedSapling is not in the range of PedersenHash. Proof. UncommittedSapling is defined as I2LEBSPℓMerkleSapling (1). By injectivity of I2LEBSPℓMerkleSapling and definitions of PedersenHash and ExtractJ(𝑟) , I2LEBSPℓMerkleSapling (1) can be in the range of PedersenHash only if there exist 𝐷 BY[8] and ◦ ◦ + 𝑀 B[N ] such that 𝑢(PedersenHashToPoint(𝐷, 𝑀 )) = 1. The latter can only be the affine-ctEdwards 𝑢-coordinate ◦ ◦ of a point in J. We show that there are no points in J with affine-ctEdwards 𝑢-coordinate 1. Suppose for a contradiction that (𝑢, v) ∈ J for 𝑢 = 1 and some v F𝑟 S . By writing the curve equation as v2 = (1 − 𝑎J ·𝑢2 )/(1 − 𝑑J ·𝑢2 ), ◦ ◦ and noting that 1 − 𝑑J ·𝑢2 ̸= 0 because 𝑑J is nonsquare, we have v2 = (1 − 𝑎J )/(1 − 𝑑J ). The right-hand-side is a nonsquare in F𝑟 S (for the Jubjub curve parameters), so there are no solutions for v (contradiction). 5.4.1.8 Mixing Pedersen Hash Function A mixing Pedersen hash is used to compute ρ from cm and pos in § 4.14 ‘Note Commitments and Nullifiers’ on p. 42. It takes as input a Pedersen commitment 𝑃 , and hashes it with another input 𝑥. (𝑟)* Define 𝒥 := FindGroupHashJ (“Zcash_J_”, “”). We define MixingPedersenHash J × {0 .. 𝑟J − 1} → J by: ◦ ◦ MixingPedersenHash(𝑃, 𝑥) := 𝑃 + [𝑥] 𝒥 . Security requirement: The function + (𝑟, 𝑀, 𝑥) {0 .. 𝑟J − 1} × B[N ◦ ◦ ] × {0 .. 𝑟J − 1} ↦→ MixingPedersenHash(WindowedPedersenCommit𝑟 (𝑀 ), 𝑥) J◦ ◦ must be collision-resistant on (𝑟, 𝑀, 𝑥). See § A.3.3.10 ‘Mixing Pedersen hash’ on p. 149 for efficient circuit implementation of this function. 5.4.1.9 Equihash Generator EquihashGen𝑛,𝑘 is a specialized hash function that maps an input and an index to an output of length 𝑛 bits. It is used in § 7.6.1 ‘Equihash’ on p. 92. Let powtag := 64-bit “ZcashPoW” 32-bit 𝑛 32-bit 𝑘 . Let powcount(𝑔) := 32-bit 𝑔 . Let EquihashGen𝑛,𝑘 (𝑆, 𝑖) := 𝑇ℎ+1 .. ℎ+𝑛 , where 𝑛 ; 𝑚 := floor 512 (︀ )︀ ℎ := (𝑖 − 1 mod 𝑚) · 𝑛; 𝑚 ) . 𝑇 := BLAKE2b-(𝑛 · 𝑚) powtag, 𝑆 || powcount(floor 𝑖−1 (︀ (︀ )︀ )︀ Indices of bits in 𝑇 are 1-based. BLAKE2b-ℓ(𝑝, 𝑥) is defined in § 5.4.1.2 ‘BLAKE2 Hash Functions’ on p. 55. Security requirement: BLAKE2b-ℓ(powtag, 𝑥) must generate output that is sufficiently unpredictable to avoid short-cuts to the Equihash solution process. It would suffice to model it as a random oracle. Note: When EquihashGen is evaluated for sequential indices, as in the Equihash (︀ )︀solving process (§ 7.6.1 ‘Equihash’ on p. 92), the number of calls to BLAKE2b can be reduced by a factor of floor 512 𝑛 in the best case (which is a factor of 2 for 𝑛 = 200). 60

5.4.2 Pseudo Random Functions Let SHA256Compress be as given in § 5.4.1.1 ‘SHA-256, SHA-256d, SHA256Compress, and SHA-512 Hash Functions’ on p. 55. The Pseudo Random Functions PRFaddr , PRFnf , PRFpk , and PRFρ , described in § 4.1.2 ‘Pseudo Random Functions’ on p. 20, are all instantiated using SHA256Compress: (︁ )︁ PRFaddr 𝑥 (𝑡) := SHA256Compress 1 1 0 0 252-bit 𝑥 8-bit 𝑡 [0]248 (︁ )︁ PRFnf ask (ρ) := SHA256Compress 1 1 1 0 252-bit ask 256-bit ρ (︁ )︁ PRFpk ask (𝑖, hSig ) := SHA256Compress 0 𝑖-1 0 0 252-bit ask 256-bit hSig (︁ )︁ PRFρϕ (𝑖, hSig ) := SHA256Compress 0 𝑖-1 1 0 252-bit ϕ 256-bit hSig Security requirements: • SHA256Compress must be collision-resistant . • SHA256Compress must be a PRF when keyed by the bits corresponding to 𝑥, ask or ϕ in the above diagrams, with input in the remaining bits. Note: The first four bits –i.e. the most significant four bits of the first byte– are used to separate distinct uses of SHA256Compress, ensuring that the functions are independent. As well as the inputs shown here, bits 1011 in this position are used to distinguish uses of the full SHA-256 hash function; see § 5.4.7.1 ‘Sprout Note Commitments’ on p. 68. (The specific bit patterns chosen here were motivated by the possibility of future extensions that might have increased Nold and/or Nnew to 3, or added an additional bit to ask to encode a new key type, or that would have required an additional PRF . In fact since Sapling switches to non-SHA256Compress-based cryptographic primitives, these extensions are unlikely to be necessary.) PRFexpand is used in § 4.2.2 ‘Sapling Key Components’ on p. 29 to derive the Spend authorizing key ask and the proof authorizing key nsk. It is instantiated using the BLAKE2b hash function defined in § 5.4.1.2 ‘BLAKE2 Hash Functions’ on p. 55: PRFexpand sk (𝑡) := BLAKE2b-512(“Zcash_ExpandSeed”, LEBS2OSP256 (sk) || 𝑡) Security requirement: BLAKE2b-512(“Zcash_ExpandSeed”, LEBS2OSP256 (sk) || 𝑡) must be a PRF for output range BY[ℓPRFexpand /8] when keyed by the bits corresponding to sk, with input in the bits corresponding to 𝑡. PRFock is used in § 4.17.1 ‘Encryption (Sapling)’ on p. 48 to derive the outgoing cipher key ock used to encrypt an Output ciphertext . It is instantiated using the BLAKE2b hash function defined in § 5.4.1.2 ‘BLAKE2 Hash Functions’ on p. 55: PRFock ovk (cv, cmu, ephemeralKey) := BLAKE2b-256(“Zcash_Derive_ock”, ockInput) where ockInput = LEBS2OSP256 (ovk) 32-byte cv 32-byte cmu 32-byte ephemeralKey . Security requirement: BLAKE2b-512(“Zcash_Derive_ock”, ockInput) must be a PRF for output range Sym.K (de- fined in § 5.4.3 ‘Symmetric Encryption’ on p. 62) when keyed by the bits corresponding to ovk, with input in the bits corresponding to cv, cmu, and ephemeralKey. 61

PRFnfSapling is used to derive the nullifier for a Sapling note. It is instantiated using the BLAKE2s hash function defined in § 5.4.1.2 ‘BLAKE2 Hash Functions’ on p. 55: (︁ )︁ PRFnfSapling nk⋆ (ρ⋆) := BLAKE2s-256 “Zcash_nf”, LEBS2OSP256 (nk⋆) LEBS2OSP256 (ρ⋆) . (︁ )︁ Security requirement: BLAKE2s-256 “Zcash_nf”, LEBS2OSP256 (nk⋆) LEBS2OSP256 (ρ⋆) must be a col- lision-resistant PRF for output range BY[32] when keyed by the bits corresponding to nk⋆, with input in the bits (𝑟) corresponding to ρ⋆. Note that nk⋆ J⋆ is a representation of a point in the 𝑟J -order subgroup of the Jubjub curve, ◦ ◦ (𝑟) and therefore is not uniformly distributed on B[ℓJ ] . J⋆ is defined in § 5.4.8.3 ‘Jubjub’ on p. 73. 5.4.3 Symmetric Encryption Let Sym.K := B[256] , Sym.P := BY[N] , and Sym.C := BY[N] . Let the authenticated one-time symmetric encryption scheme Sym.EncryptK (P) be authenticated encryption using AEAD_CHACHA20_POLY1305 [RFC-7539] encryption of plaintext P ∈ Sym.P, with empty “associated data", all-zero nonce [0]96 , and 256-bit key K ∈ Sym.K. Similarly, let Sym.DecryptK (C) be AEAD_CHACHA20_POLY1305 decryption of ciphertext C ∈ Sym.C, with empty “associated data", all-zero nonce [0]96 , and 256-bit key K ∈ Sym.K. The result is either the plaintext byte sequence, or ⊥ indicating failure to decrypt. Note: The “IETF" definition of AEAD_CHACHA20_POLY1305 from [RFC-7539] is used; this has a 32-bit block count and a 96-bit nonce, rather than a 64-bit block count and 64-bit nonce as in the original definition of ChaCha20. 5.4.4 Key Agreement And Derivation 5.4.4.1 Sprout Key Agreement KASprout is a key agreement scheme as specified in § 4.1.4 ‘Key Agreement’ on p. 21. It is instantiated as Curve25519 key agreement, described in [Bernstein2006], as follows. Let KASprout .Public and KASprout .SharedSecret be the type of Curve25519 public keys (i.e. BY[32] ), and let KASprout .Private be the type of Curve25519 secret keys. Let Curve25519(𝑛, 𝑞) be the result of point multiplication of the Curve25519 public key represented by the byte se- quence 𝑞 by the Curve25519 secret key represented by the byte sequence 𝑛, as defined in [Bernstein2006, section 2]. Let KASprout .Base := 9 be the public byte sequence representing the Curve25519 base point. Let clampCurve25519 (𝑥) take a 32-byte sequence 𝑥 as input and return a byte sequence representing a Curve25519 private key , with bits “clamped” as described in [Bernstein2006, section 3]: “clear bits 0, 1, 2 of the first byte, clear bit 7 of the last byte, and set bit 6 of the last byte.” Here the bits of a byte are numbered such that bit 𝑏 has numeric weight 2𝑏 . Define KASprout .FormatPrivate(𝑥) := clampCurve25519 (𝑥). Define KASprout .DerivePublic(𝑛, 𝑞) := Curve25519(𝑛, 𝑞). Define KASprout .Agree(𝑛, 𝑞) := Curve25519(𝑛, 𝑞). 62

5.4.4.2 Sprout Key Derivation KDFSprout is a Key Derivation Function as specified in § 4.1.5 ‘Key Derivation’ on p. 21. It is instantiated using BLAKE2b-256 as follows: KDFSprout (𝑖, hSig , sharedSecret𝑖 , epk, pkenc,𝑖 new ) := BLAKE2b-256(kdftag, kdfinput) where: kdftag := 64-bit “ZcashKDF” 8-bit 𝑖−1 [0]56 new kdfinput := 256-bit hSig 256-bit sharedSecret𝑖 256-bit epk 256-bit pkenc,𝑖 . BLAKE2b-256(𝑝, 𝑥) is defined in § 5.4.1.2 ‘BLAKE2 Hash Functions’ on p. 55. 5.4.4.3 Sapling Key Agreement KASapling is a key agreement scheme as specified in § 4.1.4 ‘Key Agreement’ on p. 21. It is instantiated as Diffie-Hellman with cofactor multiplication on Jubjub as follows: Let J, J(𝑟) , J(𝑟)* , and the cofactor ℎJ be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73. Define KASapling .Public := J. Define KASapling .PublicPrimeSubgroup := J(𝑟) . Define KASapling .SharedSecret := J(𝑟) . Define KASapling .Private := F𝑟J . Define KASapling .DerivePublic(sk, 𝐵) := [sk] 𝐵. Define KASapling .Agree(sk, 𝑃 ) := [ℎJ · sk] 𝑃 . 5.4.4.4 Sapling Key Derivation KDFSapling is a Key Derivation Function as specified in § 4.1.5 ‘Key Derivation’ on p. 21. It is instantiated using BLAKE2b-256 as follows: KDFSapling (sharedSecret, ephemeralKey) := BLAKE2b-256(“Zcash_SaplingKDF”, kdfinput). where: . (︀ )︀ kdfinput := LEBS2OSP256 reprJ (sharedSecret) LEBS2OSP256 (ephemeralKey) BLAKE2b-256(𝑝, 𝑥) is defined in § 5.4.1.2 ‘BLAKE2 Hash Functions’ on p. 55. 5.4.5 Ed25519 Ed25519 is a signature scheme as specified in § 4.1.6 ‘Signature’ on p. 22. It is used to instantiate JoinSplitSig as described in § 4.10 ‘Non-malleability (Sprout)’ on p. 38. 63

Let ExcludedPointEncodings P BY[32] (︀ )︀ ◦ ◦ ={ [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], [ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], [ 0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05 ], [ 0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a ], [ 0x13, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x85 ], [ 0xb4, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0xfa ], [ 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f ], [ 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f ], [ 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f ], [ 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ], [ 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ] }. Let 𝑝 = 2255 − 19. Let 𝑎 = −1. Let 𝑑 = −121665/121666 (mod 𝑝). Let ℓ = 2252 + 27742317777372353535851937790883648493 (the order of the Ed25519 curve’s prime-order subgroup). Let 𝐵 be the base point given in [BDLSY2012]. Define I2LEBSP, LEBS2OSP, LEOS2BSP, and LEBS2IP as in § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53. (︁ )︀)︁ Define reprBytesEd25519 Ed25519 → BY[32] such that reprBytesEd25519 (𝑥, 𝑦) = LEBS2OSP256 I2LEBSP256 𝑦 + 2255 · 𝑥 ˜ , ◦ (︀ ◦ ˜ = 𝑥 mod 2. 5 where 𝑥 Define abstBytesEd25519 BY[32] → Ed25519 ∪ {⊥} such that abstBytesEd25519 (𝑃 )is computed as follows: ◦ ◦ let 𝑦⋆ B[255] be the first 255 bits of LEOS2BSP256 (𝑃 ) and let 𝑥 ◦ ◦ ˜ B be the last bit. ◦ ◦ let 𝑦 F𝑝 = LEBS2IP255 (𝑦⋆) (mod 𝑝). ◦ ◦ if 𝑎 − 𝑑·𝑦 2 = 0, return ⊥. √︂ 1 − 𝑦2 let 𝑥 = ? 2 . 𝑎 − 𝑑·𝑦 if 𝑥 = ⊥, return ⊥. if 𝑥 mod 2 = 𝑥 ˜ then return (𝑥, 𝑦) else return (𝑝 − 𝑥, 𝑦). Note: This definition of point decoding differs from that of [RFC-8032, section 5.1.3, as corrected by the errata]. In the latter there is an additional step “If x = 0, and x_0 = 1, decoding fails.”, which rejects the encodings { [ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 ], [ 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ], [ 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ] }. In this specification, the first two of these are accepted as encodings of (0, 1), and the third is accepted as an encoding of (0, −1). Ed25519 is defined as in [BDLSY2012], using SHA-512 as the internal hash function, with the additional requirements below. A valid Ed25519 validating key is defined as a sequence of 32 bytes encoding a point on the Ed25519 curve. All conversions between Ed25519 points, byte sequences, and integers used in this section are as specified in [BDLSY2012]. 5 Here we use the (𝑥, 𝑦) naming of coordinates in [BDLSY2012], which is different from the (𝑢, v) naming used for coordinates of ctEdwards curves in § A.2 ‘Elliptic curve background’ on p. 137. 64

The requirements on a signature (𝑅, 𝑆) with validating key 𝐴 on a message 𝑀 are: • 𝑆 MUST represent an integer less than ℓ. • 𝑅 and 𝐴 MUST be encodings of points 𝑅 and 𝐴 respectively on the Ed25519 curve; • [Pre-Canopy] 𝑅 MUST NOT be in ExcludedPointEncodings; • [Pre-Canopy] The validation equation MUST be equivalent to [𝑆] 𝐵 = 𝑅 + [𝑐] 𝐴. • [Canopy onward] The validation equation MUST be equivalent to [8] [𝑆] 𝐵 = [8] 𝑅 + [8] [𝑐] 𝐴 for single- signature validation. where 𝑐 is computed as the integer corresponding to SHA-512(𝑅 || 𝐴 || 𝑀 ) as specified in [BDLSY2012]. If these requirements are not met or the validation equation does not hold, then the signature is considered invalid. The encoding of an Ed25519 signature is: 256-bit 𝑅 256-bit 𝑆 where 𝑅 and 𝑆 are as defined in [BDLSY2012]. Notes: • It is not required that the integer encoding of the 𝑦-coordinate 5 of the points represented by 𝑅 or 𝐴 are less than 2255 − 19. • It is not required that 𝐴 ̸∈ ExcludedPointEncodings. • [Canopy onward] Appendix § B.3 ‘Ed25519 batch validation’ on p. 160 describes an optimization that MAY be used to speed up validation of batches of Ed25519 signatures. Non-normative note: The exclusion, before Canopy activation, of ExcludedPointEncodings from 𝑅 is due to a quirk of version 1.0.15 of the libsodium library [libsodium] which was initially used to implement Ed25519 signature validation in zcashd. (The ED25519_COMPAT compile-time option was not set.) The intent was to exclude points of order less than ℓ; however, not all such points were covered. It is possible, with due attention to detail, to reproduce this quirk without using libsodium v1.0.15. 5.4.6 RedDSA and RedJubjub RedDSA is a Schnorr-based signature scheme, optionally supporting key re-randomization as described in § 4.1.6.1 ‘Signature with Re-Randomizable Keys’ on p. 23. It also supports a Secret Key to Public Key Monomorphism as described in § 4.1.6.2 ‘Signature with Signing Key to Validating Key Monomorphism’ on p. 24. It is based on a scheme from [FKMSSS2016, section 3], with some ideas from EdDSA [BJLSY2015]. RedJubjub is a specialization of RedDSA to the Jubjub curve (§ 5.4.8.3 ‘Jubjub’ on p. 73), using the BLAKE2b-512 hash function. The spend authorization signature scheme defined in § 5.4.6.1 ‘Spend Authorization Signature’ on p. 67 is instan- tiated by RedJubjub. The binding signature scheme BindingSig defined in § 5.4.6.2 ‘Binding Signature’ on p. 68 is instantiated by RedJubjub without use of key re-randomization. We first describe the scheme RedDSA over a general represented group. Its parameters are: • a represented group G, which also defines a subgroup G(𝑟) of order 𝑟G , a cofactor ℎG , a group operation +, an additive identity 𝒪G , a bit-length ℓG , a representation function reprG , and an abstraction function abstG , as specified in § 4.1.8 ‘Represented Group’ on p. 26; • 𝒫G , a generator of G(𝑟) ; • a bit-length ℓH N such that 2ℓH −128 ≥ 𝑟G and ℓH mod 8 = 0; ◦ ◦ • a cryptographic hash function H BY[N] → BY[ℓH /8] . ◦ ◦ 65

Its associated types are defined as follows: RedDSA.Message := BY[N] RedDSA.Signature := BY[ceiling(ℓG /8) + ceiling(bitlength(𝑟G )/8)] RedDSA.Public := G RedDSA.Private := F𝑟G . RedDSA.Random := F𝑟G . Define H~ BY[N] → F𝑟G by: ◦ ◦ H~ (𝐵) = LEOS2IPℓH H(𝐵) (mod 𝑟G ) (︀ )︀ R Define RedDSA.GenPrivate () → RedDSA.Private as: ◦ ◦ R Return sk ← F𝑟G . Define RedDSA.DerivePublic RedDSA.Private → RedDSA.Public by: ◦ ◦ RedDSA.DerivePublic(sk) := [sk] 𝒫G . R Define RedDSA.GenRandom () → RedDSA.Random as: ◦ ◦ Choose a byte sequence 𝑇 uniformly at random on BY[(ℓH +128)/8] . Return H~ (𝑇 ). Define 𝒪RedDSA.Random := 0 (mod 𝑟G ). Define RedDSA.RandomizePrivate RedDSA.Random × RedDSA.Private → RedDSA.Private by: ◦ ◦ RedDSA.RandomizePrivate(𝛼, sk) := sk + 𝛼 (mod 𝑟G ). Define RedDSA.RandomizePublic RedDSA.Random × RedDSA.Public → RedDSA.Public as: ◦ ◦ RedDSA.RandomizePublic(𝛼, vk) := vk + [𝛼] 𝒫G . R Define RedDSA.Sign (sk RedDSA.Private) × (𝑀 RedDSA.Message) → ◦ ◦ ◦ ◦ ◦ ◦RedDSA.Signature as: Choose a byte sequence 𝑇 uniformly at random on BY[(ℓH +128)/8] . Let vk = LEBS2OSPℓG reprG (RedDSA.DerivePublic(sk)) . (︀ )︀ Let 𝑟 = H~ (𝑇 || vk || 𝑀 ). Let 𝑅 = [𝑟] 𝒫G . Let 𝑅 = LEBS2OSPℓG reprG (𝑅) . (︀ )︀ Let 𝑆 = (𝑟 + H~ (𝑅 || vk || 𝑀 ) · sk) mod 𝑟G . Let 𝑆 = LEBS2OSPbitlength(𝑟G ) I2LEBSPbitlength(𝑟G ) (𝑆) . (︀ )︀ Return 𝑅 || 𝑆. Define RedDSA.Validate (vk RedDSA.Public) × (𝑀 RedDSA.Message) × (𝜎 RedDSA.Signature) → B as: ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ Let 𝑅 be the first ceiling ℓG /8 bytes of 𝜎, and let 𝑆 be the remaining ceiling (bitlength(𝑟G )/8) bytes. (︀ )︀ Let 𝑅 = abstG LEOS2BSPℓG (𝑅) , and let 𝑆 = LEOS2IP8·length(𝑆) (𝑆). (︀ )︀ Let vk = LEBS2OSPℓG reprG (vk) . (︀ )︀ Let 𝑐 = H~ (𝑅 || vk || 𝑀 ). Return 1 if 𝑅 ̸= ⊥ and 𝑆 < 𝑟G and [ℎG ] −[𝑆] 𝒫G + 𝑅 + [𝑐] vk = 𝒪G , otherwise 0. (︀ )︀ 66

Notes: • The validation algorithm does not check that 𝑅 is a point of order at least 𝑟G . • The value 𝑅 used as part of the input to H~ MUST be exactly as encoded in the signature. • Appendix § B.1 ‘RedDSA batch validation’ on p. 157 describes an optimization that MAY be used to speed up validation of batches of RedDSA signatures. Non-normative note: The randomization used in RedDSA.RandomizePrivate and RedDSA.RandomizePublic may interact with other uses of additive properties of keys for Schnorr-based signature schemes. In the Zcash protocol, such properties are used for binding signatures but not at the same time as key randomization. They are also used in [ZIP-32] when deriving child extended keys, but this does not result in any practical security weakness as long as the security recommendations of ZIP-32 are followed. If RedDSA is reused in other protocols making use of these additive properties, careful analysis of potential interactions is required. The two abelian groups specified in § 4.1.6.2 ‘Signature with Signing Key to Validating Key Monomorphism’ on p. 24 are instantiated for RedDSA as follows: • 𝒪 := 0 (mod 𝑟G ) • sk1 sk2 := sk1 + sk2 (mod 𝑟G ) • 𝒪 := 𝒪G • vk1 vk2 := vk1 + vk2 . As required, RedDSA.DerivePublic is a group monomorphism, since it is injective and: RedDSA.DerivePublic(sk1 sk2 ) = [sk1 + sk2 (mod 𝑟G )] 𝒫G = [sk1 ] 𝒫G + [sk2 ] 𝒫G (since 𝒫G has order 𝑟G ) = RedDSA.DerivePublic(sk1 ) RedDSA.DerivePublic(sk2 ). A RedDSA validating key vk can be encoded as a bit sequence reprG (vk) of length ℓG bits (or as a corresponding byte sequence vk by then applying LEBS2OSPℓG ). The scheme RedJubjub specializes RedDSA with: • G := J as defined in § 5.4.8.3 ‘Jubjub’ on p. 73; • ℓH := 512; • H(𝑥) := BLAKE2b-512(“Zcash_RedJubjubH”, 𝑥) as defined in § 5.4.1.2 ‘BLAKE2 Hash Functions’ on p. 55. The generator 𝒫G G(𝑟) is left as an unspecified parameter, different between BindingSig and SpendAuthSig. ◦ ◦ 5.4.6.1 Spend Authorization Signature Let RedJubjub be as defined in § 5.4.6 ‘RedDSA and RedJubjub’ on p. 65. (𝑟)* Define 𝒢 := FindGroupHashJ (“Zcash_G_”, “”). The spend authorization signature scheme, SpendAuthSig, is instantiated as RedJubjub with key re-randomization, and with generator 𝒫G = 𝒢. See § 4.13 ‘Spend Authorization Signature’ on p. 41 for details on the use of this signature scheme. Security requirement: SpendAuthSig must be a SURK-CMA secure signature scheme with re-randomizable keys as defined in § 4.1.6.1 ‘Signature with Re-Randomizable Keys’ on p. 23. 67

5.4.6.2 Binding Signature Let RedJubjub be as defined in § 5.4.6 ‘RedDSA and RedJubjub’ on p. 65. Let ℛ be the randomness base defined in § 5.4.7.3 ‘Homomorphic Pedersen commitments’ on p. 69. The binding signature scheme, BindingSig, is instantiated as RedJubjub without use of key re-randomization, and with generator 𝒫G = ℛ. See § 4.12 ‘Balance and Binding Signature (Sapling)’ on p. 39 for details on the use of this signature scheme. Security requirement: BindingSig must be a SUF-CMA secure signature scheme with key monomorphism as defined in § 4.1.6.2 ‘Signature with Signing Key to Validating Key Monomorphism’ on p. 24. A signature must prove knowledge of the discrete logarithm of the validating key with respect to the base ℛ. 5.4.7 Commitment schemes 5.4.7.1 Sprout Note Commitments The commitment scheme NoteCommitSprout specified in § 4.1.7 ‘Commitment’ on p. 25 is instantiated using SHA-256 as follows: (︁ )︁ NoteCommitSprout rcm (apk , v, ρ) := SHA-256 1 0 1 1 0 0 0 0 256-bit apk 64-bit v 256-bit ρ 256-bit rcm NoteCommitSprout .GenTrapdoor() generates the uniform distribution on NoteCommitSprout .Trapdoor. Note: The leading byte of the SHA-256 input is 0xB0. Security requirements: • SHA256Compress must be collision-resistant . • SHA256Compress must be a PRF when keyed by the bits corresponding to the position of rcm in the second block of SHA-256 input, with input to the PRF in the remaining bits of the block and the chaining variable. 5.4.7.2 Windowed Pedersen commitments § 5.4.1.7 ‘Pedersen Hash Function’ on p. 58 defines a Pedersen hash construction. We construct “windowed ” Ped- ersen commitments by reusing that construction, and adding a randomized point on the Jubjub curve (see § 5.4.8.3 ‘Jubjub’ on p. 73): (𝑟)* WindowedPedersenCommit𝑟 (𝑠) := PedersenHashToPoint(“Zcash_PH”, 𝑠) + [𝑟] FindGroupHashJ (“Zcash_PH”, “r”) See § A.3.5 ‘Windowed Pedersen Commitment’ on p. 150 for rationale and efficient circuit implementation of this function. The commitment scheme NoteCommitSapling specified in § 4.1.7 ‘Commitment’ on p. 25 is instantiated as follows using WindowedPedersenCommit: (︁ )︁ NoteCommitSapling rcm (g⋆d , pk⋆d , v) := WindowedPedersenCommit rcm [1]6 || I2LEBSP64 (v) || g⋆d || pk⋆d NoteCommitSapling .GenTrapdoor() generates the uniform distribution on F𝑟J . 68

Security requirements: • WindowedPedersenCommit, and hence NoteCommitSapling , must be computationally binding and at least com- putationally hiding commitment schemes. (They are in fact unconditionally hiding commitment schemes.) Notes: • MerkleCRHSapling is also defined in terms of PedersenHashToPoint (see § 5.4.1.3 ‘Merkle Tree Hash Function’ on p. 56). The prefix [1]6 distinguishes the use of WindowedPedersenCommit in NoteCommitSapling from the layer prefix used in MerkleCRHSapling . That layer prefix is a 6-bit little-endian encoding of an integer in the range {0 .. MerkleDepthSapling − 1}; because MerkleDepthSapling < 64, it cannot collide with [1]6 . • The arguments to NoteCommitSapling are in a different order to their encodings in WindowedPedersenCommit. There is no particularly good reason for this. 5.4.7.3 Homomorphic Pedersen commitments The windowed Pedersen commitments defined in the preceding section are highly efficient, but they do not support the homomorphic property we need when instantiating ValueCommit. For more details on the use of this property, see § 4.12 ‘Balance and Binding Signature (Sapling)’ on p. 39 and § 3.6 ‘Spend Transfers, Output Transfers, and their Descriptions’ on p. 16. In order to support this property, we also define homomorphic Pedersen commitments as follows: (𝑟)* (𝑟)* HomomorphicPedersenCommitrcv (𝐷, v) := [v] FindGroupHashJ (𝐷, “v”)+ [rcv] FindGroupHashJ (𝐷, “r”) ValueCommit.GenTrapdoor() generates the uniform distribution on F𝑟J . See § A.3.6 ‘Homomorphic Pedersen Commitment’ on p. 150 for rationale and efficient circuit implementation of this function. Define: (𝑟)* 𝒱 := FindGroupHashJ (“Zcash_cv”, “v”) (𝑟)* J ℛ := FindGroupHash (“Zcash_cv”, “r”). The commitment scheme ValueCommit specified in § 4.1.7 ‘Commitment’ on p. 25 is instantiated as follows using HomomorphicPedersenCommit: ValueCommitrcv (v) := HomomorphicPedersenCommitrcv (“Zcash_cv”, v). which is equivalent to: ValueCommitrcv (v) := [v] 𝒱 + [rcv] ℛ. Security requirements: • HomomorphicPedersenCommit must be a computationally binding and at least computationally hiding com- mitment scheme, for a given personalization input 𝐷. • ValueCommit must be a computationally binding and at least computationally hiding commitment scheme. (They are in fact unconditionally hiding commitment schemes.) 69

5.4.8 Represented Groups and Pairings 5.4.8.1 BN-254 The represented pairing BN-254 is defined in this section. Let 𝑞G := 21888242871839275222246405745257275088696311157297823662689037894645226208583. Let 𝑟G := 21888242871839275222246405745257275088548364400416034343698204186575808495617. Let 𝑏G := 3. (𝑞G and 𝑟G are prime.) (𝑟) Let G1 be the group (of order 𝑟G ) of rational points on a Barreto–Naehrig ([BN2005]) curve 𝐸G1 over F𝑞G with equation 𝑦 2 = 𝑥3 + 𝑏G . This curve has embedding degree 12 with respect to 𝑟G . (𝑟) Let G2 be the subgroup of order 𝑟G in the sextic twist 𝐸G2 of 𝐸G1 over F𝑞 2 with equation 𝑦 2 = 𝑥3 + 𝑏G 𝜉 , where G 𝜉 F𝑞 2 . ◦ ◦ G We represent elements of F𝑞 2 as polynomials 𝑎1 · 𝑡 + 𝑎0 F𝑞G [𝑡], modulo the irreducible polynomial 𝑡2 + 1; in this ◦ ◦ G representation, 𝜉 is given by 𝑡 + 9. Let G𝑇 be the subgroup of 𝑟Gth roots of unity in F*𝑞 12 , with multiplicative identity 1G . (𝑟) G (𝑟) (𝑟) (𝑟) Let 𝑒^G be the optimal ate pairing (see [Vercauter2009] and [AKLGL2010, section 2]) of type G1 × G2 → G𝑇 . (𝑟) (𝑟)* (𝑟) For 𝑖 {1 .. 2}, let 𝒪G𝑖 be the point at infinity (which is the additive identity) in G𝑖 , and let G𝑖 ◦ ◦ := G𝑖 ∖ {𝒪G𝑖 }. (𝑟)* Let 𝒫G1 G1 ◦ ◦ := (1, 2). (𝑟)* Let 𝒫G2 ◦ ◦ G2 := (11559732032986387107991004021392285783925812861821192530917403151452391805634 · 𝑡 + 10857046999023057135944570762232829481370756359578518086990519993285655852781, 4082367875863433681332203403145435568316851327593401208105741076214120093531 · 𝑡 + 8495653923123431417604973247489272438418190587263600148770280649306958101930). (𝑟) (𝑟) 𝒫G1 and 𝒫G2 are generators of G1 and G2 respectively. Define I2BEBSP (ℓ N) × {0 .. 2ℓ −1} → B[ℓ] as in § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53. ◦ ◦ ◦ ◦ (𝑟)* For a point 𝑃 ◦ ◦ G1 = (𝑥𝑃 , 𝑦𝑃 ): • The field elements 𝑥𝑃 and 𝑦𝑃 ◦ ◦ F𝑞 are represented as integers 𝑥 and 𝑦 {0 .. 𝑞−1}. ◦ ◦ • Let 𝑦˜ = 𝑦 mod 2. • 𝑃 is encoded as 0 0 0 0 0 0 1 1-bit 𝑦˜ 256-bit I2BEBSP256 (𝑥) . (𝑟)* For a point 𝑃 ◦ ◦ G2 = (𝑥𝑃 , 𝑦𝑃 ): • Define FE2IP F𝑞G [𝑡]/(𝑡2 + 1) → {0 .. 𝑞G2 −1} such that FE2IP(𝑎𝑤,1 · 𝑡 + 𝑎𝑤,0 ) = 𝑎𝑤,1 · 𝑞 + 𝑎𝑤,0 . ◦ ◦ • Let 𝑥 = FE2IP(𝑥𝑃 ), 𝑦 = FE2IP(𝑦𝑃 ), and 𝑦 ′ = FE2IP(−𝑦𝑃 ). {︃ 1, if 𝑦 > 𝑦 ′ • Let 𝑦˜ = 0, otherwise. • 𝑃 is encoded as 0 0 0 0 1 0 1 1-bit 𝑦˜ 512-bit I2BEBSP512 (𝑥) . 70

Non-normative notes: (𝑟) (𝑟)* • Only the 𝑟G -order subgroups G2,𝑇 are used in the protocol, not their containing groups G2,𝑇 . Points in G2 are always checked to be of order 𝑟G when decoding from external representation. (The group of rational (𝑟) points G1 on 𝐸G1 /F𝑞G is of order 𝑟G so no subgroup checks are needed in that case, and elements of G𝑇 are (𝑟) never represented externally.) The (𝑟) superscripts on G1,2,𝑇 are used for consistency with notation elsewhere in this specification. • The points at infinity 𝒪G1,2 never occur in proofs and have no defined encodings in this protocol. (𝑟)* • A rational point 𝑃 ̸= 𝒪G2 on the curve 𝐸G2 can be verified to be of order 𝑟G , and therefore in G2 , by checking that 𝑟G · 𝑃 = 𝒪G2 . • The use of big-endian order by I2BEBSP is different from the encoding of most other integers in this pro- (𝑟)* tocol. The encodings for G1,2 are consistent with the definition of EC2OSP for compressed curve points (𝑟)* in [IEEE2004, section 5.5.6.2]. The LSB compressed form (i.e. EC2OSP-XL) is used for points in G1 , and the (𝑟)* SORT compressed form (i.e. EC2OSP-XS) for points in G2 . • Testing 𝑦 > 𝑦 ′ for the compression of G2 (𝑟)* points is equivalent to testing whether (𝑎𝑦,1 , 𝑎𝑦,0 ) > (𝑎−𝑦,1 , 𝑎−𝑦,0 ) in lexicographic order. • Algorithms for decompressing points from the above encodings are given in [IEEE2000, Appendix A.12.8] for (𝑟)* (𝑟)* G1 , and [IEEE2004, Appendix A.12.11] for G2 . When computing square roots in F𝑞G or F𝑞 2 in order to decompress a point encoding, the implementation MUST G NOT assume that the square root exists, or that the encoding represents a point on the curve. 5.4.8.2 BLS12-381 The represented pairing BLS12-381 is defined in this section. Parameters are taken from [Bowe2017]. Let 𝑞S := 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787. Let 𝑟S := 52435875175126190479447740508185965837690552500527637822603658699938581184513. Let 𝑢S := −15132376222941642752. Let 𝑏S := 4. (𝑞S and 𝑟S are prime.) (𝑟) Let S1 be the subgroup of order 𝑟S of the group of rational points on a Barreto–Lynn–Scott ([BLS2002]) curve 𝐸S1 over F𝑞 S with equation 𝑦 2 = 𝑥3 + 𝑏S . This curve has embedding degree 12 with respect to 𝑟S . (𝑟) Let S2 be the subgroup of order 𝑟S in the sextic twist 𝐸S2 of 𝐸S1 over F𝑞 2 with equation 𝑦 2 = 𝑥3 + 4(𝑖 + 1), where S 𝑖 F𝑞 2 . ◦ ◦ S We represent elements of F𝑞 2 as polynomials 𝑎1 · 𝑡 + 𝑎0 F𝑞S [𝑡], modulo the irreducible polynomial 𝑡2 + 1; in this ◦ ◦ S representation, 𝑖 is given by 𝑡. Let S𝑇 be the subgroup of 𝑟Sth roots of unity in F*𝑞 12 , with multiplicative identity 1S . (𝑟) S (𝑟) (𝑟) (𝑟) Let 𝑒^S be the optimal ate pairing of type S1 × S2 → S𝑇 . (𝑟) (𝑟)* (𝑟) For 𝑖 {1 .. 2}, let 𝒪S𝑖 be the point at infinity in S𝑖 , and let S𝑖 ◦ ◦ := S𝑖 ∖ {𝒪S𝑖 }. 71

(𝑟)* Let 𝒫S1 S1 ◦ ◦ := (3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507, 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569). (𝑟)* Let 𝒫S2 S2 ◦ ◦ := (3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758 · 𝑡 + 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160, 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582 · 𝑡 + 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905). (𝑟) (𝑟) 𝒫S1 and 𝒫S2 are generators of S1 and S2 respectively. Define I2BEBSP (ℓ N) × {0 .. 2ℓ −1} → B[ℓ] as in § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53. ◦ ◦ ◦ ◦ (𝑟)* For a point 𝑃 ◦ ◦ S1 = (𝑥𝑃 , 𝑦𝑃 ): • The field elements 𝑥𝑃 and 𝑦𝑃 ◦ ◦ F𝑞S are represented as integers 𝑥 and 𝑦 {0 .. 𝑞S −1}. ◦ ◦ {︃ 1, if 𝑦 > 𝑞 S − 𝑦 • Let 𝑦˜ = 0, otherwise. • 𝑃 is encoded as 1 0 1-bit 𝑦˜ 381-bit I2BEBSP381 (𝑥) . (𝑟)* For a point 𝑃 ◦ ◦ S2 = (𝑥𝑃 , 𝑦𝑃 ): • Define FE2IPP F𝑞S [𝑡]/(𝑡2 + 1) → {0 .. 𝑞S −1}[2] such that FE2IPP(𝑎𝑤,1 · 𝑡 + 𝑎𝑤,0 ) = [𝑎𝑤,1 , 𝑎𝑤,0 ]. ◦ ◦ • Let 𝑥 = FE2IPP(𝑥𝑃 ), 𝑦 = FE2IPP(𝑦𝑃 ), and 𝑦 ′ = FE2IPP(−𝑦𝑃 ). {︃ 1, if 𝑦 > 𝑦 ′ lexicographically • Let 𝑦˜ = 0, otherwise. • 𝑃 is encoded as 1 0 1-bit 𝑦˜ 381-bit I2BEBSP381 (𝑥1 ) 384-bit I2BEBSP384 (𝑥2 ) . Non-normative notes: (𝑟) (𝑟)* • Only the 𝑟S -order subgroups S1,2,𝑇 are used in the protocol, not their containing groups S1,2,𝑇 . Points in S1,2 (𝑟) are always checked to be of order 𝑟S when decoding from external representation. (Elements of S𝑇 are (𝑟) never represented externally.) The (𝑟) superscripts on S1,2,𝑇 are used for consistency with notation elsewhere in this specification. • The points at infinity 𝒪S1,2 never occur in proofs and have no defined encodings in this protocol. • In contrast to the corresponding BN-254 curve, 𝐸S1 over F𝑞 S is not of prime order. (𝑟)* • A rational point 𝑃 ̸= 𝒪S𝑖 on the curve 𝐸S𝑖 for 𝑖 ∈ {1, 2} can be verified to be of order 𝑟S , and therefore in S𝑖 , by checking that 𝑟S · 𝑃 = 𝒪S𝑖 . (𝑟)* • The encodings for S1,2 are specific to Zcash. (𝑟)* (𝑟)* • Algorithms for decompressing points from the encodings of S1,2 are defined analogously to those for G1,2 in § 5.4.8.1 ‘BN-254’ on p. 70, taking into account that the SORT compressed form (not the LSB compressed form) (𝑟)* is used for S1 . When computing square roots in F𝑞 S or F𝑞 2 in order to decompress a point encoding, the implementation MUST S NOT assume that the square root exists, or that the encoding represents a point on the curve. 72

5.4.8.3 Jubjub “You boil it in sawdust: you salt it in glue: You condense it with locusts and tape: Still keeping one principal object in view— To preserve its symmetrical shape.” — Lewis Carroll, “The Hunting of the Snark” [Carroll1876] Sapling uses an elliptic curve, Jubjub, designed to be efficiently implementable in zk-SNARK circuits. The repre- sented group J of points on this curve is defined in this section. A complete twisted Edwards elliptic curve, as defined in [BL2017, section 4.3.4], is an elliptic curve 𝐸 over a non- binary field F𝑞 , parameterized by distinct 𝑎, 𝑑 F𝑞 ∖ {0} such that 𝑎 is square and 𝑑 is nonsquare, with equation ◦ ◦ 𝐸 : 𝑎·𝑢2 + v2 = 1 + 𝑑·𝑢2 ·v2 . We use the abbreviation “ctEdwards” to refer to complete twisted Edwards elliptic curves and coordinates. Let 𝑞J := 𝑟S , as defined in § 5.4.8.2 ‘BLS12-381’ on p. 71. Let 𝑟J := 6554484396890773809930967563523245729705921265872317281365359162392183254199. (𝑞J and 𝑟J are prime.) Let ℎJ := 8. Let 𝑎J := −1. Let 𝑑J := −10240/10241 (mod 𝑞J ). Let J be the group of points (𝑢, v) on a ctEdwards curve 𝐸J over F𝑞J with equation 𝑎J ·𝑢2 + v2 = 1 + 𝑑J ·𝑢2 ·v2 . The zero point with coordinates (0, 1) is denoted 𝒪J . J has order ℎJ ·𝑟J . Let ℓJ := 256. Define I2LEBSP (ℓ N) × {0 .. 2ℓ −1} → B[ℓ] as in § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53, and ◦ ◦ ◦ ◦ similarly for LEBS2IP (ℓ N) × B[ℓ] → {0 .. 2ℓ −1}. ◦ ◦ ◦ ◦ Define reprJ J → B[ℓJ ] such that reprJ (𝑢, v) = I2LEBSP256 v + 2255 · 𝑢 ˜ , where 𝑢 (︀ )︀ ◦ ◦ ˜ = 𝑢 mod 2. Define abstJ B[ℓJ ] → J ∪ {⊥} such that abstJ (𝑃 ⋆)is computed as follows: ◦ ◦ let v⋆ B[255] be the first 255 bits of 𝑃 ⋆ and let 𝑢 ◦ ◦ ˜ B be the last bit. ◦ ◦ if LEBS2IP255 (v⋆) ≥ 𝑞J then return ⊥, otherwise let v F𝑞J = LEBS2IP255 (v⋆) (mod 𝑞J ). ◦ ◦ if 𝑎J − 𝑑J ·v2 = 0, return ⊥. √︂ 1 − v2 let 𝑢 = ? 2 . 𝑎J − 𝑑J · v if 𝑢 = ⊥, return ⊥. if 𝑢 mod 2 = 𝑢 ˜ then return (𝑢, v) else return (𝑞J − 𝑢, v). Note: In earlier versions of this specification, abstJ was defined as the left inverse of reprJ such that if 𝑆 is not in the range of reprJ , then abstJ (𝑆) = ⊥. This differs from the specification above: (︁ )︀)︁ (︁ )︀)︁ • Previously, abstJ I2LEBSP256 2255 + 1 and abstJ I2LEBSP256 2255 − 1 were defined as ⊥. (︀ (︀ (︁ )︀)︁ • In the current specification, abstJ I2LEBSP256 2255 + 1 = abstJ I2LEBSP256 (1) = (0, 1) = 𝒪J , and also (︀ (︀ )︀ (︁ )︀)︁ abstJ I2LEBSP256 2255 − 1 = abstJ I2LEBSP256 (−1) = (0, −1). (︀ (︀ )︀ Define J(𝑟) as the order-𝑟J subgroup of J. Note that this includes 𝒪J . For the set of points of order 𝑟J (which excludes 𝒪J ), we write J(𝑟)* . {︁ }︁ (𝑟) Define J⋆ := reprJ (𝑃 ) B[ℓJ ] | 𝑃 ∈ J(𝑟) . ◦ ◦ 73

Non-normative notes: • The ctEdwards compressed encoding used here is consistent with that used in EdDSA [BJLSY2015] for validating keys and the 𝑅 element of a signature. • [BJLSY2015, “Encoding and parsing curve points”] gives algorithms for decompressing points from the encod- ing of J. When computing square roots in F𝑞J in order to decompress a point encoding, the implementation MUST NOT assume that the square root exists, or that the encoding represents a point on the curve. This specification requires “strict” parsing as defined in [BJLSY2015, “Encoding and parsing integers”]. Note that algorithms elsewhere in this specification that use Jubjub may impose other conditions on points, for example that they have order at least 𝑟J . 5.4.8.4 Hash Extractor for Jubjub Let 𝑢((𝑢, v)) = 𝑢 and let v((𝑢, v)) = v. Define ExtractJ(𝑟) J(𝑟) → B[ℓMerkleSapling ] by ◦ ◦ ExtractJ(𝑟) (𝑃 ) := I2LEBSPℓMerkleSapling (𝑢(𝑃 )). Facts: The point (0, 1) = 𝒪J , and the point (0, −1) has order 2 in J. J(𝑟) is of odd-prime order. Lemma 5.4.3. Let 𝑃 = (𝑢, v) ∈ J(𝑟) . Then (𝑢, −v) ∈ / J(𝑟) . / J(𝑟) . Else, 𝑃 is of odd-prime order. Note that v ̸= 0. (If v = 0 then 𝑎 · 𝑢2 = 1, Proof. If 𝑃 = 𝒪J then (𝑢, −v) = (0, −1) ∈ and so applying the doubling formula gives [2] 𝑃 = (0, −1), then [4] 𝑃 = (0, 1) = 𝒪J ; contradiction since then 𝑃 would not be of odd-prime order.) Therefore, −v ̸= v. Now suppose (𝑢, −v) = 𝑄 is a point in J(𝑟) . Then by applying the doubling formula we have [2] 𝑄 = −[2] 𝑃 . But also [2] (−𝑃 ) = −[2] 𝑃 . Therefore either 𝑄 = −𝑃 (then v(𝑄) = v(−𝑃 ); contradiction since −v ̸= v), or doubling is not injective on J(𝑟) (contradiction since J(𝑟) is of odd order [KvE2013]). Theorem 5.4.4. 𝑢 is injective on J(𝑟) . Proof. By writing the curve equation as v2 = (1 − 𝑎·𝑢2 )/(1 − 𝑑·𝑢2 ), and noting that the potentially exceptional case 1 − 𝑑·𝑢2 = 0 does not occur for a ctEdwards curve, we see that for a given 𝑢 there can be at most two possible solutions for v, and that if there are two solutions they can be written as v and −v. In that case by the Lemma, at most one of (𝑢, v) and (𝑢, −v) is in J(𝑟) . Therefore, 𝑢 is injective on points in J(𝑟) . Since I2LEBSPℓMerkleSapling is injective, it follows that ExtractJ(𝑟) is injective on J(𝑟) . 5.4.8.5 Group Hash into Jubjub Let GroupHash.Input := BY[8] × BY[N] , and let GroupHash.URSType := BY[64] . (The input element with type BY[8] is intended to act as a “personalization” parameter to distinguish uses of the group hash for different purposes.) Let URS be the MPC randomness beacon defined in § 5.9 ‘Randomness Beacon’ on p. 83. Let BLAKE2s-256 be as defined in § 5.4.1.2 ‘BLAKE2 Hash Functions’ on p. 55. Let LEOS2IP be as defined in § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53. Let J(𝑟) , J(𝑟)* , and abstJ be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73. Let 𝐷 BY[8] be an 8-byte domain separator, and let 𝑀 BY[N] be the hash input. ◦ ◦ ◦ ◦ 74

(𝑟)* The hash GroupHashJURS (𝐷, 𝑀 ) J(𝑟)* is calculated as follows: ◦ ◦ let 𝐻 = BLAKE2s-256(𝐷, URS || 𝑀 ) let 𝑃 = abstJ (LEOS2BSP256 (𝐻)) if 𝑃 = ⊥ then return ⊥ let 𝑄 = [ℎJ ] 𝑃 if 𝑄 = 𝒪J then return ⊥, else return 𝑄. Notes: (𝑟)* • The use of GroupHashJURS for DiversifyHash and to generate independent bases needs a random oracle (for (𝑟)* inputs on which GroupHashJURS does not return ⊥); here we show that it is sufficient to employ a simpler random oracle instantiated by BLAKE2s-256 in the security analysis. 𝐻 BY[32] ↦↛∈ {⊥, 𝒪J , (0,−1)} abstJ LEOS2BSP256 (𝐻) J is injective, and both it and its inverse are efficiently ◦ (︀ )︀ ◦ ◦ ◦ computable. 𝑃 ◦ ◦ J(𝑟)* is exactly ℎJ -to-1, and both it and its inverse relation are efficiently computable. J ↦↛∈ {𝒪J } [ℎJ ] 𝑃 ◦ ◦ It follows that when 𝐷 BY[8] , 𝑀 BY[N] ↦→ BLAKE2s-256(𝐷, URS || 𝑀 ) BY[32] is modelled as a random (︀ )︀ ◦ ◦ ◦ ◦ ◦ ◦ (𝑟)* (︀ oracle, 𝐷 BY[8] , 𝑀 BY[N] ↦↛∈ {⊥} GroupHashJURS 𝐷, 𝑀 J(𝑟)* also acts as a random oracle. (︀ ◦ )︀ ◦ )︀ ◦ ◦ ◦ ◦ • The BLAKE2s-256 chaining variable after processing URS may be precomputed. Define first (BY → 𝑇 ∪ {⊥}) → 𝑇 ∪ {⊥} so that first(𝑓 ) = 𝑓 (𝑖) where 𝑖 is the least integer in BY such that 𝑓 (𝑖) ̸= ⊥, ◦ ◦ or ⊥ if no such 𝑖 exists. (𝑟)* (︀ (𝑟)* Define FindGroupHashJ 𝐷, 𝑀 := first(𝑖 BY ↦→ GroupHashJURS (𝐷, 𝑀 || [𝑖]) J(𝑟)* ∪ {⊥}). )︀ ◦ ◦ ◦ ◦ (𝑟)* Note: For random input, FindGroupHashJ returns ⊥ with probability approximately 2−256 . In the Zcash protocol, (𝑟)* most uses of FindGroupHashJ are for constants and do not return ⊥; the only use that could potentially return ⊥ is in the computation of a default diversified payment address in § 4.2.2 ‘Sapling Key Components’ on p. 29. 5.4.9 Zero-Knowledge Proving Systems 5.4.9.1 BCTV14 Before Sapling activation, Zcash uses zk-SNARKs generated by a fork of libsnark [Zcash-libsnark] with the BCTV14 proving system described in [BCTV2014a], which is a modification of the systems in [PHGR2013] and [BCGTV2013]. A BCTV14 proof consists of (𝜋𝐴 G1 , 𝜋𝐴′ G1 , 𝜋𝐵 G2 , 𝜋𝐵′ G1 , 𝜋𝐶 G1 , 𝜋𝐶′ G1 , 𝜋𝐾 G1 , 𝜋𝐻 G1 ). ◦ (𝑟)* ◦ (𝑟)* ◦ (𝑟)* ◦ (𝑟)* ◦ (𝑟)* ◦ (𝑟)* ◦ (𝑟)* ◦ (𝑟)* ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ It is computed as described in [BCTV2014a, Appendix B], using the pairing parameters specified in § 5.4.8.1 ‘BN-254’ on p. 70. Note: Many details of the proving system are beyond the scope of this protocol document. For example, the quadratic constraint program verifying the JoinSplit statement , or its translation to a Quadratic Arithmetic Program [BCTV2014a, section 2.3], are not specified in this document. In 2015, Bryan Parno found a bug in this translation, which is corrected by the libsnark implementation6 [WCBTV2015] [Parno2015] [BCTV2014a, Remark 2.5]. In practice it will be necessary to use the specific proving and verifying keys that were generated for the Zcash production block chain, given in § 5.7 ‘BCTV14 zk-SNARK Parameters’ on p. 82, together with a proving system implementation that is interoperable with the Zcash fork of libsnark , to ensure compatibility. 6 Confusingly, the bug found by Bryan Parno was fixed in libsnark in 2015, but that fix was incompletely described in the May 2015 update [BCTV2014a-old, Theorem 2.4]. It is described completely in [BCTV2014a, Theorem 2.4] and in [Gabizon2019]. 75

Vulnerability disclosure: BCTV14 is subject to a security vulnerability, separate from [Parno2015], that could allow violation of Knowledge Soundness (and Soundness) [CVE-2019-7167] [SWB2019] [Gabizon2019]. The consequence for Zcash is that balance violation could have occurred before activation of the Sapling network upgrade, although there is no evidence of this having happened. Use of the vulnerability to produce false proofs is believed to have been fully mitigated by activation of Sapling. The use of BCTV14 in Zcash is now limited to verifying proofs that were made prior to the Sapling network upgrade. Due to this issue, new forks of Zcash MUST NOT use BCTV14, and any other users of the Zcash protocol SHOULD discontinue use of BCTV14 as soon as possible. The vulnerability does not affect the Zero Knowledge property of the scheme (as described in any version of [BCTV2014a] or as implemented in any version of libsnark that has been used in Zcash), even under subversion of the parameter generation [BGG2017, Theorem 4.10]. Encoding of BCTV14 Proofs A BCTV14 proof is encoded by concatenating the encodings of its elements; for the BN-254 pairing this is: 264-bit 𝜋𝐴 264-bit 𝜋𝐴′ 520-bit 𝜋𝐵 264-bit 𝜋𝐵′ 264-bit 𝜋𝐶 264-bit 𝜋𝐶′ 264-bit 𝜋𝐾 264-bit 𝜋𝐻 The resulting proof size is 296 bytes. In addition to the steps to verify a proof given in [BCTV2014a, Appendix B], the verifier MUST check, for the encoding of each element, that: • the lead byte is of the required form; • the remaining bytes encode a big-endian representation of an integer in {0 .. 𝑞S −1} or (in the case of 𝜋𝐵 ) {0 .. 𝑞S2 −1}; (𝑟)* (𝑟)* • the encoding represents a point in G1 or (in the case of 𝜋𝐵 ) G2 , including checking that it is of order 𝑟G in the latter case. 5.4.9.2 Groth16 After Sapling activation, Zcash uses zk-SNARKs with the Groth16 proving system described in [BGM2017], which is a modification of the system in [Groth2016]. An independent security proof of this system and its setup is given in [Maller2018]. Groth16 zk-SNARK proofs are used in transaction version 4 and later (§ 7.1 ‘Transaction Encoding and Consensus’ on p. 85), both in Sprout JoinSplit descriptions and in Sapling Spend descriptions and Output descriptions. They are generated by the bellman library [Bowe-bellman]. (𝑟)* (𝑟)* (𝑟)* A Groth16 proof consists of (𝜋𝐴 S1 , 𝜋𝐵 S2 , 𝜋𝐶 S1 ). It is computed as described in [Groth2016, section 3.2], ◦ ◦ ◦ ◦ ◦ ◦ using the pairing parameters specified in § 5.4.8.2 ‘BLS12-381’ on p. 71. The proof elements are in a different order to the presentation in [Groth2016]. Note: The quadratic constraint programs verifying the Spend statement and Output statement are described in Appendix § A ‘Circuit Design’ on p. 137. However, many other details of the proving system are beyond the scope of this protocol document. For example, certain details of the translations of the Spend statement and Output statement to Quadratic Arithmetic Programs are not specified in this document. In practice it will be necessary to use the specific proving and verifying keys generated for the Zcash production block chain (see § 5.8 ‘Groth16 zk-SNARK Parameters’ on p. 83), and a proving system implementation that is interoperable with the bellman library used by Zcash, to ensure compatibility. 76

Encoding of Groth16 Proofs A Groth16 proof is encoded by concatenating the encodings of its elements; for the BLS12-381 pairing this is: 384-bit 𝜋𝐴 768-bit 𝜋𝐵 384-bit 𝜋𝐶 The resulting proof size is 192 bytes. In addition to the steps to verify a proof given in [Groth2016], the verifier MUST check, for the encoding of each element, that: • the leading bitfield is of the required form; • the remaining bits encode a big-endian representation of an integer in {0 .. 𝑞S −1} or (in the case of 𝜋𝐵 ) two integers in that range; (𝑟)* (𝑟)* • the encoding represents a point in S1 or (in the case of 𝜋𝐵 ) S2 , including checking that it is of order 𝑟S in each case. 5.5 Encodings of Note Plaintexts and Memo Fields As explained in § 3.2.1 ‘Note Plaintexts and Memo Fields’ on p. 14, transmitted notes are stored on the block chain in encrypted form. new The note plaintexts in a JoinSplit description are encrypted to the respective transmission keys pkenc,1..Nnew . Each Sprout note plaintext (denoted np) consists of: (leadByte BY, v {0 .. 2ℓvalue −1}, ρ B[ℓPRFSprout ] , rcm NoteCommitSprout .Output, memo BY[512] ) ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ [Sapling onward] The note plaintext in each Output description is encrypted to the diversified transmission key pkd . Each Sapling note plaintext (denoted np) consists of: (leadByte BY, d B[ℓd ] , v {0 .. 2ℓvalue −1}, rseed BY[32] , memo BY[512] ) ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ ◦ memo is a 512-byte memo field associated with this note. The usage of the memo field is by agreement between the sender and recipient of the note. The memo field SHOULD be encoded as one of: • a UTF-8 human-readable string [Unicode], padded by appending zero bytes; or • the byte 0xF6 followed by 511 0x00 bytes, indicating “no memo”; or • any other sequence of 512 bytes starting with a byte value 0xF5 or greater (which is therefore not a valid UTF-8 string), as specified in [ZIP-302]. When the first byte value is less than 0xF5, wallet software is expected to strip any trailing zero bytes and then display the resulting UTF-8 string to the recipient user, where applicable. Incorrect UTF-8-encoded byte sequences SHOULD be displayed as replacement characters (U+FFFD). In other cases, the contents of the memo field SHOULD NOT be displayed unless otherwise specified by [ZIP-302]. Other fields are as defined in § 3.2 ‘Notes’ on p. 13. 77

The encoding of a Sprout note plaintext consists of: 8-bit leadByte 64-bit v 256-bit ρ 256-bit rcm memo (512 bytes) • A byte, 0x00, indicating this version of the encoding of a Sprout note plaintext . • 8 bytes specifying v. • 32 bytes specifying ρ. • 32 bytes specifying rcm. • 512 bytes specifying memo. The encoding of a Sapling note plaintext consists of: 8-bit leadByte 88-bit d 64-bit v 256-bit rseed memo (512 bytes) • A byte indicating this version of the encoding of a Sapling note plaintext . This will be 0x01 before activation of the Canopy network upgrade, and 0x02 afterward. • 11 bytes specifying d. • 8 bytes specifying v. • 32 bytes specifying rseed. • 512 bytes specifying memo. 5.6 Encodings of Addresses and Keys This section describes how Zcash encodes shielded payment addresses, incoming viewing keys, and spending keys. Addresses and keys can be encoded as a byte sequence; this is called the raw encoding . This byte sequence can then be further encoded using Base58Check. The Base58Check layer is the same as for upstream Bitcoin addresses [Bitcoin-Base58]. For Sapling-specific key and address formats, Bech32 [ZIP-173] is used instead of Base58Check. Non-normative note: ZIP 173 is similar to Bitcoin’s BIP 173, except for dropping the limit of 90 characters on an encoded Bech32 string (which does not hold for Sapling viewing keys, for example), and requirements specific to Bitcoin’s Segwit addresses. SHA256Compress outputs are always represented as sequences of 32 bytes. 5.6.1 Transparent Addresses Transparent addresses are either P2SH (Pay to Script Hash) addresses [BIP-13] or P2PKH (Pay to Public Key Hash) addresses [Bitcoin-P2PKH]. 78

The raw encoding of a P2SH address consists of: 8-bit 0x1C 8-bit 0xBD 160-bit script hash • Two bytes [0x1C, 0xBD], indicating this version of the raw encoding of a P2SH address on Mainnet . (Addresses on Testnet use [0x1C, 0xBA] instead.) • 20 bytes specifying a script hash [Bitcoin-P2SH]. The raw encoding of a P2PKH address consists of: 8-bit 0x1C 8-bit 0xB8 160-bit validating key hash • Two bytes [0x1C, 0xB8], indicating this version of the raw encoding of a P2PKH address on Mainnet . (Addresses on Testnet use [0x1D, 0x25] instead.) • 20 bytes specifying a validating key hash, which is a RIPEMD-160 hash [RIPEMD160] of a SHA-256 hash [NIST2015] of a compressed ECDSA key encoding. Notes: • In Bitcoin a single byte is used for the version field identifying the address type. In Zcash two bytes are used. For addresses on Mainnet , this and the encoded length cause the first two characters of the Base58Check encoding to be fixed as “t3” for P2SH addresses, and as “t1” for P2PKH addresses. (This does not imply that a transparent Zcash address can be parsed identically to a Bitcoin address just by removing the “t”.) • Zcash does not yet support Hierarchical Deterministic Wallet addresses [BIP-32]. 5.6.2 Transparent Private Keys These are encoded in the same way as in Bitcoin [Bitcoin-Base58], for both Mainnet and Testnet . 5.6.3 Sprout Payment Addresses Let KASprout be as defined in § 5.4.4.1 ‘Sprout Key Agreement’ on p. 62. A Sprout shielded payment address consists of apk B[ℓPRFSprout ] and pkenc KASprout .Public. ◦ ◦ ◦ ◦ apk is a SHA256Compress output. pkenc is a KASprout .Public key, for use with the encryption scheme defined in § 4.16 ‘In-band secret distribution (Sprout)’ on p. 46. These components are derived from a spending key as described in § 4.2.1 ‘Sprout Key Components’ on p. 29. The raw encoding of a Sprout shielded payment address consists of: 8-bit 0x16 8-bit 0x9A 256-bit apk 256-bit pkenc • Two bytes [0x16, 0x9A], indicating this version of the raw encoding of a Sprout shielded payment address on Mainnet . (Addresses on Testnet use [0x16, 0xB6] instead.) • 32 bytes specifying apk . • 32 bytes specifying pkenc , using the normal encoding of a Curve25519 public key [Bernstein2006]. Note: For addresses on Mainnet , the lead bytes and encoded length cause the first two characters of the Base58Check encoding to be fixed as “zc”. For Testnet , the first two characters are fixed as “zt”. 79

5.6.4 Sapling Payment Addresses Let KASapling be as defined in § 5.4.4.3 ‘Sapling Key Agreement’ on p. 63. A Sapling shielded payment address consists of d B[ℓd ] and pkd KASapling .PublicPrimeSubgroup. ◦ ◦ ◦ ◦ pkd is an encoding of a KASapling public key of type KASapling .PublicPrimeSubgroup, for use with the encryption scheme defined in § 4.17 ‘In-band secret distribution (Sapling)’ on p. 47. d is a sequence of 11 bytes. These components are derived as described in § 4.2.2 ‘Sapling Key Components’ on p. 29. The raw encoding of a Sapling shielded payment address consists of: (︀ )︀ LEBS2OSP88 (d) LEBS2OSP256 reprJ (pkd ) • 11 bytes specifying d. • 32 bytes specifying the ctEdwards compressed encoding of pkd (see § 5.4.8.3 ‘Jubjub’ on p. 73). When decoding the representation of pkd , the address MUST be considered invalid if abstJ returns ⊥ or if the resulting pkd is not in the prime-order subgroup J(𝑟) . Non-normative note: zcashd currently (as of version 3.1.0) does not fully conform to this requirement on address validation when importing shielded payment addresses. For addresses on Mainnet , the Human-Readable Part (as defined in [ZIP-173]) is “zs”. For addresses on Testnet , the Human-Readable Part is “ztestsapling”. 5.6.5 Sprout Incoming Viewing Keys Let KASprout be as defined in § 5.4.4.1 ‘Sprout Key Agreement’ on p. 62. A Sprout incoming viewing key consists of apk B[ℓPRFSprout ] and skenc KASprout .Private. ◦ ◦ ◦ ◦ apk is a SHA256Compress output. skenc is a KASprout .Private key, for use with the encryption scheme defined in § 4.16 ‘In-band secret distribution (Sprout)’ on p. 46. These components are derived from a spending key as described in § 4.2.1 ‘Sprout Key Components’ on p. 29. The raw encoding of a Sprout incoming viewing key consists of, in order: 8-bit 0xA8 8-bit 0xAB 8-bit 0xD3 256-bit apk 256-bit skenc • Three bytes [0xA8, 0xAB, 0xD3], indicating this version of the raw encoding of a Zcash incoming viewing key on Mainnet . (Addresses on Testnet use [0xA8, 0xAC, 0x0C] instead.) • 32 bytes specifying apk . • 32 bytes specifying skenc , using the normal encoding of a Curve25519 private key [Bernstein2006]. skenc MUST be “clamped” using KASprout .FormatPrivate as specified in § 4.2.1 ‘Sprout Key Components’ on p. 29. That is, a decoded incoming viewing key MUST be considered invalid if skenc ̸= KASprout .FormatPrivate(skenc ). KASprout .FormatPrivate is defined in § 5.4.4.1 ‘Sprout Key Agreement’ on p. 62. Note: For addresses on Mainnet , the lead bytes and encoded length cause the first four characters of the Base58Check encoding to be fixed as “ZiVK”. For Testnet , the first four characters are fixed as “ZiVt”. 80

5.6.6 Sapling Incoming Viewing Keys Let KASapling be as defined in § 5.4.4.3 ‘Sapling Key Agreement’ on p. 63. Let ℓivk be as defined in § 5.3 ‘Constants’ on p. 53. A Sapling incoming viewing key consists of ivk {0 .. 2ℓivk −1}. ◦ ◦ ivk is a KASapling .Private key (restricted to ℓivk bits), derived as described in § 4.2.2 ‘Sapling Key Components’ on p. 29. It is used with the encryption scheme defined in § 4.17 ‘In-band secret distribution (Sapling)’ on p. 47. The raw encoding of a Sapling incoming viewing key consists of: 256-bit ivk • 32 bytes (little-endian) specifying ivk, padded with zeros in the most significant bits. ivk MUST be in the range {0 .. 2ℓivk −1} as specified in § 4.2.2 ‘Sapling Key Components’ on p. 29. That is, a decoded incoming viewing key MUST be considered invalid if ivk is not in this range. For incoming viewing keys on Mainnet , the Human-Readable Part is “zivks”. For incoming viewing keys on Testnet , the Human-Readable Part is “zivktestsapling”. 5.6.7 Sapling Full Viewing Keys Let KASapling be as defined in § 5.4.4.3 ‘Sapling Key Agreement’ on p. 63. A Sapling full viewing key consists of ak J(𝑟)* , nk J(𝑟) , and ovk BY[ℓovk /8] . ◦ ◦ ◦ ◦ ◦ ◦ ak and nk are points on the Jubjub curve (see § 5.4.8.3 ‘Jubjub’ on p. 73). They are derived as described in § 4.2.2 ‘Sapling Key Components’ on p. 29. The raw encoding of a Sapling full viewing key consists of: (︀ )︀ (︀ )︀ LEBS2OSP256 reprJ (ak) LEBS2OSP256 reprJ (nk) 32-byte ovk • 32 bytes specifying the ctEdwards compressed encoding of ak (see § 5.4.8.3 ‘Jubjub’ on p. 73). • 32 bytes specifying the ctEdwards compressed encoding of nk. • 32 bytes specifying the outgoing viewing key ovk. When decoding this representation, the key MUST be considered invalid if abstJ returns ⊥ for either ak or nk, or if / J(𝑟)* , or if nk ∈ ak ∈ / J(𝑟) . For incoming viewing keys on Mainnet , the Human-Readable Part is “zviews”. For incoming viewing keys on Testnet , the Human-Readable Part is “zviewtestsapling”. 5.6.8 Sprout Spending Keys A Sprout spending key consists of ask , which is a sequence of 252 bits (see § 4.2.1 ‘Sprout Key Components’ on p. 29). 81

The raw encoding of a Sprout spending key consists of: 8-bit 0xAB 8-bit 0x36 [0]4 252-bit ask • Two bytes [0xAB, 0x36], indicating this version of the raw encoding of a Zcash spending key on Mainnet . (Addresses on Testnet use [0xAC, 0x08] instead.) • 32 bytes: 4 zero padding bits and 252 bits specifying ask . The zero padding occupies the most significant 4 bits of the third byte. Notes: • If an implementation represents ask internally as a sequence of 32 bytes with the 4 bits of zero padding intact, it will be in the correct form for use as an input to PRFaddr , PRFnf , and PRFpk without need for bit-shifting. Future key representations may make use of these padding bits. • For addresses on Mainnet , the lead bytes and encoded length cause the first two characters of the Base58Check encoding to be fixed as “SK”. For Testnet , the first two characters are fixed as “ST”. 5.6.9 Sapling Spending Keys A Sapling spending key consists of sk B[ℓsk ] (see § 4.2.2 ‘Sapling Key Components’ on p. 29). ◦ ◦ The raw encoding of a Sapling spending key consists of: LEBS2OSP256 (sk) • 32 bytes specifying sk. For spending keys on Mainnet , the Human-Readable Part is “secret-spending-key-main”. For spending keys on Testnet , the Human-Readable Part is “secret-spending-key-test”. 5.7 BCTV14 zk-SNARK Parameters The SHA-256 hashes of the proving key and verifying key for the Sprout JoinSplit circuit , encoded in libsnark format, are: 8bc20a7f013b2b58970cddd2e7ea028975c88ae7ceb9259a5344a16bc2c0eef7 sprout-proving.key 4bd498dae0aacfd8e98dc306338d017d9c08dd0918ead18172bd0aec2fc5df82 sprout-verifying.key These parameters were obtained by a multi-party computation described in [BGG-mpc] and [BGG2017]. They are used only before Sapling activation. Due to the security vulnerability described in § 5.4.9.1 ‘BCTV14’ on p. 75, it is not recommended to use these parameters in new protocols, and it is recommended to stop using them in protocols other than Zcash where they are currently used. 82

5.8 Groth16 zk-SNARK Parameters bellman [Bowe-bellman] encodes the proving key and verifying key for a zk-SNARK circuit in a single parameters file. The BLAKE2b-512 hashes of this file for the Sapling Spend circuit and Output circuit , and for the implementa- tion of the Sprout JoinSplit circuit used after Sapling activation, are respectively: 8270785a1a0d0bc77196f000ee6d221c9c9894f55307bd9357c3f0105d31ca63 991ab91324160d8f53e2bbd3c2633a6eb8bdf5205d822e7f3f73edac51b2b70c sapling-spend.params 657e3d38dbb5cb5e7dd2970e8b03d69b4787dd907285b5a7f0790dcc8072f60b f593b32cc2d1c030e00ff5ae64bf84c5c3beb84ddc841d48264b4a171744d028 sapling-output.params e9b238411bd6c0ec4791e9d04245ec350c9c5744f5610dfcce4365d5ca49dfef d5054e371842b3f88fa1b9d7e8e075249b3ebabd167fa8b0f3161292d36c180a sprout-groth16.params These parameters were obtained by a multi-party computation described in [BGM2017]. 5.9 Randomness Beacon Let URS := “096b36a5804bfacef1691e173c366a47ff5ba84a44f26ddd7e8d9f79d5b42df0”. (𝑟)* This value is used in the definition of GroupHashJ in § 5.4.8.5 ‘Group Hash into Jubjub’ on p. 74, and in the multi- party computation to obtain the Sapling parameters given in § 5.8 ‘Groth16 zk-SNARK Parameters’ on p. 83. It is derived as described in [Bowe2018]: • Take the hash of the Bitcoin block at height 514200 in RPC byte order , i.e. the big-endian 32-byte representation of 0x00000000000000000034b33e842ac1c50456abe5fa92b60f6b3dfc5d247f7b58. • Apply SHA-256 242 times. • Convert to a US-ASCII lowercase hexadecimal string. Note: URS is a 64-byte US-ASCII string, i.e. the first byte is 0x30, not 0x09. 6 Network Upgrades Zcash launched with a protocol revision that we call Sprout. A first network upgrade, called Overwinter, activated on Mainnet on 26 June, 2018 at block height 347500 [Swihart2018] [ZIP-201]. A second upgrade, called Sapling, activated on Mainnet on 28 October, 2018 at block height 419200 [Hamdon2018] [ZIP-205]. A third upgrade, called Blossom, activated on Mainnet on 11 December, 2019 at block height 653600 [Zcash-Blossom] [ZIP-206]. A fourth upgrade, called Heartwood, activated on Mainnet on 16 July, 2020 at block height 903000 [Zcash-Heartwd] [ZIP-250]. A fifth upgrade, called Canopy, activated on Mainnet on 18 November, 2020 at block height 1046400 (coinciding with the first block subsidy halving ) [Zcash-Canopy] [ZIP-251]. This draft specification describes a set of changes codenamed Orchard, which are proposed to activate in a future network upgrade. This section summarizes the strategy for upgrading from Sprout to subsequent versions of the protocol (Overwinter, Sapling, Blossom, Heartwood, and Canopy), and for future upgrades. The network upgrade mechanism is described in [ZIP-200]. The specifications of the Overwinter upgrade are described in this document, [ZIP-201], [ZIP-202], [ZIP-203], and [ZIP-143]. The specifications of the Sapling upgrade are described in this document, [ZIP-205], and [ZIP-243]. The specifications of the Blossom upgrade are described in this document, [ZIP-206], and [ZIP-208]. The specifications of the Heartwood upgrade are described in this document, [ZIP-250], [ZIP-213], and [ZIP-221]. The specifications of the Canopy upgrade are described in this document, [ZIP-251], [ZIP-207], [ZIP-211], [ZIP-212], [ZIP-214], and [ZIP-215]. 83

Each network upgrade is introduced as a “bilateral consensus rule change”. In this kind of upgrade, • there is an activation block height at which the consensus rule change takes effect; • blocks and transactions that are valid according to the post-upgrade rules are not valid before the upgrade block height ; • blocks and transactions that are valid according to the pre-upgrade rules are no longer valid at or after the activation block height . Full support for each network upgrade is indicated by a minimum version of the peer-to-peer protocol. At the planned activation block height , nodes that support a given upgrade will disconnect from (and will not reconnect to) nodes with a protocol version lower than this minimum. See [ZIP-201] for how this applies to the Overwinter upgrade, for example. This ensures that upgrade-supporting nodes transition cleanly from the old protocol to the new protocol. Nodes that do not support the upgrade will find themselves on a network that uses the old protocol and is fully partitioned from the upgrade-supporting network. This allows us to specify arbitrary protocol changes that take effect at a given block height . Note, however, that a block chain reorganization across the upgrade activation block height is possible. In the case of such a reorganization, blocks at a height before the activation block height will still be created and validated according to the pre-upgrade rules, and upgrade-supporting nodes MUST allow for this. 84

7 Consensus Changes from Bitcoin 7.1 Transaction Encoding and Consensus The Zcash transaction format is as follows (this should be read in the context of consensus rules later in the section): Version Bytes Name Data Type Description ≥1 4 header uint32 Contains: · fOverwintered flag (bit 31) · version (bits 30 .. 0) – transaction version. ≥3 4 nVersionGroupId uint32 Version group ID (nonzero). ≥1 Varies tx_in_count compactSize uint Number of transparent inputs. ≥1 Varies tx_in tx_in Transparent inputs, encoded as in Bitcoin. ≥1 Varies tx_out_count compactSize uint Number of transparent outputs. ≥1 Varies tx_out tx_out Transparent outputs, encoded as in Bitcoin. ≥1 4 lock_time uint32 A Unix epoch time (UTC) or block height , encoded as in Bitcoin. ≥3 4 nExpiryHeight uint32 A block height in the range {1 .. 499999999} after which the transaction will expire, or 0 to disable expiry ([ZIP-203]). ≥4 8 valueBalance int64 The net value of Sapling Spend transfers minus Output transfers. ≥4 Varies nShieldedSpend compactSize uint The number of Spend descriptions in vShieldedSpend. ≥4 384· vShieldedSpend SpendDescription A sequence of Spend descriptions, encoded as in nShieldedSpend [nShieldedSpend] § 7.3 ‘Spend Description Encoding and Consensus’ on p. 89. ≥4 Varies nShieldedOutput compactSize uint The number of Output descriptions in vShieldedOutput. ≥4 948· vShieldedOutput OutputDescription A sequence of Output descriptions, encoded as in nShieldedOutput [nShieldedOutput] § 7.4 ‘Output Description Encoding and Consensus’ on p. 89. ≥2 Varies nJoinSplit compactSize uint The number of JoinSplit descriptions in vJoinSplit. 2 .. 3 1802· vJoinSplit JSDescriptionBCTV14 A sequence of JoinSplit descriptions using BCTV14 nJoinSplit [nJoinSplit] proofs, encoded as in § 7.2 ‘JoinSplit Description Encoding and Consensus’ on p. 88. ≥4 1698· vJoinSplit JSDescriptionGroth16 A sequence of JoinSplit descriptions using Groth16 nJoinSplit [nJoinSplit] proofs, encoded as in § 7.2 ‘JoinSplit Description Encoding and Consensus’ on p. 88. ≥2† 32 joinSplitPubKey char[32] An encoding of a JoinSplitSig public validating key . ≥2† 64 joinSplitSig char[64] A signature on a prefix of the transaction encoding, to be verified using joinSplitPubKey. ≥4‡ 64 bindingSig char[64] A signature on the SIGHASH transaction hash, to be verified as specified in § 5.4.6.2 ‘Binding Signature’ on p. 68. † The joinSplitPubKey and joinSplitSig fields are present if and only if version ≥ 2 and nJoinSplit > 0. The encoding of joinSplitPubKey and the data to be signed are specified in § 4.10 ‘Non-malleability (Sprout)’ on p. 38. ‡ The bindingSig field is present if and only if version ≥ 4 and nShieldedSpend + nShieldedOutput > 0. 85

Consensus rules: • The transaction version number MUST be greater than or equal to 1. • [Pre-Overwinter] The fOverwintered flag MUST NOT be set. • [Overwinter onward] The fOverwintered flag MUST be set. • [Overwinter onward] The version group ID MUST be recognized. • [Overwinter only, pre-Sapling] The transaction version number MUST be 3 and the version group ID MUST be 0x03C48270. • [Sapling onward] The transaction version number MUST be 4 and the version group ID MUST be 0x892F2085. • [Pre-Sapling] The encoded size of the transaction MUST be less than or equal to 100000 bytes. • [Pre-Sapling] If version = 1 or nJoinSplit = 0, then both tx_in_count and tx_out_count MUST be nonzero. • [Sapling onward] At least one of tx_in_count, nShieldedSpend, and nJoinSplit MUST be nonzero. • [Sapling onward] At least one of tx_out_count, nShieldedOutput, and nJoinSplit MUST be nonzero. • A transaction with one or more transparent inputs from coinbase transactions MUST have no transparent outputs (i.e. tx_out_count MUST be 0). Inputs from coinbase transactions include Founders’ Reward outputs. • If version ≥ 2 and nJoinSplit > 0, then: – joinSplitPubKey MUST be a valid encoding (see § 5.4.5 ‘Ed25519’ on p. 63) of an Ed25519 validating key . – joinSplitSig MUST represent a valid signature under joinSplitPubKey of dataToBeSigned, as defined in § 4.10 ‘Non-malleability (Sprout)’ on p. 38. • [Sapling onward] If version ≥ 4 and nShieldedSpend + nShieldedOutput > 0, then: – let bvk and SigHash be as defined in § 4.12 ‘Balance and Binding Signature (Sapling)’ on p. 39; – bindingSig MUST represent a valid signature under the transaction binding validating key bvk of SigHash — i.e. BindingSig.Validatebvk (SigHash, bindingSig) = 1. • [Sapling onward] If version ≥ 4 and nShieldedSpend + nShieldedOutput = 0, then valueBalance MUST be 0. • The total amount of transparent outputs from a coinbase transaction, minus the amount of the valueBalance field if present, MUST NOT be greater than the amount of miner subsidy plus the total amount of transaction fees paid by transactions in this block . • A coinbase transaction MUST NOT have any JoinSplit descriptions or Spend descriptions. • [Pre-Heartwood] A coinbase transaction also MUST NOT have any Output descriptions. • A coinbase transaction for a block at block height greater than 0 MUST have a script that, as its first item, encodes the block height as follows. Let heightBytes be the signed little-endian representation of the number, using the minimum number of bytes such that the most significant byte is < 0x80. Then the encoding is the length of heightBytes encoded as one byte, followed by heightBytes itself. This matches the encoding used by Bitcoin in the implementation of [BIP-34] (but the description here is to be considered normative). • A transaction MUST NOT spend a transparent output of a coinbase transaction from a block less than 100 blocks prior to the spend. Note that transparent outputs of coinbase transactions include Founders’ Reward outputs and transparent funding stream outputs. • A transaction MUST NOT spend an output of the genesis block coinbase transaction. (There is one such zero-valued output, on each of Testnet and Mainnet .) • [Overwinter onward] nExpiryHeight MUST be less than or equal to 499999999. • [Overwinter onward] If a transaction is not a coinbase transaction and its nExpiryHeight field is nonzero, then it MUST NOT be mined at a block height greater than its nExpiryHeight. • [Sapling onward] valueBalance MUST be in the range {−MAX_MONEY .. MAX_MONEY}. • [Heartwood onward] All Sapling outputs in coinbase transactions MUST decrypt to a note plaintext , i.e. the procedure in § 4.17.3 ‘Decryption using a Full Viewing Key (Sapling)’ on p. 50 does not return ⊥, using a sequence of 32 zero bytes as the outgoing viewing key . 86

• [Canopy onward] Any Sapling output of a coinbase transaction decrypted to a note plaintext according to the preceding rule MUST have note plaintext lead byte equal to 0x02. (This applies even during the “grace period” specified in [ZIP-212].) • TODO: Other rules inherited from Bitcoin. Consensus rules associated with each JoinSplit description (§ 7.2 ‘JoinSplit Description Encoding and Consensus’ on p. 88), each Spend description (§ 7.3 ‘Spend Description Encoding and Consensus’ on p. 89), and each Output description (§ 7.4 ‘Output Description Encoding and Consensus’ on p. 89) MUST also be followed. Notes: • Previous versions of this specification defined what is now the header field as a signed int32 field which was required to be positive. The consensus rule that the fOverwintered flag MUST NOT be set before Overwinter has activated, has the same effect. • The semantics of transactions with transaction version number not equal to 1, 2, 3, or 4 is not currently defined. Miners MUST NOT create blocks before the Overwinter activation block height containing transactions with version other than 1 or 2. • The exclusion of transactions with transaction version number greater than 2 is not a consensus rule before Overwinter activation. Such transactions may exist in the block chain and MUST be treated identically to version 2 transactions. • [Overwinter onward] Once Overwinter has activated, limits on the maximum transaction version number are consensus rules. • Note that a future upgrade might use any transaction version number or version group ID. It is likely that an upgrade that changes the transaction version number or version group ID will also change the transaction format, and software that parses transactions SHOULD take this into account. • [Overwinter onward] The purpose of version group ID is to allow unambiguous parsing of “loose” transactions, independent of the context of a block chain. Code that parses transactions is likely to be reused between block chain branches as defined in [ZIP-200], and in that case the fOverwintered and version fields alone may be insufficient to determine the format to be used for parsing. • A transaction version number of 2 does not have the same meaning as in Bitcoin, where it is associated with support for OP_CHECKSEQUENCEVERIFY as specified in [BIP-68]. Zcash was forked from Bitcoin v0.11.2 and does not currently support BIP 68. • [Sapling onward] As a consequence of coinbase transactions having no Spend descriptions, the valueBalance field of a coinbase transaction must have a negative or zero value. The negative case can only occur after Heartwood activation, for transactions with [ZIP-213] shielded outputs. • Prior to the Heartwood network upgrade, it was not possible for coinbase transactions to have shielded outputs, and therefore the “coinbase maturity” rule and the requirement to spend coinbase outputs only in transactions with no transparent outputs, applied to all coinbase outputs. • The rule that Sapling outputs in coinbase transactions MUST decrypt to a note plaintext with lead byte 0x02, also applies to funding stream outputs that specify Sapling shielded payment addresses, if there are any. The changes relative to Bitcoin version 1 transactions as described in [Bitcoin-Format] are: • Transaction version 0 is not supported. • A version 1 transaction is equivalent to a version 2 transaction with nJoinSplit = 0. • The nJoinSplit, vJoinSplit, joinSplitPubKey, and joinSplitSig fields have been added. • [Overwinter onward] The nVersionGroupId field has been added. • [Sapling onward] The nShieldedSpend, vShieldedSpend, nShieldedOutput, vShieldedOutput, and bindingSig fields have been added. • In Zcash it is permitted for a transaction to have no transparent inputs, provided at least one of nJoinSplit, nShieldedSpend, and nShieldedOutput are nonzero. 87

• A consensus rule limiting transaction size has been added. In Bitcoin there is a corresponding standard rule but no consensus rule. [Pre-Overwinter ] Software that creates transactions SHOULD use version 1 for transactions with no JoinSplit descriptions. 7.2 JoinSplit Description Encoding and Consensus An abstract JoinSplit description, as described in § 3.5 ‘JoinSplit Transfers and Descriptions’ on p. 16, is encoded in a transaction as an instance of a JoinSplitDescription type as follows: Bytes Name Data Type Description old 8 vpub_old uint64 A value vpubthat the JoinSplit transfer removes from the transparent transaction value pool . new 8 vpub_new uint64 A value vpub that the JoinSplit transfer inserts into the transparent transaction value pool . 32 anchor char[32] A root rt of the Sprout note commitment tree at some block height in the past, or the root produced by a previous JoinSplit transfer in this transaction. 64 nullifiers char[32][Nold ] A sequence of nullifiers of the input notes nf old 1..N old . 64 commitments char[32][Nnew ] A sequence of note commitments for the output notes cmnew 1..N . new 32 ephemeralKey char[32] A Curve25519 public key epk. 32 randomSeed char[32] A 256-bit seed that must be chosen independently at random for each JoinSplit description. 64 vmacs char[32][Nold ] A sequence of message authentication tags h1..Nold binding hSig to each ask of the JoinSplit description, computed as described in § 4.10 ‘Non-malleability (Sprout)’ on p. 38. 296 † zkproof char[296] An encoding of the zk-SNARK proof 𝜋ZKJoinSplit (see § 5.4.9.1 ‘BCTV14’ on p. 75). 192 ‡ zkproof char[192] An encoding of the zk-SNARK proof 𝜋ZKJoinSplit (see § 5.4.9.2 ‘Groth16’ on p. 76). 1202 encCiphertexts char[601][Nnew ] A sequence of ciphertext components for the encrypted output notes, Cenc 1..N . new † BCTV14 proofs are used when the transaction version is 2 or 3, i.e. before Sapling activation. ‡ Groth16 proofs are used when the transaction version is ≥ 4, i.e. after Sapling activation. The ephemeralKey and encCiphertexts fields together form the transmitted notes ciphertext , which is computed as described in § 4.16 ‘In-band secret distribution (Sprout)’ on p. 46. Consensus rules applying to a JoinSplit description are given in § 4.3 ‘JoinSplit Descriptions’ on p. 31. 88

7.3 Spend Description Encoding and Consensus Let LEBS2OSP be as defined in § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53. Let reprJ and 𝑞J be as defined in § 5.4.8.3 ‘Jubjub’ on p. 73. An abstract Spend description, as described in § 3.6 ‘Spend Transfers, Output Transfers, and their Descriptions’ on p. 16, is encoded in a transaction as an instance of a SpendDescription type as follows: Bytes Name Data Type Description 32 cv char[32] A value commitment to )︀ the value of the input note, LEBS2OSP256 reprJ (cv) . (︀ 32 anchor char[32] A root of the Sapling note commitment tree at some block height in the past, LEBS2OSP256 (rt). 32 nullifier char[32] The nullifier of the input note, nf. 32 rk char[32] The randomized (︀ validating key for spendAuthSig, LEBS2OSP256 reprJ (rk) . )︀ 192 zkproof char[192] An encoding of the zk-SNARK proof 𝜋ZKSpend (see § 5.4.9.2 ‘Groth16’ on p. 76). 64 spendAuthSig char[64] A signature authorizing this Spend. Consensus rule: LEOS2IP256 (anchor) MUST be less than 𝑞J . Other consensus rules applying to a Spend description are given in § 4.4 ‘Spend Descriptions’ on p. 32. 7.4 Output Description Encoding and Consensus Let LEBS2OSP be as defined in § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53. Let reprJ and 𝑞J be as in § 5.4.8.3 ‘Jubjub’ on p. 73, and ExtractJ(𝑟) as in § 5.4.8.4 ‘Hash Extractor for Jubjub’ on p. 74. An abstract Output description, described in § 3.6 ‘Spend Transfers, Output Transfers, and their Descriptions’ on p. 16, is encoded in a transaction as an instance of an OutputDescription type as follows: Bytes Name Data Type Description 32 cv char[32] A value commitment to )︀ the value of the output note, LEBS2OSP256 reprJ (cv) . (︀ 32 cmu char[32] The 𝑢-coordinate of the note commitment for the output note, LEBS2OSP256 (cm𝑢 ) where cm𝑢 = ExtractJ(𝑟) (cm). 32 ephemeralKey char[32] An encoding of (︀ an ephemeral Jubjub public key , LEBS2OSP256 reprJ (epk) . )︀ 580 encCiphertext char[580] A ciphertext component for the encrypted output note, Cenc . 80 outCiphertext char[80] A ciphertext component for the encrypted output note, Cout . 192 zkproof char[192] An encoding of the zk-SNARK proof 𝜋ZKOutput (see § 5.4.9.2 ‘Groth16’ on p. 76). The ephemeralKey, encCiphertext, and outCiphertext fields together form the transmitted note ciphertext , which is computed as described in § 4.17 ‘In-band secret distribution (Sapling)’ on p. 47. Consensus rule: LEOS2IP256 (cmu) MUST be less than 𝑞J . Other consensus rules applying to an Output description are given in § 4.5 ‘Output Descriptions’ on p. 33. 89

7.5 Block Header Encoding and Consensus The Zcash block header format is as follows (this should be read in the context of consensus rules later in the section): Bytes Name Data Type Description 4 nVersion int32 The block version number indicates which set of block validation rules to follow. The current and only defined block version number for Zcash is 4. 32 hashPrevBlock char[32] A SHA-256d hash in internal byte order of the previous block ’s header . This ensures no previous block can be changed without also changing this block ’s header . 32 hashMerkleRoot char[32] A SHA-256d hash in internal byte order. The merkle root is derived from the hashes of all transactions included in this block , ensuring that none of those transactions can be modified without modifying the header . 32 hashReserved / char[32] [Pre-Sapling] A reserved field which should hashFinalSaplingRoot / be ignored. [Sapling and Blossom only, hashLightClientRoot pre-Heartwood] The root LEBS2OSP256 (rt) of the Sapling note commitment tree corresponding to the final Sapling treestate of this block . [Heartwood onward] The hashChainHistoryRoot of this block . 4 nTime uint32 The block timestamp is a Unix epoch time (UTC) when the miner started hashing the header (according to the miner). 4 nBits uint32 An encoded version of the target threshold this block ’s header hash must be less than or equal to, in the same nBits format used by Bitcoin. [Bitcoin-nBits] 32 nNonce char[32] An arbitrary field that miners can change to modify the header hash in order to produce a hash less than or equal to the target threshold . 3 solutionSize compactSize uint The size of an Equihash solution in bytes (always 1344). 1344 solution char[1344] The Equihash solution. A block consists of a block header and a sequence of transactions. How transactions are encoded in a block is part of the Zcash peer-to-peer protocol but not part of the consensus protocol. Let ThresholdBits be as defined in § 7.6.3 ‘Difficulty adjustment’ on p. 93, and let PoWMedianBlockSpan be the con- stant defined in § 5.3 ‘Constants’ on p. 53. Define the median-time-past of a block to be the median (as defined in § 7.6.3 ‘Difficulty adjustment’ on p. 93) of the nTime fields of the preceding PoWMedianBlockSpan blocks (or all preceding blocks if there are fewer than PoWMedianBlockSpan). The median-time-past of a genesis block is not defined. 90

Consensus rules: • The block version number MUST be greater than or equal to 4. • For a block at block height height, nBits MUST be equal to ThresholdBits(height). • The block MUST pass the difficulty filter defined in § 7.6.2 ‘Difficulty filter’ on p. 93. • solution MUST represent a valid Equihash solution as defined in § 7.6.1 ‘Equihash’ on p. 92. • For each block other than the genesis block , nTime MUST be strictly greater than the median-time-past of that block . • For each block at block height 2 or greater on Mainnet , or block height 653606 or greater on Testnet , nTime MUST be less than or equal to the median-time-past of that block plus 90 · 60 seconds. • The size of a block MUST be less than or equal to 2000000 bytes. • [Sapling and Blossom only, pre-Heartwood] hashLightClientRoot MUST be LEBS2OSP256 (rt) where rt is the root of the Sapling note commitment tree for the final Sapling treestate of this block . • [Heartwood onward] hashLightClientRoot MUST be set to the value of hashChainHistoryRoot for this block , as specified in [ZIP-221]. • TODO: Other rules inherited from Bitcoin. In addition, a full validator MUST NOT accept blocks with nTime more than two hours in the future according to its clock. This is not strictly a consensus rule because it is nondeterministic, and clock time varies between nodes. Also note that a block that is rejected by this rule at a given point in time may later be accepted. Notes: • The semantics of blocks with block version number not equal to 4 is not currently defined. Miners MUST NOT create such blocks. • The exclusion of blocks with block version number greater than 4 is not a consensus rule; such blocks may exist in the block chain and MUST be treated identically to version 4 blocks by full validators. Note that a future upgrade might use block version number either greater than or less than 4. It is likely that such an upgrade will change the block header and/or transaction format, and software that parses blocks SHOULD take this into account. • The nVersion field is a signed integer. (It was specified as unsigned in a previous version of this specification.) A future upgrade might use negative values for this field, or otherwise change its interpretation. • There is no relation between the values of the version field of a transaction, and the nVersion field of a block header . • Like other serialized fields of type compactSize uint, the solutionSize field MUST be encoded with the minimum number of bytes (3 in this case), and other encodings MUST be rejected. This is necessary to avoid a potential attack in which a miner could test several distinct encodings of each Equihash solution against the difficulty filter, rather than only the single intended encoding. • As in Bitcoin, the nTime field MUST represent a time strictly greater than the median of the timestamps of the past PoWMedianBlockSpan blocks. The Bitcoin Developer Reference [Bitcoin-Block] was previously in error on this point, but has now been corrected. • The rule limiting nTime to be no later than 90 · 60 seconds after the median-time-past is a retrospective consensus change, applied as a soft fork in zcashd v2.1.1-1. It had not been violated by any block from the given block heights in the consensus block chains of either Mainnet or Testnet . • There are no changes to the block version number or format for Overwinter. • Although the block version number does not change for Sapling, the previously reserved (and ignored) field hashReserved has been repurposed for hashFinalSaplingRoot. There are no other format changes. • There are no changes to the block version number or format for Blossom. • For Heartwood, the hashFinalSaplingRoot field is renamed to hashLightClientRoot. Once Heartwood acti- vates, the meaning of this field changes according to [ZIP-221]. 91

The changes relative to Bitcoin version 4 blocks as described in [Bitcoin-Block] are: • Block versions less than 4 are not supported. • The hashReserved (or hashFinalSaplingRoot), solutionSize, and solution fields have been added. • The type of the nNonce field has changed from uint32 to char[32]. • The maximum block size has been doubled to 2000000 bytes. 7.6 Proof of Work Zcash uses Equihash [BK2016] as its Proof of Work. The original motivations for changing the Proof of Work from SHA-256d used by Bitcoin were described in [WG2016]. A block satisfies the Proof of Work if and only if: • The solution field encodes a valid Equihash solution according to § 7.6.1 ‘Equihash’ on p. 92. • The block header satisfies the difficulty check according to § 7.6.2 ‘Difficulty filter’ on p. 93. 7.6.1 Equihash An instance of the Equihash algorithm is parameterized by positive integers 𝑛 and 𝑘, such that 𝑛 is a multiple of 𝑘 + 1. We assume 𝑘 ≥ 3. The Equihash parameters for Mainnet and Testnet are 𝑛 = 200, 𝑘 = 9. Equihash is based on a variation of the Generalized Birthday Problem [AR2017]: given a sequence 𝑋1 .. N of 𝑛-bit 𝑘 ⨁︀2 strings, find 2𝑘 distinct 𝑋𝑖𝑗 such that 𝑗=1 𝑋𝑖𝑗 = 0. 𝑛 In Equihash, N = 2 𝑘+1 +1 , and the sequence 𝑋1 .. N is derived from the block header and a nonce. Let powheader := 32-bit nVersion 256-bit hashPrevBlock 256-bit hashMerkleRoot 256-bit hashReserved 32-bit nTime 32-bit nBits 256-bit nNonce For 𝑖 ∈ {1 .. 𝑁 }, let 𝑋𝑖 = EquihashGen𝑛,𝑘 (powheader, 𝑖). EquihashGen is instantiated in § 5.4.1.9 ‘Equihash Generator’ on p. 60. Define I2BEBSP (ℓ N) × {0 .. 2ℓ −1} → B[ℓ] as in § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53. ◦ ◦ ◦ ◦ 𝑘 A valid Equihash solution is then a sequence 𝑖 {1 .. 𝑁 }2 that satisfies the following conditions: ◦ ◦ 𝑘 2 ⨁︁ Generalized Birthday condition 𝑋𝑖𝑗 = 0. 𝑗=1 Algorithm Binding conditions 𝑟 2 ⨁︁ 𝑘−𝑟 • For all 𝑟 ∈ {1 .. 𝑘−1}, for all 𝑤 ∈ {0 .. 2 −1} : 𝑋𝑖 𝑟 has 𝑛·𝑟 𝑘+1 leading zeros; and 𝑤·2 +𝑗 𝑗=1 • For all 𝑟 ∈ {1 .. 𝑘}, for all 𝑤 ∈ {0 .. 2𝑘−𝑟 −1} : 𝑖𝑤·2𝑟 +1..𝑤·2𝑟 +2𝑟−1 < 𝑖𝑤·2𝑟 +2𝑟−1 +1..𝑤·2𝑟 +2𝑟 lexicographically. Notes: • This does not include a difficulty condition, because here we are defining validity of an Equihash solution independent of difficulty. • Previous versions of this specification incorrectly specified the range of 𝑟 to be {1 .. 𝑘−1} for both parts of the algorithm binding condition. The implementation in zcashd was as intended. 92

An Equihash solution with 𝑛 = 200 and 𝑘 = 9 is encoded in the solution field of a block header as follows: I2BEBSP21 (𝑖1 − 1) I2BEBSP21 (𝑖2 − 1) ··· I2BEBSP21 (𝑖512 − 1) Recall from § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53 that bits in the above diagram are ordered from most to least significant in each byte. For example, if the first 3 elements of 𝑖 are [69, 42, 221 ], then the corresponding bit array is: I2BEBSP21 (68) I2BEBSP21 (41) I2BEBSP21 (221 − 1) 00000000000000 1000 100000000000000000 10 100 1111111111111111111111 8-bit 0 8-bit 2 8-bit 32 8-bit 0 8-bit 10 8-bit 127 8-bit 255 ··· and so the first 7 bytes of solution would be [0, 2, 32, 0, 10, 127, 255]. Note: I2BEBSP is big-endian, while integer field encodings in powheader and in the instantiation of EquihashGen are little-endian. The rationale for this is that little-endian serialization of block headers is consistent with Bitcoin, but little-endian ordering of bits in the solution encoding would require bit-reversal (as opposed to only shifting). 7.6.2 Difficulty filter Let ToTarget be as defined in § 7.6.4 ‘nBits conversion’ on p. 94. Difficulty is defined in terms of a target threshold , which is adjusted for each block according to the algorithm defined in § 7.6.3 ‘Difficulty adjustment’ on p. 93. The difficulty filter is unchanged from Bitcoin, and is calculated using SHA-256d on the whole block header (including solutionSize and solution). The result is interpreted as a 256-bit integer represented in little-endian byte order, which MUST be less than or equal to the target threshold given by ToTarget(nBits). 7.6.3 Difficulty adjustment The desired time between blocks is called the block target spacing . Zcash uses a difficulty adjustment algorithm based on DigiShield v3/v4 [DigiByte-PoW], with simplifications and altered parameters, to adjust difficulty to target the desired block target spacing . Unlike Bitcoin, the difficulty adjustment occurs after every block . The constants PoWLimit, PreBlossomHalvingInterval, PoWAveragingWindow, PoWMaxAdjustDown, PoWMaxAdjustUp, PoWDampingFactor, PreBlossomPoWTargetSpacing, and PostBlossomPoWTargetSpacing are specified in section § 5.3 ‘Constants’ on p. 53. Let ToCompact and ToTarget be as defined in § 7.6.4 ‘nBits conversion’ on p. 94. Let nTime(height) be the value of the nTime field in the header of the block at block height height. Let nBits(height) be the value of the nBits field in the header of the block at block height height. Block header fields are specified in § 7.5 ‘Block Header Encoding and Consensus’ on p. 90. Define: ∑︀length(𝑆) 𝑆𝑖 mean(𝑆) := 𝑖=1 length(𝑆) median(𝑆) := sorted(𝑆)ceiling((length(𝑆)+1)/2) bound upper lower (𝑥) := max(lower, min(upper, 𝑥))) {︃ floor(𝑥) , if 𝑥 ≥ 0 trunc(𝑥) := −floor(−𝑥) , otherwise 93

IsBlossomActivated(height N) := (height ≥ BlossomActivationHeight) ◦ ◦ PreBlossomPoWTargetSpacing BlossomPoWTargetSpacingRatio := PostBlossomPoWTargetSpacing PostBlossomHalvingInterval := floor(PreBlossomHalvingInterval · BlossomPoWTargetSpacingRatio) {︃ PreBlossomPoWTargetSpacing, if not IsBlossomActivated(height) PoWTargetSpacing(height N) := ◦ ◦ PostBlossomPoWTargetSpacing, otherwise AveragingWindowTimespan(height N) := PoWAveragingWindow · PoWTargetSpacing(height) ◦ ◦ MinActualTimespan(height N) := floor(AveragingWindowTimespan(height) · (1 − PoWMaxAdjustUp)) ◦ ◦ MaxActualTimespan(height N) := floor(AveragingWindowTimespan(height) · (1 + PoWMaxAdjustDown)) ◦ ◦ MedianTime(height N) := median([[ nTime(𝑖) for 𝑖 from max(0, height − PoWMedianBlockSpan) up to height − 1 ] ) ◦ ◦ ActualTimespan(height N) := MedianTime(height) − MedianTime(height − PoWAveragingWindow) ◦ ◦ ActualTimespanDamped(height N) := ◦ ◦ (︁ )︁ ActualTimespan(height) − AveragingWindowTimespan(height) AveragingWindowTimespan(height) + trunc PoWDampingFactor MaxActualTimespan(height) ActualTimespanBounded(height N) := ◦ ◦ bound MinActualTimespan(height) (ActualTimespanDamped(height)) ⎧ ⎨PoWLimit, ⎪ if height ≤ PoWAveragingWindow MeanTarget(height N) := mean([[ ToTarget(nBits(𝑖)) for 𝑖 from height−PoWAveragingWindow up to height−1]]), ◦ ◦ otherwise. ⎪ ⎩ The target threshold for a given block height height is then calculated as: ⎧ ⎨PoWLimit, ⎪ ⎪ (︁ )︁ if height = 0 MeanTarget(height) Threshold(height N) := min(PoWLimit, floor ◦ ◦ · ActualTimespanBounded(height)), ⎪ AveragingWindowTimespan otherwise ⎪ ⎩ ThresholdBits(height N) := ToCompact(Threshold(height)). ◦ ◦ Notes: • The convention used for the height parameters to the functions MedianTime, MeanTarget, ActualTimespan, ActualTimespanDamped, ActualTimespanBounded, Threshold, and ThresholdBits is that these functions use only information from blocks preceding the given block height . • When the median function is applied to a sequence of even length (which only happens in the definition of MedianTime during the first PoWAveragingWindow − 1 blocks of the block chain), the element that begins the second half of the sequence is taken. This corresponds to the zcashd implementation, but was not specified correctly in versions of this specification prior to 2019.0-beta-40. On Testnet from block height 299188 onward, the difficulty adjustment algorithm is changed to allow minimum- difficulty blocks, as described in [ZIP-205]. The Blossom network upgrade changes the minimum-difficulty time threshold to 6 times the block target spacing , as described in [ZIP-208]. These changes do not apply to Mainnet . 7.6.4 nBits conversion Deterministic conversions between a target threshold and a “compact" nBits value are not fully defined in the Bitcoin documentation [Bitcoin-nBits], and so we define them here: (︁ )︁ bitlength(𝑥) size(𝑥) := ceiling 8 (︁ )︁ mantissa(𝑥) := floor 𝑥 · 2563−size(𝑥) 94

24 if mantissa(𝑥) < 223 {︃ mantissa(𝑥) + 2)︁ ·size(𝑥), ToCompact(𝑥) := (︁ mantissa(𝑥) 24 floor + 2 ·(size(𝑥) + 1), otherwise 256 if 𝑥 î 223 = 223 {︃ 0, ToTarget(𝑥) := (𝑥 î (223 − 1)) · 256floor(𝑥/2 )−3 , otherwise. 24 7.6.5 Definition of Work As explained in § 3.3 ‘The Block Chain’ on p. 15, a node chooses the “best” block chain visible to it by finding the chain of valid blocks with the greatest total work. Let ToTarget be as defined in § 7.6.4 ‘nBits conversion’ on p. 94. (︂ )︂ 2256 The work of a block with value nBits for the nBits field in its block header is defined as floor . ToTarget(nBits) + 1 7.7 Calculation of Block Subsidy, Funding Streams, and Founders’ Reward § 3.9 ‘Block Subsidy, Funding Streams, and Founders’ Reward’ on p. 18 defines the block subsidy , miner sub- sidy , Founders’ Reward , and funding streams. Their amounts in zatoshi are calculated from the block height using the formulae below. Let the constants SlowStartInterval, PreBlossomHalvingInterval, PostBlossomHalvingInterval, BlossomActivationHeight, MaxBlockSubsidy, and FoundersFraction be as defined in § 5.3 ‘Constants’ on p. 53. Let FundingStreams be as specified in § 7.9.1 ‘ZIP 214 Funding Streams’ on p. 99. SlowStartInterval SlowStartShift N := ◦ ◦ 2 MaxBlockSubsidy SlowStartRate N := ◦ ◦ SlowStartInterval ⎧ 0, (︁ )︁ if height < SlowStartShift ⎪ ⎪ height − SlowStartShift ⎪ Halving(height N) := floor PreBlossomHalvingInterval , if not IsBlossomActivated(height) ⎨ ◦ ◦ ⎪ (︁ )︁ ⎩floor BlossomActivationHeight − SlowStartShift + height − BlossomActivationHeight , otherwise ⎪ ⎪ PreBlossomHalvingInterval PostBlossomHalvingInterval ⎧ ⎪ ⎪ ⎪SlowStartRate · height, if height < SlowStartShift ⎪ if SlowStartShift ≤ height ⎪ SlowStartRate · (height + 1), ⎪ ⎪ ⎪ and height < SlowStartInterval ⎪ ⎪ ⎪ ⎪ ⎨ BlockSubsidy(height N) := (︁ )︁ ◦ MaxBlockSubsidy if SlowStartInterval ≤ height ◦ floor , 2Halving(height) ⎪ and not IsBlossomActivated(height) ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ (︂ )︂ MaxBlockSubsidy , otherwise ⎪ ⎩floor ⎪ ⎪ Halving(height) BlossomPoWTargetSpacingRatio · 2 {︃ BlockSubsidy(height) · FoundersFraction, if Halving(height) < 1 FoundersReward(height N) := ◦ ◦ 0, otherwise for fs ∈ FundingStreams, fs.Value(height) := ⎧ ⎨0, (︁ )︁ if height < CanopyActivationHeight ⎪ ⎪ fs.Numerator floor BlockSubsidy(height) · , if fs.StartHeight ≤ height and height < fs.EndHeight ⎪ fs.Denominator otherwise ⎪ ⎩0, 95

∑︀ MinerSubsidy(height) := BlockSubsidy(height) − FoundersReward(height) − fs ∈ FundingStreams fs.Value(height). 7.8 Payment of Founders’ Reward The Founders’ Reward is paid by a transparent output in the coinbase transaction, to one of NumFounderAddresses transparent addresses, depending on the block height . For Mainnet , FounderAddressList1..NumFounderAddresses is: [ “t3Vz22vK5z2LcKEdg16Yv4FFneEL1zg9ojd”, “t3cL9AucCajm3HXDhb5jBnJK2vapVoXsop3”, “t3fqvkzrrNaMcamkQMwAyHRjfDdM2xQvDTR”, “t3TgZ9ZT2CTSK44AnUPi6qeNaHa2eC7pUyF”, “t3SpkcPQPfuRYHsP5vz3Pv86PgKo5m9KVmx”, “t3Xt4oQMRPagwbpQqkgAViQgtST4VoSWR6S”, “t3ayBkZ4w6kKXynwoHZFUSSgXRKtogTXNgb”, “t3adJBQuaa21u7NxbR8YMzp3km3TbSZ4MGB”, “t3K4aLYagSSBySdrfAGGeUd5H9z5Qvz88t2”, “t3RYnsc5nhEvKiva3ZPhfRSk7eyh1CrA6Rk”, “t3Ut4KUq2ZSMTPNE67pBU5LqYCi2q36KpXQ”, “t3ZnCNAvgu6CSyHm1vWtrx3aiN98dSAGpnD”, “t3fB9cB3eSYim64BS9xfwAHQUKLgQQroBDG”, “t3cwZfKNNj2vXMAHBQeewm6pXhKFdhk18kD”, “t3YcoujXfspWy7rbNUsGKxFEWZqNstGpeG4”, “t3bLvCLigc6rbNrUTS5NwkgyVrZcZumTRa4”, “t3VvHWa7r3oy67YtU4LZKGCWa2J6eGHvShi”, “t3eF9X6X2dSo7MCvTjfZEzwWrVzquxRLNeY”, “t3esCNwwmcyc8i9qQfyTbYhTqmYXZ9AwK3X”, “t3M4jN7hYE2e27yLsuQPPjuVek81WV3VbBj”, “t3gGWxdC67CYNoBbPjNvrrWLAWxPqZLxrVY”, “t3LTWeoxeWPbmdkUD3NWBquk4WkazhFBmvU”, “t3P5KKX97gXYFSaSjJPiruQEX84yF5z3Tjq”, “t3f3T3nCWsEpzmD35VK62JgQfFig74dV8C9”, “t3Rqonuzz7afkF7156ZA4vi4iimRSEn41hj”, “t3fJZ5jYsyxDtvNrWBeoMbvJaQCj4JJgbgX”, “t3Pnbg7XjP7FGPBUuz75H65aczphHgkpoJW”, “t3WeKQDxCijL5X7rwFem1MTL9ZwVJkUFhpF”, “t3Y9FNi26J7UtAUC4moaETLbMo8KS1Be6ME”, “t3aNRLLsL2y8xcjPheZZwFy3Pcv7CsTwBec”, “t3gQDEavk5VzAAHK8TrQu2BWDLxEiF1unBm”, “t3Rbykhx1TUFrgXrmBYrAJe2STxRKFL7G9r”, “t3aaW4aTdP7a8d1VTE1Bod2yhbeggHgMajR”, “t3YEiAa6uEjXwFL2v5ztU1fn3yKgzMQqNyo”, “t3g1yUUwt2PbmDvMDevTCPWUcbDatL2iQGP”, “t3dPWnep6YqGPuY1CecgbeZrY9iUwH8Yd4z”, “t3QRZXHDPh2hwU46iQs2776kRuuWfwFp4dV”, “t3enhACRxi1ZD7e8ePomVGKn7wp7N9fFJ3r”, “t3PkLgT71TnF112nSwBToXsD77yNbx2gJJY”, “t3LQtHUDoe7ZhhvddRv4vnaoNAhCr2f4oFN”, “t3fNcdBUbycvbCtsD2n9q3LuxG7jVPvFB8L”, “t3dKojUU2EMjs28nHV84TvkVEUDu1M1FaEx”, “t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME”, “t3MEXDF9Wsi63KwpPuQdD6by32Mw2bNTbEa”, “t3WDhPfik343yNmPTqtkZAoQZeqA83K7Y3f”, “t3PSn5TbMMAEw7Eu36DYctFezRzpX1hzf3M”, “t3R3Y5vnBLrEn8L6wFjPjBLnxSUQsKnmFpv”, “t3Pcm737EsVkGTbhsu2NekKtJeG92mvYyoN” ] 96

For Testnet , FounderAddressList1..NumFounderAddresses is: [ “t2UNzUUx8mWBCRYPRezvA363EYXyEpHokyi”, “t2N9PH9Wk9xjqYg9iin1Ua3aekJqfAtE543”, “t2NGQjYMQhFndDHguvUw4wZdNdsssA6K7x2”, “t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy”, “t2BkYdVCHzvTJJUTx4yZB8qeegD8QsPx8bo”, “t2J8q1xH1EuigJ52MfExyyjYtN3VgvshKDf”, “t2Crq9mydTm37kZokC68HzT6yez3t2FBnFj”, “t2EaMPUiQ1kthqcP5UEkF42CAFKJqXCkXC9”, “t2F9dtQc63JDDyrhnfpzvVYTJcr57MkqA12”, “t2LPirmnfYSZc481GgZBa6xUGcoovfytBnC”, “t26xfxoSw2UV9Pe5o3C8V4YybQD4SESfxtp”, “t2D3k4fNdErd66YxtvXEdft9xuLoKD7CcVo”, “t2DWYBkxKNivdmsMiivNJzutaQGqmoRjRnL”, “t2C3kFF9iQRxfc4B9zgbWo4dQLLqzqjpuGQ”, “t2MnT5tzu9HSKcppRyUNwoTp8MUueuSGNaB”, “t2AREsWdoW1F8EQYsScsjkgqobmgrkKeUkK”, “t2Vf4wKcJ3ZFtLj4jezUUKkwYR92BLHn5UT”, “t2K3fdViH6R5tRuXLphKyoYXyZhyWGghDNY”, “t2VEn3KiKyHSGyzd3nDw6ESWtaCQHwuv9WC”, “t2F8XouqdNMq6zzEvxQXHV1TjwZRHwRg8gC”, “t2BS7Mrbaef3fA4xrmkvDisFVXVrRBnZ6Qj”, “t2FuSwoLCdBVPwdZuYoHrEzxAb9qy4qjbnL”, “t2SX3U8NtrT6gz5Db1AtQCSGjrpptr8JC6h”, “t2V51gZNSoJ5kRL74bf9YTtbZuv8Fcqx2FH”, “t2FyTsLjjdm4jeVwir4xzj7FAkUidbr1b4R”, “t2EYbGLekmpqHyn8UBF6kqpahrYm7D6N1Le”, “t2NQTrStZHtJECNFT3dUBLYA9AErxPCmkka”, “t2GSWZZJzoesYxfPTWXkFn5UaxjiYxGBU2a”, “t2RpffkzyLRevGM3w9aWdqMX6bd8uuAK3vn”, “t2JzjoQqnuXtTGSN7k7yk5keURBGvYofh1d”, “t2AEefc72ieTnsXKmgK2bZNckiwvZe3oPNL”, “t2NNs3ZGZFsNj2wvmVd8BSwSfvETgiLrD8J”, “t2ECCQPVcxUCSSQopdNquguEPE14HsVfcUn”, “t2JabDUkG8TaqVKYfqDJ3rqkVdHKp6hwXvG”, “t2FGzW5Zdc8Cy98ZKmRygsVGi6oKcmYir9n”, “t2DUD8a21FtEFn42oVLp5NGbogY13uyjy9t”, “t2UjVSd3zheHPgAkuX8WQW2CiC9xHQ8EvWp”, “t2TBUAhELyHUn8i6SXYsXz5Lmy7kDzA1uT5”, “t2Tz3uCyhP6eizUWDc3bGH7XUC9GQsEyQNc”, “t2NysJSZtLwMLWEJ6MH3BsxRh6h27mNcsSy”, “t2KXJVVyyrjVxxSeazbY9ksGyft4qsXUNm9”, “t2J9YYtH31cveiLZzjaE4AcuwVho6qjTNzp”, “t2QgvW4sP9zaGpPMH1GRzy7cpydmuRfB4AZ”, “t2NDTJP9MosKpyFPHJmfjc5pGCvAU58XGa4”, “t29pHDBWq7qN4EjwSEHg8wEqYe9pkmVrtRP”, “t2Ez9KM8VJLuArcxuEkNRAkhNvidKkzXcjJ”, “t2D5y7J5fpXajLbGrMBQkFg2mFN8fo3n8cX”, “t2UV2wr1PTaUiybpkV3FdSdGxUJeZdZztyt” ] Note: For Testnet only, the addresses from index 4 onward have been changed from what was implemented at launch. This reflects an upgrade on Testnet , starting from block height 53127. [Zcash-Issue2113] Each address representation in FounderAddressList denotes a transparent P2SH multisig address. Let SlowStartShift and Halving be defined as in the previous section. Define: (︁ )︁ SlowStartShift + PreBlossomHalvingInterval FounderAddressChangeInterval := ceiling NumFounderAddresses FounderAddressAdjustedHeight(height N) := ◦ ◦ )︁ if not IsBlossomActivated(height), {︃ height, (︁ height − BlossomActivationHeight BlossomActivationHeight + floor , otherwise BlossomPoWTargetSpacingRatio (︁ )︁ FounderAddressAdjustedHeight(height) FounderAddressIndex(height N) := 1 + floor ◦ ◦ FounderAddressChangeInterval FoundersRewardLastBlockHeight := max({height N | Halving(height) < 1}). ◦ ◦ Let FounderRedeemScriptHash(height N) be the standard redeem script hash, as specified in [Bitcoin-Multisig], for ◦ ◦ the P2SH multisig address with Base58Check form given by FounderAddressList FounderAddressIndex(height) . Consensus rule: [Pre-Canopy ] A coinbase transaction at height ∈ {1 .. FoundersRewardLastBlockHeight} MUST include at least one output that pays exactly FoundersReward(height) zatoshi with a standard P2SH script of the form OP_HASH160 FounderRedeemScriptHash(height) OP_EQUAL as its scriptPubKey. 97

Notes: • No Founders’ Reward is required to be paid for height > FoundersRewardLastBlockHeight (i.e. after the first halving ), or for height = 0 (i.e. the genesis block ), or after Canopy activation. • The Founders’ Reward addresses are not treated specially in any other way, and there can be other outputs to them, in coinbase transactions or otherwise. In particular, it is valid for a coinbase transaction with height ∈ {1 .. FoundersRewardLastBlockHeight} to have other outputs, possibly to the same address, that do not meet the criterion in the above consensus rule, as long as at least one output meets it. • The assertion FounderAddressIndex(FoundersRewardLastBlockHeight) ≤ NumFounderAddresses holds, ensuring that the Founders’ Reward address index remains in range for the whole period in which the Founders’ Reward is paid. Non-normative notes: • [Blossom onward] FoundersRewardLastBlockHeight = 1046399. • Blossom is not intended to change the total Founders’ Reward or the effective period over which it is paid. 7.9 Payment of Funding Streams The funding streams are paid by outputs in the coinbase transaction, to one of a pre-defined set of addresses, depending on the block height . A funding stream fs is defined by a block subsidy fraction (represented as a numerator and denominator), a start block height (inclusive), an end block height (exclusive), and a sequence of address representations: fs.Numerator N+◦ ◦ fs.Denominator N+ ◦ ◦ fs.StartHeight N ◦ ◦ fs.EndHeight N ◦ ◦ + fs.AddressList BY[N][N ] . ◦ ◦ Define: HeightForHalving(halving N+ ) := min({height N | Halving(height) = halving}) ◦ ◦ ◦ ◦ FundingStreamAddressChangeInterval := PostBlossomHalvingInterval/48 (︁ )︁ height − (HeightForHalving(1) − PostBlossomHalvingInterval) FundingStreamAddressPeriod(height) := floor . FundingStreamAddressChangeInterval For each funding stream fs, define: fs.AddressIndex(height) := 1 + FundingStreamAddressPeriod(height) − FundingStreamAddressPeriod(fs.StartHeight) fs.NumAddresses := fs.AddressIndex(fs.EndHeight − 1). fs.AddressList MUST be of length fs.NumAddresses. Each element of fs.AddressList MUST represent either a transpar- ent P2SH address as specified in § 5.6.1 ‘Transparent Addresses’ on p. 78, or a Sapling shielded payment address as specified in § 5.6.4 ‘Sapling Payment Addresses’ on p. 80. Recall from § 7.7 ‘Calculation of Block Subsidy, Funding Streams, and Founders’ Reward’ on p. 95 the defini- tion of fs.Value. A funding stream fs is “active” at block height height when fs.Value(height) > 0. 98

Consensus rule: [Canopy onward] The coinbase transaction at block height height MUST contain at least one output per funding stream fs active at height, that pays fs.Value(height) zatoshi in the prescribed way to the stream’s recipient address represented by fs.AddressListfs.AddressIndex(height) . • The “prescribed way” to pay a transparent P2SH address is to use a standard P2SH script of the form OP_HASH160 fs.RedeemScriptHash(height) OP_EQUAL as the scriptPubKey. Here fs.RedeemScriptHash(height) is the standard redeem script hash for the recipient address given by fs.AddressList fs.AddressIndex(height) in Base58Check form. The standard redeem script hash is specified in [Bitcoin-Multisig] for P2SH multisig addresses, or [Bitcoin-P2SH] for other P2SH addresses. • The “prescribed way" to pay a Sapling address is as defined in [ZIP-213], using the post-Heartwood consensus rules specified for Sapling outputs of coinbase transactions in § 7.1 ‘Transaction Encoding and Consensus’ on p. 85. Notes: • The funding stream addresses are not treated specially in any other way, and there can be other outputs to them, in coinbase transactions or otherwise. In particular, it is valid for a coinbase transaction to have other outputs, possibly to the same address, that do not meet the criterion in the above consensus rule, as long as at least one output meets it. 7.9.1 ZIP 214 Funding Streams Let CanopyActivationHeight be as defined in § 5.3 ‘Constants’ on p. 53. [ZIP-214] defines these funding streams for Mainnet : Stream Numerator Denominator Start height End height FS_ZIP214_ECC 7 100 1046400 2726400 FS_ZIP214_ZF 5 100 1046400 2726400 FS_ZIP214_MG 8 100 1046400 2726400 It also defines these funding streams for Testnet : Stream Numerator Denominator Start height End height FS_ZIP214_ECC 7 100 1028500 2796000 FS_ZIP214_ZF 5 100 1028500 2796000 FS_ZIP214_MG 8 100 1028500 2796000 Notes: • The block heights of halvings are different between Testnet and Mainnet , as a result of different activation block heights for the Blossom network upgrade (which changed the block target spacing ). The end height of these funding streams corresponds to the second halving on each network. • On Testnet , the activation block height of Canopy is before the first halving . Therefore, the consequence of the above rules for Testnet is that the amount sent to each Zcash Development Fund recipient address will initially (before Testnet block height 1116000) be double the number of currency units as the corresponding initial amount on Mainnet . This reduces to the same number of currency units as on Mainnet , from Testnet block heights 1116000 (inclusive) to 2796000 (exclusive). 7.10 Changes to the Script System The OP_CODESEPARATOR opcode has been disabled. This opcode also no longer affects the calculation of SIGHASH transaction hashes. 99

7.11 Bitcoin Improvement Proposals In general, Bitcoin Improvement Proposals (BIPs) do not apply to Zcash unless otherwise specified in this section. All of the BIPs referenced below should be interpreted by replacing “BTC”, or “bitcoin” used as a currency unit, with “ZEC”; and “satoshi” with “zatoshi”. The following BIPs apply, otherwise unchanged, to Zcash: [BIP-11], [BIP-14], [BIP-31], [BIP-35], [BIP-37], [BIP-61]. The following BIPs apply starting from the Zcash genesis block , i.e. any activation rules or exceptions for particular blocks in the Bitcoin block chain are to be ignored: [BIP-16], [BIP-30], [BIP-65], [BIP-66]. The effect of [BIP-34] has been incorporated into the consensus rules (§ 7.1 ‘Transaction Encoding and Consensus’ on p. 85). This excludes the Mainnet and Testnet genesis blocks, for which the “height in coinbase” was inadvertently omitted. [BIP-13] applies with the changes to address version bytes described in § 5.6.1 ‘Transparent Addresses’ on p. 78. [BIP-111] applies from network protocol version 170004 onward; that is: • references to protocol version 70002 are to be replaced by 170003; • references to protocol version 70011 are to be replaced by 170004; • the reference to protocol version 70000 is to be ignored (Zcash nodes have supported Bloom-filtered connec- tions since launch). 8 Differences from the Zerocash paper 8.1 Transaction Structure Zerocash introduces two new operations, which are described in the paper as new transaction types, in addition to the original transaction type of the cryptocurrency on which it is based (e.g. Bitcoin). In Zcash, there is only the original Bitcoin transaction type, which is extended to contain a sequence of zero or more Zcash-specific operations. This allows for the possibility of chaining transfers of shielded value in a single Zcash transaction, e.g. to spend a shielded note that has just been created. (In Zcash, we refer to value stored in UTXOs as transparent , and value stored in output notes of JoinSplit transfers or Output transfers) as shielded .) This was not possible in the Zerocash design without using multiple transactions. It also allows transparent and shielded transfers to happen atomically — possibly under the control of nontrivial script conditions, at some cost in distinguishability. Computation of SIGHASH transaction hashes, as described in § 4.9 ‘SIGHASH Transaction Hashing’ on p. 37, was changed to clean up handling of an error case for SIGHASH_SINGLE, to remove the special treatment of OP_CODESEPARATOR, and to include Zcash-specific fields in the hash [ZIP-76]. 8.2 Memo Fields Zcash adds a memo field sent from the creator of a JoinSplit description to the recipient of each output note. This feature is described in more detail in § 5.5 ‘Encodings of Note Plaintexts and Memo Fields’ on p. 77. 8.3 Unification of Mints and Pours In the original Zerocash protocol, there were two kinds of transaction relating to shielded notes: • a “Mint” transaction takes value from transparent UTXOs as input and produces a new shielded note as output. 100

• a “Pour” transaction takes up to Nold shielded notes as input, and produces up to Nnew shielded notes and a transparent UTXO as output. Only “Pour” transactions included a zk-SNARK proof. [Pre-Sapling] In Zcash, the sequence of operations added to a transaction (see § 8.1 ‘Transaction Structure’ on p. 100) consists only of JoinSplit transfers. A JoinSplit transfer is a Pour operation generalized to take a transparent UTXO as input, allowing JoinSplit transfers to subsume the functionality of Mints. An advantage of this is that a Zcash transaction that takes input from an UTXO can produce up to Nnew output notes, improving the indistinguishability properties of the protocol. A related change conceals the input arity of the JoinSplit transfer : an unused (zero-value) input is indistinguishable from an input that takes value from a note. This unification also simplifies the fix to the Faerie Gold attack described below, since no special case is needed for Mints. [Sapling onward] In Sapling, there are still no “Mint” transactions. Instead of JoinSplit transfers, there are Spend transfers and Output transfers. These make use of Pedersen value commitments to represent the shielded values that are transferred. Because these commitments are additively homomorphic, it is possible to check that all Spend transfers and Output transfers balance; see § 4.12 ‘Balance and Binding Signature (Sapling)’ on p. 39 for detail. This reduces the granularity of the circuit, allowing a substantial performance improvement (orthogonal to other Sapling circuit improvements) when the numbers of shielded inputs and outputs are significantly different. This comes at the cost of revealing the exact number of shielded inputs and outputs, but dummy (zero-valued) outputs are still possible. 8.4 Faerie Gold attack and fix When a shielded note is created in Zerocash, the creator is supposed to choose a new ρ value at random. The nullifier of the note is derived from its spending key (ask ) and ρ. The note commitment is derived from the recipient address component apk , the value v, and the commitment trapdoor rcm, as well as ρ. However nothing prevents creating multiple notes with different v and rcm (hence different note commitments) but the same ρ. An adversary can use this to mislead a note recipient, by sending two notes both of which are verified as valid by Receive (as defined in [BCGGMTV2014, Figure 2]), but only one of which can be spent. We call this a “Faerie Gold” attack — referring to various Celtic legends in which faeries pay mortals in what appears to be gold, but which soon after reveals itself to be leaves, gorse blossoms, gingerbread cakes, or other less valuable things [LG2004]. This attack does not violate the security definitions given in [BCGGMTV2014]. The issue could be framed as a problem either with the definition of Completeness, or the definition of Balance: • The Completeness property asserts that a validly received note can be spent provided that its nullifier does not appear on the ledger. This does not take into account the possibility that distinct notes, which are validly received, could have the same nullifier . That is, the security definition depends on a protocol detail –nullifiers– that is not part of the intended abstract security property, and that could be implemented incorrectly. • The Balance property only asserts that an adversary cannot obtain more funds than they have minted or received via payments. It does not prevent an adversary from causing others’ funds to decrease. In a Faerie Gold attack, an adversary can cause spending of a note to reduce (to zero) the effective value of another note for which the adversary does not know the spending key , which violates an intuitive conception of global balance. These problems with the security definitions need to be repaired, but doing so is outside the scope of this specifi- cation. Here we only describe how Zcash addresses the immediate attack. It would be possible to address the attack by requiring that a recipient remember all of the ρ values for all notes they have ever received, and reject duplicates (as proposed in [GGM2016]). However, this requirement would interfere with the intended Zcash feature that a holder of a spending key can recover access to (and be sure that they are able to spend) all of their funds, even if they have forgotten everything but the spending key . 101

[Sprout] Instead, Zcash enforces that an adversary must choose distinct values for each ρ, by making use of the fact that all of the nullifiers in JoinSplit descriptions that appear in a valid block chain must be distinct. This is true regardless of whether the nullifiers corresponded to real or dummy notes (see § 4.7.1 ‘Dummy Notes (Sprout)’ on p. 35). The nullifiers are used as input to hSigCRH to derive a public value hSig which uniquely identifies the transaction, as described in § 4.3 ‘JoinSplit Descriptions’ on p. 31. (hSig was already used in Zerocash in a way that requires it to be unique in order to maintain indistinguishability of JoinSplit descriptions; adding the nullifiers to the input of the hash used to calculate it has the effect of making this uniqueness property robust even if the transaction creator is an adversary.) [Sprout] The ρ value for each output note is then derived from a random private seed ϕ and hSig using PRFρϕ . The correct construction of ρ for each output note is enforced by § 4.15.1 ‘JoinSplit Statement (Sprout)’ on p. 43 in the JoinSplit statement . [Sprout] Now even if the creator of a JoinSplit description does not choose ϕ randomly, uniqueness of nullifiers and collision resistance of both hSigCRH and PRFρ will ensure that the derived ρ values are unique, at least for any two JoinSplit descriptions that get into a valid block chain. This is sufficient to prevent the Faerie Gold attack. A variation on the attack attempts to cause the nullifier of a sent note to be repeated, without repeating ρ. However, since the nullifier is computed as PRFnf nfSapling ask (ρ) (or PRFnk (ρ⋆) for Sapling), this is only possible if the adver- sary finds a collision across both inputs on PRFnf (or PRFnfSapling ), which is assumed to be infeasible — see § 4.1.2 ‘Pseudo Random Functions’ on p. 20. [Sprout] Crucially, “nullifier integrity” is enforced whether or not the enforceMerklePath𝑖 flag is set for an input note (§ 4.15.1 ‘JoinSplit Statement (Sprout)’ on p. 43). If this were not the case then an adversary could perform the attack by creating a zero-valued note with a repeated nullifier , since the nullifier would not depend on the value. [Sprout] Nullifier integrity also prevents a “roadblock attack” in which the adversary sees a victim’s transaction, and is able to publish another transaction that is mined first and blocks the victim’s transaction. This attack would be possible if the public value(s) used to enforce uniqueness of ρ could be chosen arbitrarily by the transaction creator: the victim’s transaction, rather than the adversary’s, would be considered to be repeating these values. In the chosen solution that uses nullifiers for these public values, they are enforced to be dependent on spending keys controlled by the original transaction creator (whether or not each input note is a dummy ), and so a roadblock attack cannot be performed by another party who does not know these keys. [Sapling onward] In Sapling, uniqueness of ρ is ensured by making it dependent on the position of the note commitment in the Sapling note commitment tree. Specifically, ρ = cm + [pos] 𝒥 , where 𝒥 is a generator inde- pendent of the generators used in NoteCommitSapling . Therefore, ρ commits uniquely to the note and its position, and this commitment is collision-resistant by the same argument used to prove collision resistance of Pedersen hashes. Note that it is possible for two distinct Sapling positioned notes (having different ρ values and nullifiers, but different note positions) to have the same note commitment , but this causes no security problem. Roadblock attacks are not possible because a given note position does not repeat for outputs of different transactions in the same block chain. 8.5 Internal hash collision attack and fix The Zerocash security proof requires that the composition of COMMrcm and COMMs is a computationally binding commitment to its inputs apk , v, and ρ. However, the instantiation of COMMrcm and COMMs in section 5.1 of the paper did not meet the definition of a binding commitment at a 128-bit security level. Specifically, the internal hash of apk and ρ is truncated to 128 bits (motivated by providing statistical hiding security). This allows an attacker, with a work factor on the order of 264 , to find distinct pairs (apk , ρ) and (apk′ , ρ′ ) with colliding outputs of the truncated hash, and therefore the same note commitment . This would have allowed such an attacker to break the Balance property by double-spending notes, potentially creating arbitrary amounts of currency for themself [HW2016]. Zcash uses a simpler construction with a single hash evaluation for the commitment: SHA-256 for Sprout, and PedersenHash for Sapling. The motivation for the nested construction in Zerocash was to allow Mint transactions to be publically verified without requiring a zk-SNARK proof ([BCGGMTV2014, section 1.3, under step 3]). Since Zcash combines “Mint” and “Pour” transactions into generalized JoinSplit transfers (for Sprout), or Spend transfers 102

and Output transfers (for Sapling), and each transfer always uses a zk-SNARK proof , Zcash does not require the nesting. A side benefit is that this reduces the cost of computing the note commitments: for Sprout it reduces the number of SHA256Compress evaluations needed to compute each note commitment from three to two, saving a total of four SHA256Compress evaluations in the JoinSplit statement . [Sprout] Note: Sprout note commitments are not statistically hiding, so for Sprout notes, Zcash does not support the “everlasting anonymity” property described in [BCGGMTV2014, section 8.1], even when used as described in that section. While it is possible to define a statistically hiding, computationally binding commitment scheme for this use at a 128-bit security level, the overhead of doing so within the JoinSplit statement was not considered to justify the benefits. [Sapling onward] In Sapling, Pedersen commitments are used instead of SHA256Compress. These commitments are statistically hiding, and so “everlasting anonymity” is supported for Sapling notes under the same conditions as in Zerocash (by the protocol, not necessarily by zcashd). Note that diversified payment addresses can be linked if the Discrete Logarithm Problem on the Jubjub curve can be broken. 8.6 Changes to PRF inputs and truncation The format of inputs to the PRFs instantiated in § 5.4.2 ‘Pseudo Random Functions’ on p. 61 has changed relative to Zerocash. There is also a requirement for another PRF , PRFρ , which must be domain-separated from the others. In the Zerocash protocol, ρold sn 𝑖 is truncated from 256 to 254 bits in the input to PRF (which corresponds to PRF nf pk in Zcash). Also, hSig is truncated from 256 to 253 bits in the input to PRF . These truncations are not taken into account in the security proofs. Both truncations affect the validity of the proof sketch for Lemma D.2 in the proof of Ledger Indistinguishability in [BCGGMTV2014, Appendix D]. In more detail: • In the argument relating H and a2 , it is stated that in a2 , “for each 𝑖 ∈ {1, 2}, sn𝑖 := PRFsn ask (ρ) for a random (and not previously used) ρ”. It is also argued that “the calls to PRFsn ask are each by definition unique”. The latter assertion depends on the fact that ρ is “not previously used”. However, the argument is incorrect because the truncated input to PRFsn ask , i.e. [ρ]254 , may repeat even if ρ does not. • In the same argument, it is stated that “with overwhelming probability, hSig is unique”. In fact what is required to be unique is the truncated input to PRFpk , i.e. [hSig ]253 = [CRH(pksig )]253 . In practice this value will be unique under a plausible assumption on CRH provided that pksig is chosen randomly, but no formal argument for this is presented. Note that ρ is truncated in the input to PRFsn but not in the input to COMMrcm , which further complicates the analysis. As further evidence that it is essential for the proofs to explicitly take any such truncations into account, consider a slightly modified protocol in which ρ is truncated in the input to COMMrcm but not in the input to PRFsn . In that case, it would be possible to violate balance by creating two notes for which ρ differs only in the truncated bits. These notes would have the same note commitment but different nullifiers, so it would be possible to spend the same value twice. [Sprout] For resistance to Faerie Gold attacks as described in § 8.4 ‘Faerie Gold attack and fix’ on p. 101, Zcash depends on collision resistance of hSigCRH and PRFρ (instantiated using BLAKE2b-256 and SHA256Compress re- spectively). Collision resistance of a truncated hash does not follow from collision resistance of the original hash, even if the truncation is only by one bit. This motivated avoiding truncation along any path from the inputs to the computation of hSig to the uses of ρ. [Sprout] Since the PRFs are instantiated using SHA256Compress which has an input block size of 512 bits (of which 256 bits are used for the PRF input and 4 bits are used for domain separation), it was necessary to reduce the size of 103

the PRF key to 252 bits. The key is set to ask in the case of PRFaddr , PRFnf , and PRFpk , and to ϕ (which does not exist in Zerocash) for PRFρ , and so those values have been reduced to 252 bits. This is preferable to requiring reasoning about truncation, and 252 bits is quite sufficient for security of these cryptovalues. Sapling uses Pedersen hashes and BLAKE2s where Sprout used SHA256Compress. Pedersen hashes can be efficiently instantiated for arbitrary input lengths. BLAKE2s has an input block size of 512 bits, and uses a finalization flag rather than padding of the last input block; it also supports domain separation via a personalization parameter distinct from the input. Therefore, there is no need for truncation in the inputs to any of these hashes. Note however that the output of CRHivk is truncated, requiring a security assumption on BLAKE2s truncated to 251 bits (see § 5.4.1.5 ‘CRHivk Hash Function’ on p. 57). 8.7 In-band secret distribution Zerocash specified ECIES (referencing Certicom’s SEC 1 standard) as the encryption scheme used for the in-band secret distribution. This has been changed to a key agreement scheme based on Curve25519 (for Sprout) or Jubjub (for Sapling) and the authenticated encryption algorithm AEAD_CHACHA20_POLY1305. This scheme is still loosely based on ECIES, and on the crypto_box_seal scheme defined in libsodium [libsodium-Seal]. The motivations for this change were as follows: • The Zerocash paper did not specify the curve to be used. We believe that Curve25519 has significant side- channel resistance, performance, implementation complexity, and robustness advantages over most other available curve choices, as explained in [Bernstein2006]. For Sapling, the Jubjub curve was designed according to a similar design process following the “Safe curves” criteria [BL-SafeCurves] [Hopwood2018]. This retains Curve25519’s advantages while keeping shielded payment address sizes short, because the same public key material supports both encryption and spend authentication. • ECIES permits many options, which were not specified. There are at least –counting conservatively– 576 possible combinations of options and algorithms over the four standards (ANSI X9.63, IEEE Std 1363a-2004, ISO/IEC 18033-2, and SEC 1) that define ECIES variants [MAEÁ2010]. • Although the Zerocash paper states that ECIES satisfies key privacy (as defined in [BBDP2001]), it is not clear that this holds for all curve parameters and key distributions. For example, if a group of non-prime order is used, the distribution of ciphertexts could be distinguishable depending on the order of the points representing the ephemeral and recipient public keys. Public key validity is also a concern. Curve25519 (and Jubjub) key agreement is defined in a way that avoids these concerns due to the curve structure and the “clamping” of private keys (or explicit cofactor multiplication and point validation for Sapling). • Unlike the DHAES/DHIES proposal on which it is based [ABR1999], ECIES does not require a representation of the sender’s ephemeral public key to be included in the input to the KDF, which may impair the security properties of the scheme. (The Std 1363a-2004 version of ECIES [IEEE2004] has a “DHAES mode” that allows this, but the representation of the key input is underspecified, leading to incompatible implementations.) The scheme we use for Sprout has both the ephemeral and recipient public key encodings –which are unambiguous for Curve25519– and also hSig and a nonce as described below, as input to the KDF. For Sapling, it is only possible to include the ephemeral public key encoding, but this is sufficient to retain the original security properties of DHAES. Note that being able to break the Elliptic Curve Diffie-Hellman Problem on Curve25519 or Jubjub (without breaking AEAD_CHACHA20_POLY1305 as an authenticated encryption scheme or BLAKE2b-256 as a KDF) would not help to decrypt the transmitted note(s) ciphertext unless pkenc is known or guessed. • [Sprout] The KDF also takes a public seed hSig as input. This can be modeled as using a different “randomness extractor” for each JoinSplit transfer , which limits degradation of security with the number of JoinSplit transfers. This facilitates security analysis as explained in [DGKM2011] — see section 7 of that paper for a security proof that can be applied to this construction under the assumption that single-block BLAKE2b-256 is a “weak PRF ”. Note that hSig is authenticated, by the zk-SNARK proof , as having been chosen with knowledge of aold sk,1..N old , so an adversary cannot modify it in a ciphertext from someone else’s transaction for use in a chosen-ciphertext attack without detection. (In Sapling, there is no equivalent to hSig , but the binding signature and spend authorization signatures prevent such modifications.) 104

• [Sprout] The scheme used by Sprout includes an optimization that reuses the same ephemeral key (with different nonces) for the two ciphertexts encrypted in each JoinSplit description. The security proofs of [ABR1999] can be adapted straightforwardly to the resulting scheme. Although DHAES as defined in that paper does not pass the recipient public key or a public seed to the hash function 𝐻, this does not impair the proof because we can consider 𝐻 to be the specialization of our KDF to a given recipient key and seed. (Passing the recipient public key to the KDF could in principle compromise key privacy , but not confidentiality of encryption.) [Sprout] It is necessary to adapt the “HDH independence” assumptions and the proof slightly to take into account that the ephemeral key is reused for two encryptions. Note that the 256-bit key for AEAD_CHACHA20_POLY1305 maintains a high concrete security level even under attacks using parallel hardware [Bernstein2005] in the multi-user setting [Zaverucha2012]. This is especially neces- sary because the privacy of Zcash transactions may need to be maintained far into the future, and upgrading the encryption algorithm would not prevent a future adversary from attempting to decrypt ciphertexts encrypted before the upgrade. Other cryptovalues that could be attacked to break the privacy of transactions are also sufficiently long to resist parallel brute force in the multi-user setting: for Sprout, ask is 252 bits, and skenc is no shorter than ask . 8.8 Omission in Zerocash security proof The abstract Zerocash protocol requires PRFaddr only to be a PRF ; it is not specified to be collision-resistant . This reveals a flaw in the proof of the Balance property. Suppose that an adversary finds a collision on PRFaddr such that a1sk and a2sk are distinct spending keys for the same apk . Because the note commitment is to apk , but the nullifier is computed from ask (and ρ), the adversary is able to double-spend the note, once with each ask . This is not detected because each Spend reveals a different nullifier . The JoinSplit statements are still valid because they can only check that the ask in the witness is some preimage of the apk used in the note commitment . The error is in the proof of Balance in [BCGGMTV2014, Appendix D.3]. For the “𝒜 violates Condition I” case, the proof says: “(i) If cmold old old old 1 = cm2 , then the fact that sn1 ̸= sn2 implies that the witness 𝑎 contains two distinct openings of cm1 (the first opening contains (ask,1 , ρ1 ), while the second opening contains (aold old old old old sk,2 , ρ2 )). This violates the binding property of the commitment scheme COMM." In fact the openings do not contain aold old old old old old sk,𝑖 ; they contain apk,𝑖 . (In Sprout cm𝑖 opens directly to (apk,𝑖 , v𝑖 , ρ𝑖 ), and in Zerocash it opens to (v𝑖old , COMMs (aold old pk,𝑖 , ρ𝑖 ).) A similar error occurs in the argument for the “𝒜 violates Condition II” case. The flaw is not exploitable for the actual instantiations of PRFaddr in Zerocash and Sprout, which are collision- resistant assuming that SHA256Compress is. The proof can be straightforwardly repaired. The intuition is that we can rely on collision resistance of PRFaddr (on both its arguments) to argue that distinctness of aold old sk,1 and ask,2 , together with constraint 1(b) of the JoinSplit statement (see § 4.15.1 ‘JoinSplit Statement (Sprout)’ on p. 43), implies distinctness of aold old pk,1 and apk,2 , therefore distinct openings of the note commitment when Condition I or II is violated. 8.9 Miscellaneous • The paper defines a note as ((apk , pkenc ), v, ρ, rcm, s, cm), whereas this specification defines a Sprout note as (apk , v, ρ, rcm). The instantiation of COMMs in section 5.1 of the paper did not actually use s, and neither does the new instantiation of NoteCommitSprout in Sprout. pkenc is also not needed as part of a note: it is not an input to NoteCommitSprout nor is it constrained by the Zerocash POUR statement or the Zcash JoinSplit statement . cm can be computed from the other fields. (The definition of notes for Sapling is different again.) 105

• The length of proof encodings given in the paper is 288 bytes. [Sprout] This differs from the 296 bytes specified in § 5.4.9.1 ‘BCTV14’ on p. 75, because both the 𝑥-coordinate and compressed 𝑦-coordinate of each point need to be represented. Although it is possible to encode a proof in 288 bytes by making use of the fact that elements of F𝑞 can be represented in 254 bits, we prefer to use the standard formats for points defined in [IEEE2004]. The fork of libsnark used by Zcash uses this standard encoding rather than the less efficient (uncompressed) one used by upstream libsnark . In Sapling, a customized encoding is used for BLS12-381 points in Groth16 proofs to minimize length. • The range of monetary values differs. In Zcash this range is {0 .. MAX_MONEY}, while in Zerocash it is {0 .. 2ℓvalue −1}. (The JoinSplit statement still only directly enforces that the sum of amounts in a given JoinSplit transfer is in the latter range; this enforcement is technically redundant given that the Balance property holds.) 9 Acknowledgements The inventors of Zerocash are Eli Ben-Sasson, Alessandro Chiesa, Christina Garman, Matthew Green, Ian Miers, Eran Tromer, and Madars Virza. The designers of the Zcash protocol are the Zerocash inventors and also Daira Hopwood, Sean Bowe, Jack Grigg, Simon Liu, Taylor Hornby, Nathan Wilcox, Zooko Wilcox, Jay Graber, Ariel Gabizon, George Tankersley, Ying Tong Lai, Kris Nuttycombe, and Jack Gavigan. The Equihash proof-of-work algorithm was designed by Alex Biryukov and Dmitry Khovratovich. The authors would like to thank everyone with whom they have discussed the Zerocash and Zcash protocol designs; in addition to the preceding, this includes Mike Perry, isis agora lovecruft, Leif Ryge, Andrew Miller, Ben Blaxill, Samantha Hulsey, Alex Balducci, Jake Tarren, Solar Designer, Ling Ren, John Tromp, Paige Peterson, jl777, Alison Stevenson, Maureen Walsh, Filippo Valsorda, Zaki Manian, Tracy Hu, Brian Warner, Mary Maller, Michael Dixon, Andrew Poelstra, Eirik Ogilvie-Wigley, Benjamin Winston, Kobi Gurkan, Weikeng Chen, Henry de Valence, Deirdre Connolly, Chelsea Komlo, Zancas Wilcox, Jane Lusby, Teor, Izaak Meckler, Zac Williamson, Vitalik Buterin, Jakub Zalewski. and no doubt others. We would also like to thank the designers and developers of Bitcoin. Zcash has benefited from security audits performed by NCC Group, Coinspect, Least Authority, Mary Maller, Kudelski Security, QEDIT, and Trail of Bits. The Faerie Gold attack was found by Zooko Wilcox; subsequent analysis of variations on the attack was performed by Daira Hopwood and Sean Bowe. The internal hash collision attack was found by Taylor Hornby. The error in the Zerocash proof of Balance relating to collision resistance of PRFaddr was found by Daira Hopwood. The errors in the proof of Ledger Indistinguishability mentioned in § 8.6 ‘Changes to PRF inputs and truncation’ on p. 103 were also found by Daira Hopwood. The 2015 Soundness vulnerability in BCTV14 [Parno2015] was found by Bryan Parno. An additional condition needed to resist this attack was documented by Ariel Gabizon [Gabizon2019, section 3]. The 2019 Soundness vulnerability in BCTV14 [Gabizon2019] was found by Ariel Gabizon. The design of Sapling is primarily due to Matthew Green, Ian Miers, Daira Hopwood, Sean Bowe, Jack Grigg, and Jack Gavigan. A potential attack linking diversified payment addresses, avoided in the adopted design, was found by Brian Warner. The observation in § 5.4.1.6 ‘DiversifyHash Hash Function’ on p. 57 that diversified payment address unlinkability can be proven in the same way as key privacy for ElGamal, is due to Mary Maller. We thank Ariel Gabizon for teaching us the techniques of [BFIJSV2010] used in § B.2 ‘Groth16 batch verification’ on p. 158, by applying them to BCTV14. Numerous people have contributed to the science of zero-knowledge proving systems, but we would particularly like to acknowledge the work of Shafi Goldwasser, Silvio Micali, Oded Goldreich, Charles Rackoff, Rosario Gennaro, Bryan Parno, Jon Howell, Craig Gentry, Mariana Raykova, Jens Groth, Rafail Ostrovsky, and Amit Sahai. 106

Many of the ideas used in Zcash —including the use of zero-knowledge proofs to resolve the tension between privacy and auditability, Merkle trees over note commitments (using Pedersen hashes as in Sapling), and the use of “serial numbers” or nullifiers to detect or prevent double-spends— were first applied to privacy-preserving digital currencies by Tomas Sander and Amnon Ta–Shma. To a large extent Zcash is a refinement of their “Auditable, Anonymous Electronic Cash” proposal in [ST1999]. We thank Alexandra Elbakyan for her tireless work in dismantling barriers to scientific research. Finally, we would like to thank the Internet Archive for their scan of Peter Newell’s illustration of the Jubjub bird, from [Carroll1902]. 10 Change History 2021.1.16 2021-01-11 • Add macros and Makefile support for building the Orchard draft specification. • Clarify the encoding of block heights for the “height in coinbase” rule. The description of this rule has also moved from § 7.5 on p. 90 to § 7.1 ‘Transaction Encoding and Consensus’ on p. 85. • Include the activation dates of Heartwood and Canopy in § 6 ‘Network Upgrades’ on p. 83. • Section links in the Heartwood and Canopy versions of the specification now go to the correct document URL. • Attempt to improve search and cut-and-paste behaviour for ligatures in some PDF readers. 2020.1.15 2020-11-06 • Add a missing consensus rule that has always been implemented in zcashd: there must be at least one transparent output , Output description, or JoinSplit description in a transaction. • Add a consensus rule that the (zero-valued) coinbase transaction output of the genesis block cannot be spent. • Define Sprout chain value pool balance and Sapling chain value pool balance, and include consensus rules from [ZIP-209]. • Correct the Sapling note decryption algorithms: – ephemeralKey is kept as a byte sequence rather than immediately converted to a curve point; this matters because of non-canonical encoding. – The representation of pkd in a note plaintext may also be non-canonical and need not be in the prime subgroup. – Move checking of cm𝑢 in decryption with ivk to the end of the algorithm, to more closely match the implementation. – The note about decryption of outputs in mempool transactions should have been normative. • Reserve transaction version number 0x7FFFFFFF and version group ID 0xFFFFFFFF for experimental use. • Remove a statement that the language consisting of key and address encoding possibilities is prefix-free. (The human-readable forms are prefix-free but the raw encodings are not; for example, the raw encoding of a Sapling spending key can be a prefix of several of the other encodings.) • Use “let mutable” to introduce mutable variables in algorithms. • Include a reference to [BFIJSV2010] for batch pairing verification techniques. • Acknowledge Jack Gavigan as a co-designer of Sapling and of the Zcash protocol. • Acknowledge Izaak Meckler, Zac Williamson, Vitalik Buterin, and Jakub Zalewski. • Acknowledge Alexandra Elbakyan. 107

2020.1.14 2020-08-19 • The consensus rule that a coinbase transaction must not spend more than is available from the block subsidy and transaction fees, was not explicitly stated. (This rule was correctly implemented in zcashd.) • Fix a type error in the output of PRFnfSapling ; a Sapling nullifier is a sequence of 32 bytes, not a bit sequence. • Correct an off-by-one in an expression used in the definition of 𝑐 in § 5.4.1.7 ‘Pedersen Hash Function’ on p. 58 (this does not change the value of 𝑐). 2020.1.13 2020-08-11 • Rename the type of Sapling transmission keys from KASapling .PublicPrimeOrder to KASapling .PublicPrimeSubgroup. This type is defined as J(𝑟) , which reflects the implementation in zcashd (subject to the next point below); it was never enforced that a transmission key (pkd ) cannot be 𝒪J . • Add a non-normative note saying that zcashd does not fully conform to the requirement to treat transmission keys not in KASapling .PublicPrimeSubgroup as invalid when importing shielded payment addresses. • Set CanopyActivationHeight for Testnet . • Modify the tables and notes in § 7.9.1 ‘ZIP 214 Funding Streams’ on p. 99 to reflect changes in [ZIP-214]. old • Updates to reflect [ZIP-211]: add a consensus rule on vpub in § 4.3 ‘JoinSplit Descriptions’ on p. 31, and a rule about node and wallet support for sending to Sprout addresses in § 4.6.1 ‘Sending Notes (Sprout)’ on p. 34. • Refine the domain of HeightForHalving from N to N+ . • Make Halving(height) return 0 (rather than −1) for height < SlowStartShift. This has no effect on consensus since the Halving function is not used in that case, but it makes the definition match the intuitive meaning of the function. • Rename sections under § 7 ‘Consensus Changes from Bitcoin’ on p. 85 to clarify that these sections do not only concern encoding, but also consensus rules. • Make the Canopy specification the default. 2020.1.12 2020-08-03 • Include SHA-512 in § 5.4.1.1 ‘SHA-256, SHA-256d, SHA256Compress, and SHA-512 Hash Functions’ on p. 55. • Add a reference to [BCCGLRT2014] in § 4.1.12 ‘Zero-Knowledge Proving System’ on p. 28. • Use abstBytesEd25519 and reprBytesEd25519 for conversions in § B.3 ‘Ed25519 batch validation’ on p. 160, and fix a missing requirement that 𝑆𝑗 < ℓ for all signatures. 2020.1.11 2020-07-13 • Change instances of “the production network” to “Mainnet ”, and “the test network” to Testnet . This follows the terminology used in ZIPs. • Update stale references to Bitcoin documentation. • Add changes for [ZIP-207] and [ZIP-214]. 2020.1.10 2020-07-05 • Corrections to a note in § 5.4.5 ‘Ed25519’ on p. 63. 108

2020.1.9 2020-07-05 • Add § 3.11 ‘Mainnet and Testnet’ on p. 18. • Acknowledge Jane Lusby and Teor. • Precisely specify the encoding and decoding of Ed25519 points. • Correct an error introduced in 2020.1.8; “−𝒪J ” was incorrectly used when the point (0, −1) on Jubjub was meant. • Precisely specify the conversion from a bit sequence in abstJ . 2020.1.8 2020-07-04 • Add Ying Tong Lai and Kris Nuttycombe as Zcash protocol designers. • Change the specification of abstJ in § 5.4.8.3 ‘Jubjub’ on p. 73 to match the implementation. (𝑟)* • Repair the argument for GroupHashJURS being usable as a random oracle, which previously depended on abstJ being injective. • In RedDSA verification, clarify that 𝑅 used as part of the input to H~ must be exactly as encoded in the signature. • Specify that shielded outputs of coinbase transactions MUST use v2 note plaintexts after Canopy activation. • Correct a bug in § 4.17.3 ‘Decryption using a Full Viewing Key (Sapling)’ on p. 50: esk is only to be checked against ToScalar PRFexpand rseed ([4]) when leadByte ̸= 0x01. (︀ )︀ 2020.1.7 2020-06-26 • Delete some ‘new’ superscripts that only added notational clutter. • Add an explicit lead byte field to Sprout note plaintexts, and clearly specify the error handling when it is invalid. • Define a Sapling note plaintext lead byte as having type BY (so that decoding to a note plaintext always succeeds, and error handling is more explicit). • Fix a sign error in the fixed-base term of the batch validation equation in § B.1 ‘RedDSA batch validation’ on p. 157. • Fix a sign error in the fixed-base term of the batch validation equation in § B.3 ‘Ed25519 batch validation’ on p. 160. 2020.1.6 2020-06-17 • Incorporate changes to Sapling note encryption from [ZIP-212]. • Correct an error in the specification of Ed25519 validating keys: they should not have been specified to be checked against ExcludedPointEncodings, since libsodium v1.0.15 does not do so. • Incorporate Ed25519 changes for Canopy from [ZIP-215]. • Add Appendix § B.3 ‘Ed25519 batch validation’ on p. 160. • Consistently use “validating” for signatures and “verifying” for proofs. √ • Use the symbol + ∙ for positive square root. 2020.1.5 2020-06-02 • Reference [ZIP-173] instead of BIP 173. • Mark more index entries as definitions. 109

2020.1.4 2020-05-27 • Reference [BIP-32] and [ZIP-32] when describing keys and their encodings. • Network Upgrade 4 has been given the name Canopy. • Reference [ZIP-211], [ZIP-212], and [ZIP-215] for the Canopy upgrade. • Improve LaTeX portability of this specification. 2020.1.3 2020-04-22 • Correct a wording error transposing transparent inputs and transparent outputs in § 4.11 ‘Balance (Sprout)’ on p. 39. • Minor wording clarifications. • Reference [ZIP-251], [ZIP-207], and [ZIP-214] for the Canopy upgrade. 2020.1.2 2020-03-20 • The implementation of Sprout Ed25519 signature validation in zcashd differed from what was specified in § 5.4.5 ‘Ed25519’ on p. 63. The specification has been changed to match the implementation. • Add consensus rules for Heartwood. • Remove “pvc” Makefile targets. • Make the Heartwood specification the default. • Add macros and Makefile support for building the Canopy specification. 2020.1.1 2020-02-13 • Resolve conflicts in the specification of memo fields by deferring to [ZIP-302]. 2020.1.0 2020-02-06 • Specify a retrospective soft fork implemented in zcashd v2.1.1-1 that limits the nTime field of a block relative to its median-time-past . • Correct the definition of median-time-past for the first PoWMedianBlockSpan blocks in a block chain. • Add acknowledgements to Henry de Valence, Deirdre Connolly, Chelsea Komlo, and Zancas Wilcox. • Add an acknowledgement to Trail of Bits for their security audit. • Change indices in the incremental Merkle tree diagram to be zero-based. • Use the term “monomorphism” for an injective homomorphism, in the context of a signature scheme with key monomorphism. 2019.0.9 2019-12-27 • No changes to Sprout or Sapling. • Specify the height at which Blossom activated. • Add Blossom to § 6 ‘Network Upgrades’ on p. 83. • Add a non-normative note giving the explicit value of FoundersRewardLastBlockHeight. • Clarify the effect of Blossom on SIGHASH transaction hashes. • Makefile updates for Heartwood. 110

2019.0.8 2019-09-24 • No changes to Sprout. • Fix a typo in the generator 𝒫S1 in § 5.4.8.2 ‘BLS12-381’ on p. 71 found by magrady. • Clarify the type of vnew in § 4.6.2 ‘Sending Notes (Sapling)’ on p. 34. 2019.0.7 2019-09-24 • Fix a discrepancy in the number of constraints for BLAKE2s found by QED-it. • Fix an error in the expression for Δ in § A.3.3.9 ‘Pedersen hash’ on p. 147, and add acknowledgement to Kobi Gurkan. • Fix a typo in § 4.8 ‘Merkle Path Validity’ on p. 37 and add acknowledgement to Weikeng Chen. • Update references to ZIPs and to the Electric Coin Company blog. • Makefile improvements to suppress unneeded output. 2019.0.6 2019-08-23 • No changes to Sprout or Sapling. • Replace dummy Blossom activation block height with the Testnet height, and a reference to [ZIP-206]. 2019.0.5 2019-08-23 • Note the change to the minimum-difficulty threshold time on Testnet for Blossom. • Correct the packing of nf old into input elements in § A.4 ‘The Sapling Spend circuit’ on p. 154. • Add an epigraph from [Carroll1876] to the start of § 5.4.8.3 ‘Jubjub’ on p. 73. • Clarify how the constant 𝑐 in § 5.4.1.7 ‘Pedersen Hash Function’ on p. 58 is obtained. • Add a footnote that zcashd uses [ZIP-32] extended spending keys instead of the derivation from sk in § 3.1 ‘Payment Addresses and Keys’ on p. 12. • Remove “optimized” Makefile targets (which actually produced a larger PDF, with TeXLive 2019). • Remove “html” Makefile targets. • Make the Blossom spec the default. 2019.0.4 2019-07-23 • Clicking on a section heading now shows section labels. • Add a List of Theorems and Lemmata. • Changes needed to support TeXLive 2019. 2019.0.3 2019-07-08 • Experimental support for building using LuaTEX and XeTEX. • Add an Index. 111

2019.0.2 2019-06-18 • Correct a misstatement in the security argument in § 4.12 ‘Balance and Binding Signature (Sapling)’ on p. 39: binding for a commitment scheme does not imply that the commitment determines its randomness. The rest of the security argument did not depend on this; it is simpler to rely on knowledge soundness of the Spend and Output proofs. • Give a definition for complete twisted Edwards elliptic curves in § 5.4.8.3 ‘Jubjub’ on p. 73. • Clarify that Theorem 5.4.2 on p. 60 depends on the parameters of the Jubjub curve. • Ensure that this document builds correctly and without missing characters on recent versions of TEXLive. • Update the Makefile to use Ghostscript for PDF optimization. • Ensure that hyperlinks are preserved, and available as “Destination names” in URL fragments and links from other PDF documents. 2019.0.1 2019-05-20 • No changes to Sprout or Sapling. • Minor fix to the list of integer constants in § 2 ‘Notation’ on p. 9. • Use IsBlossomActivated in the definition of FounderAddressAdjustedHeight for consistency. 2019.0.0 2019-05-01 • Fix a specification error in the Founders’ Reward calculation during the slow start period. • Correct an inconsistency in difficulty adjustment between the spec and zcashd implementation for the first PoWAveragingWindow − 1 blocks of the block chain. This inconsistency was pointed out by NCC Group in their Blossom specification audit. • Revert changes for funding streams from Withdrawn ZIP 207. 2019.0-beta-39 2019-04-18 • Change author affiliations from “Zerocoin Electric Coin Company” to “Electric Coin Company”. • Add acknowledgement to Mary Maller for the observation that diversified payment address unlinkability can be proven in the same way as key privacy for ElGamal. 2019.0-beta-38 2019-04-18 • Update the following sections to match the current draft of [ZIP-208]: – § 7.6.3 ‘Difficulty adjustment’ on p. 93 – § 7.7 ‘Calculation of Block Subsidy, Funding Streams, and Founders’ Reward’ on p. 95 • Specify funding streams, along with the draft funding streams defined in the current draft of ZIP 207. • Update the following sections to match the current draft of ZIP 207: – § 3.9 ‘Block Subsidy, Funding Streams, and Founders’ Reward’ on p. 18 – § 3.10 ‘Coinbase Transactions’ on p. 18 – § 7.7 ‘Calculation of Block Subsidy, Funding Streams, and Founders’ Reward’ on p. 95 – § 7.8 ‘Payment of Founders’ Reward’ on p. 96 • Correct the generators 𝒫S1 and 𝒫S2 for BLS12-381. • Update README.rst to include Makefile targets for Blossom. • Makefile updates: – Fix a typo for the pvcblossom target. – Update the pinned git hashes for sam2p and pdfsizeopt. 112

2019.0-beta-37 2019-02-22 • The rule that miners SHOULD NOT mine blocks that chain to other blocks with a block version number greater than 4, has been removed. This is because such blocks (mined nonconformantly) exist in the current Mainnet consensus block chain. • Clarify that Equihash is based on a variation of the Generalized Birthday Problem, and cite [AR2017]. • Update reference [BGG2017] (previously [BGG2016]). • Clarify which transaction fields are added by Overwinter and Sapling. • Correct the rule about when a transaction is permitted to have no transparent inputs. • Explain the differences between the system in [Groth2016] and what we refer to as Groth16. • Reference Mary Maller’s security proof for Groth16 [Maller2018]. • Correct [BGM2018] to [BGM2017]. • Fix a typo in § B.2 ‘Groth16 batch verification’ on p. 158 and clarify the costs of Groth16 batch verification. • Add macros and Makefile support for building the Blossom specification. 2019.0-beta-36 2019-02-09 • Correct isis agora lovecruft’s name. 2019.0-beta-35 2019-02-08 • Cite [Gabizon2019] and acknowledge Ariel Gabizon. • Correct [SBB2019] to [SWB2019]. • The [Gabizon2019] vulnerability affected Soundness of BCTV14 as well as Knowledge Soundness. • Clarify the history of the [Parno2015] vulnerability and acknowledge Bryan Parno. • Specify the difficulty adjustment change that occurred on Testnet at block height 299188. • Add Eirik Ogilvie-Wigley and Benjamin Winston to acknowledgements. • Rename zk-SNARK Parameters sections to be named according to the proving system (BCTV14 or Groth16), not the shielded protocol construction (Sprout or Sapling). • In § 6 ‘Network Upgrades’ on p. 83, say when Sapling activated. 2019.0-beta-34 2019-02-05 • Disclose a security vulnerability in BCTV14 that affected Sprout before activation of the Sapling network upgrade (see § 5.4.9.1 ‘BCTV14’ on p. 75). • Rename PHGR13 to BCTV2014. • Rename reference [BCTV2015] to [BCTV2014a], and [BCTV2014] to [BCTV2014b]. 2018.0-beta-33 2018-11-14 • No changes to Sprout. • Complete § A.4 ‘The Sapling Spend circuit’ on p. 154. • Add § A.5 ‘The Sapling Output circuit’ on p. 156. • Change the description of window lookup in § A.3.3.7 ‘Fixed-base Affine-ctEdwards scalar multiplication’ on p. 145 to match sapling-crypto. • Describe 2-bit window lookup with conditional negation in § A.3.3.9 ‘Pedersen hash’ on p. 147. • Fix or complete various calculations of constraint costs. • Adjust the notation used for scalar multiplication in Appendix A to allow bit sequences as scalars. 113

2018.0-beta-32 2018-10-24 • No changes to Sprout. • Correct the input to H~ used to derive the nonce 𝑟 in RedDSA.Sign, from 𝑇 || 𝑀 to 𝑇 || vk || 𝑀 . This matches the sapling-crypto implementation; the specification of this input was unintentionally changed in version 2018.0-beta-20. • Clarify the description of the Merkle path check in § A.3.4 ‘Merkle path check’ on p. 150. 2018.0-beta-31 2018-09-30 • No changes to Sprout. • Correct some uses of 𝑟J that should have been 𝑟S or 𝑞. • Correct uses of LEOS2IPℓ in RedDSA.Validate and RedDSA.BatchValidate to ensure that ℓ is a multiple of 8 as required. • Minor changes to avoid clashing notation for Edwards curves 𝐸Edwards(𝑎,𝑑) , Montgomery curves 𝐸Mont(𝐴,𝐵) , and extractors ℰ𝒜 . • Correct a use of J that should have been M in the proof of Theorem A.3.4 on p. 143, and make a minor tweak to the theorem statement (𝑘2 ̸= ±𝑘1 instead of 𝑘1 ̸= ±𝑘2 ) to make the contradiction derived by the proof clearer. • Clarify notation in the proof of Theorem A.3.3 on p. 143. • Address some of the findings of the QED-it report: – Improved cross-referencing in § 5.4.1.7 ‘Pedersen Hash Function’ on p. 58. – Clarify the notes concerning domain separation of prefixes in § 5.4.1.3 ‘MerkleCRHSapling Hash Function’ on p. 56 and § 5.4.7.2 ‘Windowed Pedersen commitments’ on p. 68. – Correct the statement and proof of Theorem A.3.2 on p. 143. • Add the QED-it report to the acknowledgements. 2018.0-beta-30 2018-09-02 • No changes to Sprout. • Give an informal security argument for Unlinkability of diversified payment addresses based on reduction to key privacy of ElGamal encryption, for which a security proof is given in [BBDP2001]. (This argument has gaps which will be addressed in a future version.) • Add a reference to [BGM2017] for the Sapling zk-SNARK parameters. • Write § A.4 ‘The Sapling Spend circuit’ on p. 154 (draft). • Add a reference to the ristretto_bulletproofs design notes [Dalek-notes] for the synthetic blinding factor technique. • Ensure that the constraint costs in § A.3.3.1 ‘Checking that Affine-ctEdwards coordinates are on the curve’ on p. 142 and § A.3.3.6 ‘Affine-ctEdwards nonsmall-order check’ on p. 145 accurately reflect the implementa- tion in sapling-crypto. • Minor correction to the non-normative note in § A.3.2.2 ‘Range check’ on p. 140. • Clarify the non-normative note in § 4.1.7 ‘Commitment’ on p. 25 about the definitions of ValueCommit.Output and NoteCommitSapling .Output. • Clarify that the signer of a spend authorization signature is supposed to choose the spend authorization randomizer , 𝛼, itself. Only step 4 in the procedure in § 4.13 ‘Spend Authorization Signature’ on p. 41 may securely be delegated. • Add a non-normative note to § 5.4.6 ‘RedDSA and RedJubjub’ on p. 65 explaining that RedDSA key random- ization may interact with other uses of additive properties of Schnorr keys. • Add dates to Change History entries. (These are the dates of the git tags in local, i.e. UK, time.) 114

2018.0-beta-29 2018-08-15 • No changes to Sprout. • Finish § A.3.2.2 ‘Range check’ on p. 140. • Change § A.3.7 ‘BLAKE2s hashes’ on p. 151 to correct the constraint count and to describe batched equality checks performed by the sapling-crypto implementation. 2018.0-beta-28 2018-08-14 • No changes to Sprout. • Finish § A.3.7 ‘BLAKE2s hashes’ on p. 151. • Minor corrections to § A.3.3.8 ‘Variable-base Affine-ctEdwards scalar multiplication’ on p. 146. 2018.0-beta-27 2018-08-12 • Notational changes: – Use a superscript (𝑟) to mark the subgroup order, instead of a subscript. – Use G(𝑟)* for the set of 𝑟G -order points in G. (𝑟) – Mark the subgroup order in pairing groups, e.g. use G1 instead of G1 . – Make the bit-representation indicator ⋆ an affix instead of a superscript. • Clarify that when validating a Groth16 proof, it is necessary to perform a subgroup check for 𝜋𝐴 and 𝜋𝐶 as well as for 𝜋𝐵 . • Correct the description of Groth16 batch verification to explicitly take account of how verification depends on primary inputs. • Add Charles Rackoff, Rafail Ostrovsky, and Amit Sahai to the acknowledgements section for their work on zero-knowledge proofs. 2018.0-beta-26 2018-08-05 • No changes to Sprout. • Add § B.2 ‘Groth16 batch verification’ on p. 158. 2018.0-beta-25 2018-08-05 • No changes to Sprout. • Add the hashes of parameter files for Sapling. • Add cross references for parameters and functions used in RedDSA batch validation. • Makefile changes: name the PDF file for the Sprout version of the specification as sprout.pdf, and make protocol.pdf link to the Sapling version. 2018.0-beta-24 2018-07-31 • No changes to Sprout. • Add a missing consensus rule for version 4 transactions: if there are no Sapling Spends or Outputs, then valueBalance MUST be 0. 115

2018.0-beta-23 2018-07-27 • No changes to Sprout. • Update RedDSA validation to use cofactor multiplication. This is necessary in order for the output of batch validation to match that of unbatched validation in all cases. • Add § B.1 ‘RedDSA batch validation’ on p. 157. 2018.0-beta-22 2018-07-18 • No changes to Sprout. • Update § 6 ‘Network Upgrades’ on p. 83 to take account that Overwinter has activated. • The recommendation for transactions without JoinSplit descriptions to be version 1 applies only before Overwinter, not before Sapling. • Complete the proof of Theorem A.3.5 on p. 148. • Add a note about redundancy in the nonsmall-order checking of rk. • Clarify the use of cvnew and cmnew , and the selection of outgoing viewing key , in sending Sapling notes. • Delete the description of optimizations for the affine twisted Edwards nonsmall-order check, since the Sapling circuit does not use them. Also clarify that some other optimizations are not used. 2018.0-beta-21 2018-06-22 • Remove the consensus rule “If nJoinSplit > 0, the transaction MUST NOT use SIGHASH types other than SIGHASH_ALL.”, which was never implemented. • Add section on signature hashing. • Briefly describe the changes to computation of SIGHASH transaction hashes in Sprout. • Clarify that interstitial treestates form a tree for each transaction containing JoinSplit descriptions. • Correct the description of P2PKH addresses in § 5.6.1 ‘Transparent Addresses’ on p. 78 — they use a hash of a compressed, not an uncompressed ECDSA key representation. • Clarify the wording of the caveat 3 about the claimed security of shielded transactions. • Correct the definition of set difference (𝑆 ∖ 𝑇 ). • Add a note concerning malleability of zk-SNARK proofs. • Clarify attribution of the Zcash protocol design. • Acknowledge Alex Biryukov and Dmitry Khovratovich as the designers of Equihash. • Acknowledge Shafi Goldwasser, Silvio Micali, Oded Goldreich, Rosario Gennaro, Bryan Parno, Jon Howell, Craig Gentry, Mariana Raykova, and Jens Groth for their work on zero-knowledge proving systems. • Acknowledge Tomas Sander and Amnon Ta–Shma for [ST1999]. • Acknowledge Kudelski Security’s audit. • Use the more precise subgroup types G(𝑟) and J(𝑟) in preference to G and J where applicable. • Change the types of auxiliary inputs to the Spend statement and Output statement , to be more faithful to the implementation. • Rename the cm field of an Output description to cmu, reflecting the fact that it is a Jubjub curve 𝑢-coordinate. • Add explicit consensus rules that the anchor field of a Spend description and the cmu field of an Output description must be canonical encodings. • Enforce that esk in outCiphertext is a canonical encoding. 116

• Add consensus rules that cv in a Spend description, and cv and epk in an Output description, are not of small order. Exclude 0 from the range of esk when encrypting Sapling notes. • Add a consensus rule that valueBalance is in the range {−MAX_MONEY .. MAX_MONEY}. • Enforce stronger constraints on the types of key components pkd , ak, and nk. • Correct the conformance rule for fOverwintered (it must not be set before Overwinter has activated, not before Sapling has activated). • Correct the argument that v* is in range in § 4.12 ‘Balance and Binding Signature (Sapling)’ on p. 39. • Correct an error in the algorithm for RedDSA.Validate: the validating key vk is given directly to this algorithm and should not be computed from the unknown signing key sk. (𝑟)* (𝑟)* • Correct or improve the types of GroupHashJ , FindGroupHashJ , ExtractJ(𝑟) , PRFexpand , PRFock , and CRHivk . • Instantiate PRFock using BLAKE2b-256. • Change the syntax of a commitment scheme to add COMM.GenTrapdoor. This is necessary because the intended distribution of commitment trapdoors may not be uniform on all values that are acceptable trapdoor inputs. • Add notes on the purpose of outgoing viewing keys. • Correct the encoding of a full viewing key (ovk was missing). • Ensure that Sprout functions and values are given Sprout-specific types where appropriate. • Improve cross-referencing. • Clarify the use of BCTV14 vs Groth16 proofs in JoinSplit statements. √ • Clarify that the + 𝑎 notation refers to the positive square root. (This matters for the conversion in § A.3.3.3 ‘ctEdwards ↔ Montgomery conversion’ on p. 142.) • Model the group hash as a random oracle. This appears to be unavoidable in order to allow proving unlink- ability of DiversifyHash. Explain how this relates to the Discrete Logarithm Independence assumption used previously, and justify this modelling by showing that it follows from treating BLAKE2s-256 as a random oracle (𝑟)* in the instantiation of GroupHashJ . • Rename CRS (Common Random String) to URS (Uniform Random String ), to match the terminology adopted at the first zkproof workshop held in Boston, Massachusetts on May 10–11, 2018. • Generalize PRFexpand to accept an arbitrary-length input. (This specification does not use that generalization, but [ZIP-32] does.) • Change the notation for a multiplication constraint in Appendix § A ‘Circuit Design’ on p. 137 to avoid potential confusion with cartesian product. • Clarify the wording of the abstract. • Correct statements about which algorithms are instantiated by BLAKE2s and BLAKE2b. • Add a note explaining which conformance requirements of BIP 173 (defining Bech32) apply. • Add the Jubjub bird image to the title page. This image has been edited from a scan of Peter Newell’s original illustration (as it appeared in [Carroll1902]) to remove the background and Bandersnatch, and to restore the bird’s clipped right wing. • Change the light yellow background to white (indicating that this Overwinter and Sapling specification is no longer a draft). 117

2018.0-beta-20 2018-05-22 • Add Michael Dixon and Andrew Poelstra to acknowledgements. • Minor improvements to cross-references. • Correct the order of arguments to RedDSA.RandomizePrivate and RedDSA.RandomizePublic. • Correct a reference to RedDSA.RandomizePrivate that was intended to be RedDSA.RandomizePublic. • Fix the description of the balancing value in § 4.12 ‘Balance and Binding Signature (Sapling)’ on p. 39. • Correct a type error in § 5.4.8.5 ‘Group Hash into Jubjub’ on p. 74. • Correct a type error in RedDSA.Sign in § 5.4.6 ‘RedDSA and RedJubjub’ on p. 65. • Ensure 𝒢 is defined in § 5.4.6.1 ‘Spend Authorization Signature’ on p. 67. • Make the validating key prefix part of the input to the hash function in RedDSA, not part of the message. (𝑟)* • Correct the statement about FindGroupHashJ never returning ⊥. • Correct an error in the computation of generators for Pedersen hashes. • Change the order in which NoteCommitSapling commits to its inputs, to match the sapling-crypto implementa- tion. • Fail Sapling key generation if ivk = 0. (This has negligible probability.) • Change the notation H⋆ to H~ in § 5.4.6 ‘RedDSA and RedJubjub’ on p. 65, to avoid confusion with the ⋆ con- vention for representations of group elements. • cmu encodes only the 𝑢-coordinate of the note commitment , not the full curve point. • rk is checked to be not of small order outside the Spend statement , not in the Spend statement . • Change terminology describing constraint systems. 2018.0-beta-19 2018-04-23 • No changes to Sprout. • Minor clarifications. 2018.0-beta-18 2018-04-23 • No changes to Sprout. • Clarify the security argument for balance in Sapling. • Correct a subtle problem with the type of the value input to ValueCommit: although it is only directly used to commit {︁ to values}︁in {0 .. 2ℓvalue −1}, the security argument depends on a sum of commitments being binding 𝑟J −1 𝑟J −1 on − 2 .. 2 . • Fix the loss of tightness in the use of PRFnfSapling by specifying the keyspace more precisely. • Correct type ambiguities for ρ. • Specify the representation of 𝑖 in group G2 of BLS12-381. 2018.0-beta-17 2018-04-21 • No changes to Sprout. • Correct an error in the definition of DefaultDiversifier. 118

2018.0-beta-16 2018-04-21 • Explicitly note that outputs from coinbase transactions include Founders’ Reward outputs. • The point represented by 𝑅 in an Ed25519 signature is checked to not be of small order; this is not the same as checking that it is of prime order ℓ. • Specify support for [BIP-111] (the NODE_BLOOM service bit) in network protocol version 170004. • Give references [Vercauter2009] and [AKLGL2010] for the optimal ate pairing. • Give references for BLS [BLS2002] and BN [BN2005] curves. • Define KASprout .DerivePublic for Curve25519. • Caveat the claim about note traceability set in § 1.2 ‘High-level Overview’ on p. 8 and link to [Peterson2017] and [Quesnelle2017]. • Do not require a generator as part of the specification of a represented group; instead, define it in the represented pairing or scheme using the group. • Refactor the abstract definition of a signature scheme to allow derivation of validating keys independent of key pair generation. • Correct the explanation in § 1.2 ‘High-level Overview’ on p. 8 to apply to Sapling. • Add the definition of a signing key to validating key homomorphism for signature schemes. • Remove the output index as an input to KDFSapling . • Allow dummy Sapling input notes. • Specify RedDSA and RedJubjub. • Specify binding signatures and spend authorization signatures. • Specify the randomness beacon. • Add Output ciphertexts and ock. • Define DefaultDiversifier. • Change the Spend circuit and Output circuit specifications to remove unintended differences from sapling- crypto. • Use ℎJ to refer to the Jubjub curve cofactor, rather than 8. • Correct an error in the 𝑦-coordinate formula for addition in § A.3.3.4 ‘Affine-Montgomery arithmetic’ on p. 143 (the constraints were correct). • Add acknowledgements for Brian Warner, Mary Maller, and the Least Authority audit. • Makefile improvements. 2018.0-beta-15 2018-03-19 • Clarify the bit ordering of SHA-256. • Drop _t from the names of representation types. • Remove functions from the Sprout specification that it does not use. • Updates to transaction format and consensus rules for Overwinter and Sapling. • Add specification of the Output statement . • Change MerkleDepthSapling from 29 to 32. • Updates to Sapling construction, changing how the nullifier is computed and separating it from the random- ized Spend validating key (rk). • Clarify conversions between bit and byte sequences for sk, reprJ (ak), and reprJ (nk). 119

• Change the Makefile to avoid multiple reloads in PDF readers while rebuilding the PDF. • Spacing and pagination improvements. 2018.0-beta-14 2018-03-11 • Only cosmetic changes to Sprout. (𝑟)* • Simplify FindGroupHashJ to use a single-byte index. • Changes to diversification for Pedersen hashes and Pedersen commitments. • Improve security definitions for signatures. 2018.0-beta-13 2018-03-11 • Only cosmetic changes to Sprout. • Change how (ask, nsk) are derived from the spending key sk to ensure they are on the full range of F𝑟J . • Change PRFnr to produce output computationally indistinguishable from uniform on F𝑟J . • Change UncommittedSapling to be a 𝑢-coordinate for which there is no point on the curve. • Appendix A updates: – categorize components into larger sections – fill in the [de]compression and validation algorithm – more precisely state the assumptions for inputs and outputs – delete not-all-one component which is no longer needed – factor out xor into its own component – specify [un]packing more precisely; separate it from boolean constraints – optimize checking for non-small order – notation in variable-base multiplication algorithm. 2018.0-beta-12 2018-03-06 • No changes to Sprout. • Add references to Overwinter ZIPs and update the section on Overwinter/Sapling transitions. • Add a section on re-randomizable signatures. • Add definition of PRFnr . • Work-in-progress on Sapling statements. • Rename “raw ” to “homomorphic ” Pedersen commitments. • Add packing modulo the field size and range checks to Appendix A. • Update the algorithm for variable-base scalar multiplication to what is implemented by sapling-crypto. 2018.0-beta-11 2018-02-26 • No changes to Sprout. • Add sections on Spend descriptions and Output descriptions. • Swap order of cv and rt in a Spend description for consistency. • Fix off-by-one error in the range of ivk. 120

2018.0-beta-10 2018-02-26 • Split the descriptions of SHA-256 and SHA256Compress, and of BLAKE2, into their own sections. Specify SHA256Compress more precisely. • Add Tracy Hu to acknowledgements (for the idea of explicitly encoding the root of the Sapling note commit- ment tree in block headers). • Move bit/byte/integer conversion primitives into § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53. • Refer to Overwinter and Sapling just as “upgrades” in the abstract, not as the next “minor version” and “major version”. • PRFnr must be collision-resistant . • Correct an error in the Pedersen hash specification. • Use a named variable, 𝑐, for chunks per segment in the Pedersen hash specification, and change its value from 61 to 63. Add a proof justifying this value of 𝑐. • Specify Pedersen commitments. • Notation changes. • Generalize the distinct-𝑥 criterion (Theorem A.3.4 on p. 143) to allow negative indices. 2018.0-beta-9 2018-02-10 • Specify the coinbase maturity rule, and the rule that coinbase transactions cannot contain JoinSplit descrip- tions, Spend descriptions, or Output descriptions. • Delay lifting the 100000-byte transaction size limit from Overwinter to Sapling. • Improve presentation of the proof of injectivity for ExtractJ(𝑟) . (𝑟)* • Specify GroupHashJ . • Specify Pedersen hashes. 2018.0-beta-8 2018-02-08 • No changes to Sprout. • Add instantiation of CRHivk . • Add instantiation of a hash extractor for Jubjub. • Make the background lighter and the Sapling green darker, for contrast. 2018.0-beta-7 2018-02-07 • Specify the 100000-byte limit on transaction size. (The implementation in zcashd was as intended.) • Specify that 0xF6 followed by 511 zero bytes encodes an empty memo field . • Reference security definitions for Pseudo Random Functions and Pseudo Random Generators. • Rename clamp to bound and ActualTimespanClamped to ActualTimespanBounded in the difficulty adjustment algorithm, to avoid a name collision with Curve25519 scalar “clamping”. • Change uses of the term full node to full validator . A full node by definition participates in the peer-to-peer network, whereas a full validator just needs a copy of the block chain from somewhere. The latter is what was meant. • Add an explanation of how Sapling prevents Faerie Gold and roadblock attacks. • Sapling work in progress. 121

2018.0-beta-6 2018-01-31 • No changes to Sprout. • Sapling work in progress, mainly on Appendix § A ‘Circuit Design’ on p. 137. 2018.0-beta-5 2018-01-30 • Specify more precisely the requirements on Ed25519 validating keys and signatures. • Sapling work in progress. 2018.0-beta-4 2018-01-25 • No changes to Sprout. • Update key components diagram for Sapling. 2018.0-beta-3 2018-01-22 • Explain how the chosen fix to Faerie Gold avoids a potential “roadblock” attack. • Update some explanations of changes from Zerocash for Sapling. • Add a description of the Jubjub curve. • Add an acknowledgement to George Tankersley. • Add an appendix on the design of the Sapling circuits at the quadratic constraint program level. 2017.0-beta-2.9 2017-12-17 • Refer to skenc as a receiving key rather than as a viewing key. • Updates for incoming viewing key support. • Refer to Network Upgrade 0 as Overwinter. 2017.0-beta-2.8 2017-12-02 • Correct the non-normative note describing how to check the order of 𝜋𝐵 . • Initial version of draft Sapling protocol specification. 2017.0-beta-2.7 2017-07-10 • Fix an off-by-one error in the specification of the Equihash algorithm binding condition. (The implementation in zcashd was as intended.) • Correct the types and consensus rules for transaction version numbers and block version numbers. (Again, the implementation in zcashd was as intended.) • Clarify the computation of h𝑖 in a JoinSplit statement . 2017.0-beta-2.6 2017-05-09 • Be more precise when talking about curve points and pairing groups. 122

2017.0-beta-2.5 2017-03-07 • Clarify the consensus rule preventing double-spends. • Clarify what a note commitment opens to in § 8.8 ‘Omission in Zerocash security proof’ on p. 105. • Correct the order of arguments to COMM in § 5.4.7.1 ‘Sprout Note Commitments’ on p. 68. • Correct a statement about indistinguishability of JoinSplit descriptions. • Change the Founders’ Reward addresses, for Testnet only, to reflect the hard-fork upgrade described in [Zcash-Issue2113]. 2017.0-beta-2.4 2017-02-25 • Explain a variation on the Faerie Gold attack and why it is prevented. • Generalize the description of the InternalH attack to include finding collisions on (apk , ρ) rather than just on ρ. • Rename enforce𝑖 to enforceMerklePath𝑖 . 2017.0-beta-2.3 2017-02-12 • Specify the security requirements on the SHA256Compress function in order for the scheme in § 5.4.7.1 ‘Sprout Note Commitments’ on p. 68 to be a secure commitment. • Specify G2 more precisely. • Explain the use of interstitial treestates in chained JoinSplit transfers. 2017.0-beta-2.2 2017-02-11 • Give definitions of computational binding and computational hiding for commitment schemes. • Give a definition of statistical zero knowledge. • Reference the white paper on MPC parameter generation [BGG2017]. 2017.0-beta-2.1 2017-02-06 • ℓMerkle is a bit length, not a byte length. • Specify the maximum block size. 2017.0-beta-2 2017-02-04 • Add abstract and keywords. • Fix a typo in the definition of nullifier integrity. • Make the description of block chains more consistent with upstream Bitcoin documentation (referring to “best“ chains rather than using the concept of a block chain view ). • Define how nodes select a best valid block chain. 2016.0-beta-1.13 2017-01-20 • Specify the difficulty adjustment algorithm. • Clarify some definitions of fields in a block header . • Define PRFaddr in § 4.2.1 ‘Sprout Key Components’ on p. 29. 123

2016.0-beta-1.12 2017-01-09 • Update the hashes of proving and verifying keys for the final Sprout parameters. • Add cross references from shielded payment address and spending key encoding sections to where the key components are specified. • Add acknowledgements for Filippo Valsorda and Zaki Manian. 2016.0-beta-1.11 2016-12-19 • Specify a check on the order of 𝜋𝐵 in a zk-SNARK proof . • Note that due to an oversight, the Zcash genesis block does not follow [BIP-34]. 2016.0-beta-1.10 2016-10-30 • Update reference to the Equihash paper [BK2016]. (The newer version has no algorithmic changes, but the section discussing potential ASIC implementations is substantially expanded.) • Clarify the discussion of proof size in “Differences from the Zerocash paper”. 2016.0-beta-1.9 2016-10-28 • Add Founders’ Reward addresses for Mainnet . • Change “protected ” terminology to “shielded ”. 2016.0-beta-1.8 2016-10-04 • Revise the lead bytes for transparent P2SH and P2PKH addresses, and reencode the Testnet Founders’ Reward addresses. • Add a section on which BIPs apply to Zcash. • Specify that OP_CODESEPARATOR has been disabled, and no longer affects SIGHASH transaction hashes. • Change the representation type of vpub_old and vpub_new to uint64. (This is not a consensus change be- old new cause the type of vpub and vpub was already specified to be {0 .. MAX_MONEY}; it just better reflects the implementation.) • Correct the representation type of the block nVersion field to uint32. 2016.0-beta-1.7 2016-10-02 • Clarify the consensus rule for payment of the Founders’ Reward , in response to an issue raised by the NCC audit. 2016.0-beta-1.6 2016-09-26 • Fix an error in the definition of the sortedness condition for Equihash: it is the sequences of indices that are sorted, not the sequences of hashes. • Correct the number of bytes in the encoding of solutionSize. • Update the section on encoding of transparent addresses. (The precise prefixes are not decided yet.) • Clarify why BLAKE2b-ℓ is different from truncated BLAKE2b-512. • Clarify a note about SU-CMA security for signatures. • Add a note about PRFnf corresponding to PRFsn in Zerocash. • Add a paragraph about key length in § 8.7 ‘In-band secret distribution’ on p. 104. • Add acknowledgements for John Tromp, Paige Peterson, Maureen Walsh, Jay Graber, and Jack Gavigan. 124

2016.0-beta-1.5 2016-09-22 • Update the Founders’ Reward address list. • Add some clarifications based on Eli Ben-Sasson’s review. 2016.0-beta-1.4 2016-09-19 • Specify the block subsidy , miner subsidy , and the Founders’ Reward . • Specify coinbase transaction outputs to Founders’ Reward addresses. • Improve notation (for example “·” for multiplication and “𝑇 [ℓ] ” for sequence types) to avoid ambiguity. 2016.0-beta-1.3 2016-09-16 • Correct the omission of solutionSize from the block header format. • Document that compactSize uint encodings must be canonical. • Add a note about conformance language in the introduction. • Add acknowledgements for Solar Designer, Ling Ren and Alison Stevenson, and for the NCC Group and Coinspect security audits. 2016.0-beta-1.2 2016-09-11 • Remove GeneralCRH in favour of specifying hSigCRH and EquihashGen directly in terms of BLAKE2b-ℓ. • Correct the security requirement for EquihashGen. 2016.0-beta-1.1 2016-09-05 • Add a specification of abstract signatures. • Clarify what is signed in the “Sending Notes” section. • Specify ZK parameter generation as a randomized algorithm, rather than as a distribution of parameters. 2016.0-beta-1 2016-09-04 • Major reorganization to separate the abstract cryptographic protocol from the algorithm instantiations. • Add type declarations. • Add a “High-level Overview” section. • Add a section specifying the zero-knowledge proving system and the encoding of proofs. Change the encoding of points in proofs to follow IEEE Std 1363[a]. • Add a section on consensus changes from Bitcoin, and the specification of Equihash. • Complete the “Differences from the Zerocash paper” section. • Correct the Merkle tree depth to 29. • Change the length of memo fields to 512 bytes. • Switch the JoinSplit signature scheme to Ed25519, with consequent changes to the computation of hSig . • Fix the lead bytes in shielded payment address and spending key encodings to match the implemented protocol. old new • Add a consensus rule about the ranges of vpub and vpub . • Clarify cryptographic security requirements and added definitions relating to the in-band secret distribution. 125

• Add various citations: the “Fixing Vulnerabilities in the Zcash Protocol” and “Why Equihash?” blog posts, several crypto papers for security definitions, the Bitcoin whitepaper, the CryptoNote whitepaper, and several references to Bitcoin documentation. • Reference the extended version of the Zerocash paper rather than the Oakland proceedings version. • Add JoinSplit transfers to the Concepts section. • Add a section on Coinbase Transactions. • Add acknowledgements for Jack Grigg, Simon Liu, Ariel Gabizon, jl777, Ben Blaxill, Alex Balducci, and Jake Tarren. • Fix a Makefile compatibility problem with the escaping behaviour of echo. • Switch to biber for the bibliography generation, and add backreferences. • Make the date format in references more consistent. • Add visited dates to all URLs in references. • Terminology changes. 2016.0-alpha-3.1 2016-05-20 • Change main font to Quattrocento. 2016.0-alpha-3 2016-05-09 • Change version numbering convention (no other changes). 2.0-alpha-3 2016-05-06 • Allow anchoring to any previous output treestate in the same transaction, rather than just the immediately preceding output treestate. • Add change history. 2.0-alpha-2 2016-04-21 • Change from truncated BLAKE2b-512 to BLAKE2b-256. • Clarify endianness, and that uses of BLAKE2b are unkeyed. • Minor correction to what SIGHASH types cover. • Add “as intended for the Zcash release of summer 2016" to title page. • Require PRFaddr to be collision-resistant (see § 8.8 ‘Omission in Zerocash security proof’ on p. 105). • Add specification of path computation for the incremental Merkle tree. • Add a note in § 4.15.1 ‘JoinSplit Statement (Sprout)’ on p. 43 about how this condition corresponds to con- ditions in the Zerocash paper. • Changes to terminology around keys. 2.0-alpha-1 2016-03-30 • First version intended for public review. 126

11 References [ABR1999] Michel Abdalla, Mihir Bellare, and Phillip Rogaway. DHAES: An Encryption Scheme Based on the Diffie-Hellman Problem. Cryptology ePrint Archive: Report 1999/007. Received March 17, 1999. September 1998. URL: https://eprint.iacr.org/1999/007 (visited on 2016-08-21) (↑ p21, 104, 105). [AGRRT2017] Martin Albrecht, Lorenzo Grassi, Christian Rechberger, Arnab Roy, and Tyge Tiessen. MiMC: Efficient Encryption and Cryptographic Hashing with Minimal Multiplicative Complexity. Cryp- tology ePrint Archive: Report 2016/492. Received May 21, 2016. January 5, 2017. URL: https: //eprint.iacr.org/2016/492 (visited on 2018-01-12) (↑ p153). [AKLGL2010] Diego Aranha, Koray Karabina, Patrick Longa, Catherine Gebotys, and Julio López. Faster Explicit Formulas for Computing Pairings over Ordinary Curves. Cryptology ePrint Archive: Report 2010/526. Last revised September 12, 2011. URL: https://eprint.iacr.org/2010/526 (visited on 2018-04-03) (↑ p70, 119). [ANWW2013] Jean-Philippe Aumasson, Samuel Neves, Zooko Wilcox-O’Hearn, and Christian Winnerlein. BLAKE2: simpler, smaller, fast as MD5. January 29, 2013. URL: https://blake2.net/#sp (visited on 2016-08-14) (↑ p55, 151). [AR2017] Leo Alcock and Ling Ren. “A Note on the Security of Equihash”. In: CCSW ’17. Proceedings of the 2017 Cloud Computing Security Workshop (Dallas, TX, USA, November 3, 2017); post-workshop of the 2017 ACM SIGSAC Conference on Computer and Communications Security. ACM. URL: http://sci-hub.tw/10.1145/3140649.3140652 (visited on 2019-01-09) (↑ p92, 113). [BBDP2001] Mihir Bellare, Alexandra Boldyreva, Anand Desai, and David Pointcheval. Key-Privacy in Public- Key Encryption. September 2001. URL: https://cseweb.ucsd.edu/~mihir/papers/anonenc. html (visited on 2016-08-14). Full version. (↑ p22, 57, 104, 114). [BBJLP2008] Daniel Bernstein, Peter Birkner, Marc Joye, Tanja Lange, and Christiane Peters. Twisted Edwards Curves. Cryptology ePrint Archive: Report 2008/013. Received January 8, 2008. March 13, 2008. URL: https://eprint.iacr.org/2008/013 (visited on 2018-01-12) (↑ p143, 144). [BCCGLRT2014] Nir Bitansky, Ran Canetti, Alessandro Chiesa, Shafi Goldwasser, Huijia Lin, Aviad Rubinstein, and Eran Tromer. The Hunting of the SNARK. Cryptology ePrint Archive: Report 2014/580. Received July 24, 2014. URL: https://eprint.iacr.org/2014/580 (visited on 2020-08-01) (↑ p28, 108). [BCGGMTV2014] Eli Ben-Sasson, Alessandro Chiesa, Christina Garman, Matthew Green, Ian Miers, Eran Tromer, and Madars Virza. Zerocash: Decentralized Anonymous Payments from Bitcoin (extended ver- sion). URL: http://zerocash- project.org/media/pdf/zerocash- extended- 20140518.pdf (visited on 2016-08-06). A condensed version appeared in Proceedings of the IEEE Symposium on Security and Privacy (Oakland) 2014, pages 459–474; IEEE, 2014. (↑ p7, 8, 10, 20, 39, 43, 47, 101, 102, 103, 105). [BCGTV2013] Eli Ben-Sasson, Alessandro Chiesa, Daniel Genkin, Eran Tromer, and Madars Virza. SNARKs for C: Verifying Program Executions Succinctly and in Zero Knowledge. Cryptology ePrint Archive: Report 2013/507. Last revised October 7, 2013. URL: https://eprint.iacr.org/2013/ 507 (visited on 2016-08-31). An earlier version appeared in Proceedings of the 33rd Annual International Cryptology Conference, CRYPTO 2013, pages 90–108; IACR, 2013. (↑ p75). [BCP1988] Jurgen Bos, David Chaum, and George Purdy. “A Voting Scheme”. Unpublished. Presented at the rump session of CRYPTO ’88 (Santa Barbara, California, USA, August 21–25, 1988); does not appear in the proceedings. (↑ p58). [BCTV2014a] Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, and Madars Virza. Succinct Non-Interac- tive Zero Knowledge for a von Neumann Architecture. Cryptology ePrint Archive: Report 2013/879. Last revised February 5, 2019. URL: https://eprint.iacr.org/2013/879 (visited on 2019-02-08) (↑ p75, 76, 113, 137). 127

[BCTV2014a-old] Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, and Madars Virza. Succinct Non-Interactive Zero Knowledge for a von Neumann Architecture (May 19, 2015 version). Cryptology ePrint Archive: Report 2013/879. Version: 20150519:172604. URL: https://eprint.iacr.org/2013/ 879/20150519:172604 (visited on 2019-02-08) (↑ p75). [BCTV2014b] Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, and Madars Virza. “Scalable Zero Knowledge via Cycles of Elliptic Curves (extended version)”. In: Advances in Cryptology - CRYPTO 2014. Vol. 8617. Lecture Notes in Computer Science. Springer, 2014, pages 276–294. URL: https://www. cs.tau.ac.il/~tromer/papers/scalablezk- 20140803.pdf (visited on 2016-09-01) (↑ p 28, 113). [BDEHR2011] Johannes Buchmann, Erik Dahmen, Sarah Ereth, Andreas Hülsing, and Markus Rückert. On the Security of the Winternitz One-Time Signature Scheme (full version). Cryptology ePrint Archive: Report 2011/191. Received April 13, 2011. URL: https://eprint.iacr.org/2011/191 (visited on 2016-09-05) (↑ p22). [BDJR2000] Mihir Bellare, Anand Desai, Eric Jokipii, and Phillip Rogaway. A Concrete Security Treatment of Symmetric Encryption: Analysis of the DES Modes of Operation. September 2000. URL: https : / / cseweb . ucsd . edu / ~mihir / papers / sym - enc . html (visited on 2018-02-07). An extended abstract appeared in Proceedings of the 38th Annual Symposium on Foundations of Computer Science (Miami Beach, Florida, USA, October 20–22, 1997), pages 394–403; IEEE Computer Society Press, 1997; ISBN 0-8186-8197-7. (↑ p20). [BDLSY2012] Daniel Bernstein, Niels Duif, Tanja Lange, Peter Schwabe, and Bo-Yin Yang. “High-speed high- security signatures”. In: Journal of Cryptographic Engineering 2 (September 26, 2011), pages 77– 89. URL: http : / / cr . yp . to / papers . html # ed25519 (visited on 2016-08-14). Document ID: a1a62a2f76d23f65d622484ddd09caf8. (↑ p64, 65, 158). [Bernstein2001] Daniel Bernstein. Pippenger’s exponentiation algorithm. December 18, 2001. URL: https:// cr.yp.to/papers.html#pippenger (visited on 2018-07-27). Draft. To be incorporated into the author’s High-speed cryptography book. Error pointed out by Sam Hocevar: the example in Figure 4 needs 2 and is thus of length 18. (↑ p158, 159). [Bernstein2005] Daniel Bernstein. “Understanding brute force”. In: ECRYPT STVL Workshop on Symmetric Key Encryption, eSTREAM report 2005/036. April 25, 2005. URL: https : / / cr . yp . to / papers . html#bruteforce (visited on 2016-09-24). Document ID: 73e92f5b71793b498288efe81fe55dee. (↑ p105). [Bernstein2006] Daniel Bernstein. “Curve25519: new Diffie-Hellman speed records”. In: Public Key Cryptography – PKC 2006. Proceedings of the 9th International Conference on Theory and Practice in Public- Key Cryptography (New York, NY, USA, April 24–26, 2006). Springer-Verlag, February 9, 2006. URL: http : / / cr . yp . to / papers . html # curve25519 (visited on 2016-08-14). Document ID: 4230efdfa673480fc079449d90f322c0. (↑ p21, 62, 79, 80, 104). [BFIJSV2010] Olivier Blazy, Georg Fuchsbauer, Malika Izabachène, Amandine Jambert, Hervé Sibert, and Damien Vergnaud. Batch Groth–Sahai. Cryptology ePrint Archive: Report 2010/040. Last revised February 3, 2010. URL: https://eprint.iacr.org/2010/040 (visited on 2020-10-17) (↑ p106, 107, 158). [BGG-mpc] Sean Bowe, Ariel Gabizon, and Matthew Green. GitHub repository ‘ zcash/mpc’ : zk-SNARK parameter multi-party computation protocol. URL: https://github.com/zcash/mpc (visited on 2017-01-06) (↑ p82). [BGG1995] Mihir Bellare, Oded Goldreich, and Shafi Goldwasser. “Incremental Cryptography: The Case of Hashing and Signing”. In: Advances in Cryptology - CRYPTO ’94. Proceedings of the 14th Annual International Cryptology Conference (Santa Barbara, California, USA, August 21–25, 1994). Ed. by Yvo Desmedt. Vol. 839. Lecture Notes in Computer Science. Springer, October 20, 1995, pages 216–233. ISBN: 978-3-540-48658-9. DOI: 10 . 1007 / 3 - 540 - 48658 - 5 _ 22. URL: https : //cseweb.ucsd.edu/~mihir/papers/inc1.pdf (visited on 2018-02-09) (↑ p58, 59, 147). 128

[BGG2017] Sean Bowe, Ariel Gabizon, and Matthew Green. A multi-party protocol for constructing the public parameters of the Pinocchio zk-SNARK. Cryptology ePrint Archive: Report 2017/602. Last revised June 25, 2017. URL: https://eprint.iacr.org/2017/602 (visited on 2019-02-10) (↑ p76, 82, 113, 123). [BGM2017] Sean Bowe, Ariel Gabizon, and Ian Miers. Scalable Multi-party Computation for zk-SNARK Parameters in the Random Beacon Model. Cryptology ePrint Archive: Report 2017/1050. Last revised November 5, 2017. URL: https://eprint.iacr.org/2017/1050 (visited on 2018-08-31) (↑ p76, 83, 113, 114). [BIP-11] Gavin Andresen. M-of-N Standard Transactions. Bitcoin Improvement Proposal 11. Created Oc- tober 18, 2011. URL: https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki (visited on 2020-07-13) (↑ p100). [BIP-13] Gavin Andresen. Address Format for pay-to-script-hash. Bitcoin Improvement Proposal 13. Created October 18, 2011. URL: https : / / github . com / bitcoin / bips / blob / master / bip - 0013.mediawiki (visited on 2020-07-13) (↑ p78, 100). [BIP-14] Amir Taaki and Patrick Strateman. Protocol Version and User Agent. Bitcoin Improvement Proposal 14. Created November 10, 2011. URL: https : / / github . com / bitcoin / bips / blob / master/bip-0014.mediawiki (visited on 2020-07-13) (↑ p100). [BIP-16] Gavin Andresen. Pay to Script Hash. Bitcoin Improvement Proposal 16. Created January 3, 2012. URL: https://github.com/bitcoin/bips/blob/master/bip- 0016.mediawiki (visited on 2020-07-13) (↑ p100). [BIP-30] Pieter Wuille. Duplicate transactions. Bitcoin Improvement Proposal 30. Created February 22, 2012. URL: https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki (visited on 2020-07-13) (↑ p100). [BIP-31] Mike Hearn. Pong message. Bitcoin Improvement Proposal 31. Created April 11, 2012. URL: https: //github.com/bitcoin/bips/blob/master/bip- 0031.mediawiki (visited on 2020-07-13) (↑ p100). [BIP-32] Pieter Wuille. Hierarchical Deterministic Wallets. Bitcoin Improvement Proposal 32. Created February 11, 2012. Last updated January 15, 2014. URL: https://github.com/bitcoin/bips/ blob/master/bip-0032.mediawiki (visited on 2020-07-13) (↑ p79, 110). [BIP-34] Gavin Andresen. Block v2, Height in Coinbase. Bitcoin Improvement Proposal 34. Created July 6, 2012. URL: https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki (visited on 2020-07-13) (↑ p86, 100, 124). [BIP-35] Jeff Garzik. mempool message. Bitcoin Improvement Proposal 35. Created August 16, 2012. URL: https://github.com/bitcoin/bips/blob/master/bip- 0035.mediawiki (visited on 2020-07-13) (↑ p100). [BIP-37] Mike Hearn and Matt Corallo. Connection Bloom filtering. Bitcoin Improvement Proposal 37. Created October 24, 2012. URL: https : / / github . com / bitcoin / bips / blob / master / bip - 0037.mediawiki (visited on 2020-07-13) (↑ p100). [BIP-61] Gavin Andresen. Reject P2P message. Bitcoin Improvement Proposal 61. Created June 18, 2014. URL: https://github.com/bitcoin/bips/blob/master/bip- 0061.mediawiki (visited on 2020-07-13) (↑ p100). [BIP-62] Pieter Wuille. Dealing with malleability. Bitcoin Improvement Proposal 62. Withdrawn Novem- ber 17, 2015. URL: https://github.com/bitcoin/bips/blob/master/bip- 0062.mediawiki (visited on 2020-07-13) (↑ p23). [BIP-65] Peter Todd. OP_CHECKLOCKTIMEVERIFY. Bitcoin Improvement Proposal 65. Created October 10, 2014. URL: https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki (visited on 2020-07-13) (↑ p100). 129

[BIP-66] Pieter Wuille. Strict DER signatures. Bitcoin Improvement Proposal 66. Created January 10, 2015. URL: https://github.com/bitcoin/bips/blob/master/bip- 0066.mediawiki (visited on 2020-07-13) (↑ p100). [BIP-68] Mark Friedenbach, BtcDrak, Nicolas Dorier, and kinoshitajona. Relative lock-time using consen- sus-enforced sequence numbers. Bitcoin Improvement Proposal 68. Last revised November 21, 2015. URL: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki (visited on 2020-07-13) (↑ p87). [BIP-111] Matt Corallo and Peter Todd. NODE_BLOOM service bit. Bitcoin Improvement Proposal 111. Created August 20, 2015. URL: https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki (visited on 2020-07-13) (↑ p100, 119). [Bitcoin-Base58] Base58Check encoding — Bitcoin Wiki. URL: https://en.bitcoin.it/wiki/Base58Check_ encoding (visited on 2020-07-13) (↑ p78, 79). [Bitcoin-Block] Block Headers — Bitcoin Developer Reference. URL: https : / / developer . bitcoin . org / reference/block_chain.html#block-headers (visited on 2020-07-13) (↑ p91, 92). [Bitcoin-CoinJoin] CoinJoin — Bitcoin Wiki. URL: https://en.bitcoin.it/wiki/CoinJoin (visited on 2020-07-13) (↑ p9). [Bitcoin-Format] Raw Transaction Format — Bitcoin Developer Reference. URL: https://developer.bitcoin. org/reference/transactions.html#raw-transaction-format (visited on 2020-07-13) (↑ p87). [Bitcoin-Multisig] Transactions: Multisig — Bitcoin Developer Guide. URL: https://developer.bitcoin.org/ devguide/transactions.html#multisig (visited on 2020-07-13) (↑ p97, 99). [Bitcoin-nBits] Target nBits — Bitcoin Developer Reference. URL: https://developer.bitcoin.org/reference/ block_chain.html#target-nbits (visited on 2020-07-13) (↑ p90, 94). [Bitcoin-P2PKH] Transactions: P2PKH Script Validation — Bitcoin Developer Guide. URL: https://developer. bitcoin.org/devguide/transactions.html#p2pkh-script-validation (visited on 2020-07- 13) (↑ p78). [Bitcoin-P2SH] Transactions: P2SH Scripts — Bitcoin Developer Guide. URL: https://developer.bitcoin.org/ devguide/transactions.html#pay-to-script-hash-p2sh (visited on 2020-07-13) (↑ p79, 99). [Bitcoin-Protocol] Protocol documentation — Bitcoin Wiki. URL: https : / / en . bitcoin . it / wiki / Protocol _ documentation (visited on 2020-07-13) (↑ p8). [Bitcoin-SigHash] Signature Hash Types — Bitcoin Developer Guide. URL: https://developer.bitcoin.org/ devguide/transactions.html#signature-hash-types (visited on 2020-07-13) (↑ p38). [BJLSY2015] Daniel Bernstein, Simon Josefsson, Tanja Lange, Peter Schwabe, and Bo-Yin Yang. EdDSA for more curves. Technical Report. July 4, 2015. URL: https://cr.yp.to/papers.html#eddsa (visited on 2018-01-22) (↑ p65, 74). [BK2016] Alex Biryukov and Dmitry Khovratovich. Equihash: Asymmetric Proof-of-Work Based on the Generalized Birthday Problem (full version). Cryptology ePrint Archive: Report 2015/946. Last revised October 27, 2016. URL: https://eprint.iacr.org/2015/946 (visited on 2016-10-30) (↑ p10, 92, 124). [BL-SafeCurves] Daniel Bernstein and Tanja Lange. SafeCurves: choosing safe curves for elliptic-curve cryptogra- phy. URL: https://safecurves.cr.yp.to (visited on 2018-01-29) (↑ p104, 132). [BL2017] Daniel Bernstein and Tanja Lange. Montgomery curves and the Montgomery ladder. Cryptology ePrint Archive: Report 2017/293. Received March 30, 2017. URL: https://eprint.iacr.org/ 2017/293 (visited on 2017-11-26) (↑ p73, 137, 143, 144). [BLS2002] Paulo Barreto, Ben Lynn, and Michael Scott. Constructing Elliptic Curves with Prescribed Em- bedding Degrees. Cryptology ePrint Archive: Report 2002/088. Last revised February 22, 2005. URL: https://eprint.iacr.org/2002/088 (visited on 2018-04-20) (↑ p71, 119). 130

[BN2005] Paulo Barreto and Michael Naehrig. Pairing-Friendly Elliptic Curves of Prime Order. Cryptology ePrint Archive: Report 2005/133. Last revised February 28, 2006. URL: https://eprint.iacr. org/2005/133 (visited on 2018-04-20) (↑ p70, 119). [BN2007] Mihir Bellare and Chanathip Namprempre. Authenticated Encryption: Relations among notions and analysis of the generic composition paradigm. Cryptology ePrint Archive: Report 2000/025. Last revised July 14, 2007. URL: https://eprint.iacr.org/2000/025 (visited on 2016-09-02) (↑ p21). [Bowe-bellman] Sean Bowe. bellman: zk-SNARK library. URL: https://github.com/ebfull/bellman (visited on 2018-04-03) (↑ p76, 83). [Bowe2017] Sean Bowe. ebfull/pairing source code, BLS12-381 – README.md as of commit e726600. URL: https://github.com/ebfull/pairing/tree/e72660056e00c93d6b054dfb08ff34a1c67cb799/ src/bls12_381 (visited on 2017-07-16) (↑ p71). [Bowe2018] Sean Bowe. Random Beacon. March 22, 2018. URL: https://github.com/ZcashFoundation/ powersoftau-attestations/tree/master/0088 (visited on 2018-04-08) (↑ p83). [Carroll1876] Lewis Carroll. The Hunting of the Snark. With illustrations by Henry Holiday. MacMillan and Co. London. March 29, 1876. URL: https://www.gutenberg.org/files/29888/29888-h/29888- h.htm (visited on 2018-05-23) (↑ p73, 111). [Carroll1902] Lewis Carroll. Through the Looking-Glass, and What Alice Found There (1902 edition). Illustrated by Peter Newell and Robert Murray Wright. Harper and Brothers Publishers. New York. October 1902. URL: https://archive.org/details/throughlookinggl00carr4 (visited on 2018-06-20) (↑ p107, 117). [CDvdG1987] David Chaum, Ivan Damgård, and Jeroen van de Graaf. “Multiparty computations ensuring privacy of each party’s input and correctness of the result”. In: Advances in Cryptology - CRYPTO ’87. Proceedings of the 14th Annual International Cryptology Conference (Santa Barbara, California, USA, August 16–20, 1987). Ed. by Carl Pomerance. Vol. 293. Lecture Notes in Computer Science. Springer, January 1988, pages 87–119. ISBN: 978-3-540-48184-3. DOI: 10 . 1007 / 3 - 540- 48184- 2_7. URL: https://www.researchgate.net/profile/Jeroen_Van_de_Graaf/ publication/242379939_Multiparty_computations_ensuring_secrecy_of_each_party% 27s_input_and_correctness_of_the_output (visited on 2018-03-01) (↑ p58). [CVE-2019-7167] Common Vulnerabilities and Exposures. CVE-2019-7167. URL: https://cve.mitre.org/cgi- bin/cvename.cgi?name=CVE-2019-7167 (visited on 2019-02-05) (↑ p76). [CvHP1991] David Chaum, Eugène van Heijst, and Birgit Pfitzmann. Cryptographically Strong Undeniable Signatures, Unconditionally Secure for the Signer. February 1991. URL: http : / / citeseerx . ist.psu.edu/viewdoc/summary?doi=10.1.1.34.8570 (visited on 2018-02-17). An extended abstract appeared in Advances in Cryptology - CRYPTO ’91: Proceedings of the 11th Annual International Cryptology Conference (Santa Barbara, California, USA, August 11–15, 1991); Ed. by Joan Feigenbaum; Vol. 576, Lecture Notes in Computer Science, pages 470–484; Springer, 1992; ISBN 978-3-540-55188-1. (↑ p58, 147). [Dalek-notes] Cathie Yun, Henry de Valence, Oleg Andreev, and Dimitris Apostolou. ristretto_bulletproofs notes. URL: https://doc-internal.dalek.rs/ristretto_bulletproofs/notes/index.html (visited on 2018-08-17) (↑ p41, 114). [deRooij1995] Peter de Rooij. “Efficient exponentiation using precomputation and vector addition chains”. In: Advances in Cryptology - EUROCRYPT ’94. Proceedings, Workshop on the Theory and Application of Cryptographic Techniques (Perugia, Italy, May 9–12, 1994). Ed. by Alfredo De Santis. Vol. 950. Lecture Notes in Computer Science. Springer, pages 389–399. ISBN: 978-3-540-60176-0. DOI: 10.1007/BFb0053453. URL: https://link.springer.com/chapter/10.1007/BFb0053453 (visited on 2018-07-27) (↑ p158, 159). [DGKM2011] Dana Dachman-Soled, Rosario Gennaro, Hugo Krawczyk, and Tal Malkin. Computational Ex- tractors and Pseudorandomness. Cryptology ePrint Archive: Report 2011/708. December 28, 2011. URL: https://eprint.iacr.org/2011/708 (visited on 2016-09-02) (↑ p104). 131

[DigiByte-PoW] DigiByte Core Developers. DigiSpeed 4.0.0 source code, functions GetNextWorkRequiredV3/4 in src/main.cpp as of commit 178e134. URL: https://github.com/digibyte/digibyte/blob/ 178e1348a67d9624db328062397fde0de03fe388/src/main.cpp#L1587 (visited on 2017-01-20) (↑ p93). [DS2016] David Derler and Daniel Slamanig. Key-Homomorphic Signatures and Applications to Multiparty Signatures and Non-Interactive Zero-Knowledge. Cryptology ePrint Archive: Report 2016/792. Last revised February 6, 2017. URL: https://eprint.iacr.org/2016/792 (visited on 2018-04-09) (↑ p24). [DSDCOPS2001] Alfredo De Santis, Giovanni Di Crescenzo, Rafail Ostrovsky, Guiseppe Persiano, and Amit Sa- hai. “Robust Non-Interactive Zero Knowledge”. In: Advances in Cryptology - CRYPTO 2001. Proceedings of the 21st Annual International Cryptology Conference (Santa Barbara, Califor- nia, USA, August 19–23, 2001). Ed. by Joe Kilian. Vol. 2139. Lecture Notes in Computer Science. Springer, 2001, pages 566–598. ISBN: 978-3-540-42456-7. DOI: 10.1007/3-540-44647-8_33. URL: https://www.iacr.org/archive/crypto2001/21390566.pdf (visited on 2018-05-28) (↑ p28, 37). [ECCZF2019] Electric Coin Company and Zcash Foundation. Zcash Trademark Donation and License Agree- ment. November 6, 2019. URL: https://www.zfnd.org/about/contracts/2019_ECC_ZFND_TM_ agreement.pdf (visited on 2020-07-05) (↑ p18). [ElGamal1985] Taher ElGamal. “A public key cryptosystem and a signature scheme based on discrete logarithms”. In: IEEE Transactions on Information Theory 31.4 (July 1985), pages 469–472. ISSN: 0018-9448. DOI: 10.1109/TIT.1985.1057074. URL: https://people.csail.mit.edu/alinush/6.857- spring-2015/papers/elgamal.pdf (visited on 2018-08-17) (↑ p57). [EWD-831] Edsger W. Dijkstra. Why numbering should start at zero. Manuscript. August 11, 1982. URL: https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html (visited on 2016-08-09) (↑ p10). [FKMSSS2016] Nils Fleischhacker, Johannes Krupp, Giulio Malavolta, Jonas Schneider, Dominique Schröder, and Mark Simkin. Efficient Unlinkable Sanitizable Signatures from Signatures with Re- Randomizable Keys. Cryptology ePrint Archive: Report 2012/159. Last revised February 11, 2016. URL: https://eprint.iacr.org/2015/395 (visited on 2018-03-03). An extended abstract appeared in Public Key Cryptography – PKC 2016: 19th IACR International Conference on Practice and Theory in Public-Key Cryptography (Taipei, Taiwan, March 6–9, 2016), Proceedings, Part 1; Ed. by Chen-Mou Cheng, Kai-Min Chung, Giuseppe Persiano, and Bo-Yin Yang; Vol. 9614, Lecture Notes in Computer Science, pages 301–330; Springer, 2016; ISBN 978-3-662-49384-7. (↑ p23, 24, 65). [Gabizon2019] Ariel Gabizon. On the security of the BCTV Pinocchio zk-SNARK variant. Draft. February 5, 2019. URL: https : / / github . com / arielgabizon / bctv / blob / master / bctv . pdf (visited on 2019-02-07) (↑ p75, 76, 106, 113). [GGM2016] Christina Garman, Matthew Green, and Ian Miers. Accountable Privacy for Decentralized Anonymous Payments. Cryptology ePrint Archive: Report 2016/061. Last revised January 24, 2016. URL: https://eprint.iacr.org/2016/061 (visited on 2016-09-02) (↑ p101). [Groth2016] Jens Groth. On the Size of Pairing-based Non-interactive Arguments. Cryptology ePrint Archive: Report 2016/260. Last revised May 31, 2016. URL: https://eprint.iacr.org/2016/260 (visited on 2017-08-03) (↑ p76, 77, 113, 158). [Hamdon2018] Elise Hamdon. Sapling Activation Complete. Electric Coin Company blog. June 28, 2018. URL: https://electriccoin.co/blog/sapling- activation- complete/ (visited on 2021-01-10) (↑ p83). [Hopwood2018] Daira Hopwood. GitHub repository ‘daira/jubjub’: Supporting evidence for security of the Jubjub curve to be used in Zcash. URL: https://github.com/daira/jubjub (visited on 2018-02-18). Based on code written for SafeCurves [BL-SafeCurves] by Daniel Bernstein and Tanja Lange. (↑ p104). 132

[HW2016] Taylor Hornby and Zooko Wilcox. Fixing Vulnerabilities in the Zcash Protocol. Electric Coin Company blog. April 26, 2016. URL: https://electriccoin.co/blog/fixing-zcash-vulns/ (visited on 2019-08-27). Updated December 26, 2017. (↑ p102). [IEEE2000] IEEE Computer Society. IEEE Std 1363-2000: Standard Specifications for Public-Key Cryptog- raphy. IEEE, August 29, 2000. DOI: 10.1109/IEEESTD.2000.92292. URL: http://ieeexplore. ieee.org/servlet/opac?punumber=7168 (visited on 2016-08-03) (↑ p71). [IEEE2004] IEEE Computer Society. IEEE Std 1363a-2004: Standard Specifications for Public-Key Cryptogra- phy – Amendment 1: Additional Techniques. IEEE, September 2, 2004. DOI: 10.1109/IEEESTD. 2004.94612. URL: http://ieeexplore.ieee.org/servlet/opac?punumber=9276 (visited on 2016-08-03) (↑ p71, 104, 106). [Jedusor2016] Tom Elvis Jedusor. Mimblewimble. July 19, 2016. URL: http://diyhpl.us/~bryan/papers2/ bitcoin/mimblewimble.txt (visited on 2018-04-03) (↑ p41). [KvE2013] Kaa1el and Hagen von Eitzen. If a group 𝐺 has odd order, then the square function is injective (answer). Mathematics Stack Exchange. URL: https://math.stackexchange.com/a/522277/ 185422 (visited on 2018-02-08). Version: 2013-10-11. (↑ p74). [KYMM2018] George Kappos, Haaroon Yousaf, Mary Maller, and Sarah Meiklejohn. An Empirical Analysis of Anonymity in Zcash. Preprint, to be presented at the 27th Usenix Security Syposium (Baltimore, Maryland, USA, August 15–17, 2018). May 8, 2018. URL: https://smeiklej.com/files/usenix18. pdf (visited on 2018-06-05) (↑ p9). [LG2004] Eddie Lenihan and Carolyn Eve Green. Meeting the Other Crowd: The Fairy Stories of Hidden Ireland. TarcherPerigee, February 2004, pages 109–110. ISBN: 1-58542-206-1 (↑ p101). [libsodium] libsodium documentation. URL: https://libsodium.org/ (visited on 2020-03-02) (↑ p65). [libsodium-Seal] Sealed boxes — libsodium. URL: https : / / download . libsodium . org / doc / public - key _ cryptography/sealed_boxes.html (visited on 2016-02-01) (↑ p104). [LM2017] Philip Lafrance and Alfred Menezes. On the security of the WOTS-PRF signature scheme. Cryp- tology ePrint Archive: Report 2017/938. Last revised February 5, 2018. URL: https://eprint. iacr.org/2017/938 (visited on 2018-04-16) (↑ p22). [MAEÁ2010] V. Gayoso Martínez, F. Hernández Alvarez, L. Hernández Encinas, and C. Sánchez Ávila. “A Comparison of the Standardized Versions of ECIES”. In: Proceedings of Sixth International Conference on Information Assurance and Security (Atlanta, Georgia, USA, August 23–25, 2010). IEEE, 2010, pages 1–4. ISBN: 978-1-4244-7407-3. DOI: 10.1109/ISIAS.2010.5604194. URL: https://digital.csic.es/bitstream/10261/32674/1/Gayoso_A%20Comparison%20of% 20the%20Standardized%20Versions%20of%20ECIES.pdf (visited on 2016-08-14) (↑ p104). [Maller2018] Mary Maller. A Proof of Security for the Sapling Generation of zk-SNARK Parameters in the Generic Group Model. November 16, 2018. URL: https : / / github . com / zcash / sapling - security- analysis/blob/master/MaryMallerUpdated.pdf (visited on 2018-02-10) (↑ p 76, 113). [Nakamoto2008] Satoshi Nakamoto. Bitcoin: A Peer-to-Peer Electronic Cash System. October 31, 2008. URL: https://bitcoin.org/en/bitcoin-paper (visited on 2016-08-14) (↑ p7). [NIST2015] NIST. FIPS 180-4: Secure Hash Standard (SHS). August 2015. DOI: 10.6028/NIST.FIPS.180-4. URL: https://csrc.nist.gov/publications/detail/fips/180/4/final (visited on 2018-02- 14) (↑ p55, 79). [Parno2015] Bryan Parno. A Note on the Unsoundness of vnTinyRAM’s SNARK. Cryptology ePrint Archive: Report 2015/437. Received May 6, 2015. URL: https://eprint.iacr.org/2015/437 (visited on 2019-02-08) (↑ p75, 76, 106, 113). [Peterson2017] Paige Peterson. Transaction Linkability. Electric Coin Company blog. January 25, 2017. URL: https://electriccoin.co/blog/transaction-linkability/ (visited on 2019-08-27) (↑ p 9, 119). 133

[PHGR2013] Bryan Parno, Jon Howell, Craig Gentry, and Mariana Raykova. Pinocchio: Nearly Practical Verifi- able Computation. Cryptology ePrint Archive: Report 2013/279. Last revised May 13, 2013. URL: https://eprint.iacr.org/2013/279 (visited on 2016-08-31) (↑ p75). [Quesnelle2017] Jeffrey Quesnelle. On the linkability of Zcash transactions. arXiv:1712.01210 [cs.CR]. December 4, 2017. URL: https://arxiv.org/abs/1712.01210 (visited on 2018-04-15) (↑ p9, 119). [RFC-2119] Scott Bradner. Request for Comments 7693: Key words for use in RFCs to Indicate Requirement Levels. Internet Engineering Task Force (IETF). March 1997. URL: https://www.rfc-editor.org/ rfc/rfc2119.html (visited on 2016-09-14) (↑ p7). [RFC-7539] Yoav Nir and Adam Langley. Request for Comments 7539: ChaCha20 and Poly1305 for IETF Protocols. Internet Research Task Force (IRTF). May 2015. URL: https://www.rfc-editor.org/ rfc/rfc7539.html (visited on 2016-09-02). As modified by verified errata at https://www.rfc- editor.org/errata_search.php?rfc=7539 (visited on 2016-09-02). (↑ p62). [RFC-8032] Simon Josefsson and Ilari Liusvaara. Request for Comments 8032: Edwards-Curve Digital Sig- nature Algorithm (EdDSA). Internet Engineering Task Force (IETF). January 2017. URL: https: //www.rfc- editor.org/rfc/rfc8032.html (visited on 2020-07-06). As modified by errata at https://www.rfc- editor.org/errata_search.php?rfc=8032 (visited on 2020-07-06). (↑ p64). [RIPEMD160] Hans Dobbertin, Antoon Bosselaers, and Bart Preneel. RIPEMD-160, a strengthened version of RIPEMD. URL: http://homes.esat.kuleuven.be/~bosselae/ripemd160.html (visited on 2016-09-24) (↑ p79). [ST1999] Tomas Sander and Amnon Ta–Shma. “Auditable, Anonymous Electronic Cash”. In: Advances in Cryptology - CRYPTO ’99. Proceedings of the 19th Annual International Cryptology Conference (Santa Barbara, California, USA, August 15–19, 1999). Ed. by Michael Wiener. Vol. 1666. Lecture Notes in Computer Science. Springer, 1999, pages 555–572. ISBN: 978-3-540-66347-8. DOI: 10.1007/3-540-48405-1_35. URL: https://link.springer.com/content/pdf/10.1007/3- 540-48405-1_35.pdf (visited on 2018-06-05) (↑ p107, 116). [SVPBABW2012] Srinath Setty, Victor Vu, Nikhil Panpalia, Benjamin Braun, Muqeet Ali, Andrew J. Blumberg, and Michael Walfish. Taking proof-based verified computation a few steps closer to practicality (extended version). Cryptology ePrint Archive: Report 2012/598. Last revised February 28, 2013. URL: https://eprint.iacr.org/2012/598.pdf (visited on 2018-04-25) (↑ p139). [SWB2019] Josh Swihart, Benjamin Winston, and Sean Bowe. Zcash Counterfeiting Vulnerability Successfully Remediated. February 5, 2019. URL: https://electriccoin.co/blog/zcash-counterfeiting- vulnerability-successfully-remediated/ (visited on 2019-08-27) (↑ p76, 113). [Swihart2018] Josh Swihart. Overwinter Activated Successfully. Electric Coin Company blog. June 26, 2018. URL: https://electriccoin.co/blog/overwinter- activated- successfully/ (visited on 2021-01-10) (↑ p83). [Unicode] The Unicode Consortium. The Unicode Standard. The Unicode Consortium, 2016. URL: http: //www.unicode.org/versions/latest/ (visited on 2016-08-31) (↑ p77). [vanSaberh2014] Nicolas van Saberhagen. CryptoNote v 2.0. Date disputed. URL: https://cryptonote.org/ whitepaper.pdf (visited on 2016-08-17) (↑ p9). [Vercauter2009] Frederik Vercauteren. Optimal pairings. Cryptology ePrint Archive: Report 2008/096. Last revised March 7, 2008. URL: https://eprint.iacr.org/2008/096 (visited on 2018-04-06). A version of this paper appeared in IEEE Transactions of Information Theory, Vol. 56, pages 455–461; IEEE, 2009. (↑ p70, 119). [WCBTV2015] Zooko Wilcox, Alessandro Chiesa, Eli Ben-Sasson, Eran Tromer, and Madars Virza. A Bug in libsnark. Least Authority blog. May 16, 2015. URL: https://leastauthority.com/blog/a_bug_ in_libsnark/ (visited on 2019-08-27) (↑ p75, 137). 134

[WG2016] Zooko Wilcox and Jack Grigg. Why Equihash? Electric Coin Company blog. April 15, 2016. URL: https://electriccoin.co/blog/why-equihash/ (visited on 2019-08-27). Updated August 21, 2019. (↑ p92). [Zaverucha2012] Gregory M. Zaverucha. Hybrid Encryption in the Multi-User Setting. Cryptology ePrint Archive: Report 2012/159. Received March 20, 2012. URL: https://eprint.iacr.org/2012/159 (visited on 2016-09-24) (↑ p105). [Zcash-Blossom] Electric Coin Company. Blossom. December 11, 2019. URL: https://z.cash/upgrade/blossom/ (visited on 2021-01-10) (↑ p83). [Zcash-Canopy] Electric Coin Company. Canopy. November 18, 2020. URL: https://z.cash/upgrade/canopy/ (visited on 2021-01-10) (↑ p83). [Zcash-Heartwd] Electric Coin Company. Heartwood. July 16, 2020. URL: https://z.cash/upgrade/heartwood/ (visited on 2021-01-10) (↑ p83). [Zcash-Issue2113] Simon Liu. GitHub repository ‘ zcash/zcash’ : Issue 2113. URL: https://github.com/zcash/ zcash/issues/2113 (visited on 2017-02-20) (↑ p97, 123). [Zcash-libsnark] libsnark: C++ library for zkSNARK proofs (Zcash fork). URL: https://github.com/zcash/zcash/ tree/master/src/snark (visited on 2018-02-04) (↑ p75). [ZIP-32] Jack Grigg and Daira Hopwood. Shielded Hierarchical Deterministic Wallets. Zcash Improvement Proposal 32. URL: https://zips.z.cash/zip-0032 (visited on 2019-08-28) (↑ p12, 20, 31, 34, 48, 58, 67, 110, 111, 117). [ZIP-76] Jack Grigg and Daira Hopwood. Transaction Signature Validation before Overwinter. Zcash Improvement Proposal 76 (in progress). (↑ p38, 100). [ZIP-143] Jack Grigg and Daira Hopwood. Transaction Signature Validation for Overwinter. Zcash Improve- ment Proposal 143. Created December 27, 2017. URL: https://zips.z.cash/zip-0143 (visited on 2019-08-28) (↑ p38, 55, 83). [ZIP-173] Daira Hopwood. Bech32 Format. Zcash Improvement Proposal 173. Created June 13, 2018. URL: https://zips.z.cash/zip-0173 (visited on 2020-06-01) (↑ p78, 80, 109). [ZIP-200] Jack Grigg. Network Upgrade Mechanism. Zcash Improvement Proposal 200. Created January 8, 2018. URL: https://zips.z.cash/zip-0200 (visited on 2019-08-28) (↑ p83, 87). [ZIP-201] Simon Liu. Network Peer Management for Overwinter. Zcash Improvement Proposal 201. Cre- ated January 15, 2018. URL: https://zips.z.cash/zip-0201 (visited on 2019-08-28) (↑ p 83, 84). [ZIP-202] Simon Liu. Version 3 Transaction Format for Overwinter. Zcash Improvement Proposal 202. Created January 10, 2018. URL: https://zips.z.cash/zip-0202 (visited on 2019-08-28) (↑ p83). [ZIP-203] Jay Graber. Transaction Expiry. Zcash Improvement Proposal 203. Created January 9, 2018. URL: https://zips.z.cash/zip-0203 (visited on 2019-08-28) (↑ p83, 85). [ZIP-205] Daira Hopwood. Deployment of the Sapling Network Upgrade. Zcash Improvement Proposal 205. Created October 8, 2018. URL: https://zips.z.cash/zip-0205 (visited on 2019-08-28) (↑ p83, 94). [ZIP-206] Daira Hopwood. Deployment of the Blossom Network Upgrade. Zcash Improvement Proposal 206. Created July 29, 2019. URL: https://zips.z.cash/zip-0206 (visited on 2019-08-28) (↑ p38, 83, 111). [ZIP-207] Jack Grigg. Funding Streams. Zcash Improvement Proposal 207. Created January 4, 2019. URL: https://zips.z.cash/zip-0207 (visited on 2019-08-28) (↑ p83, 108, 110). [ZIP-208] Simon Liu and Daira Hopwood. Shorter Block Target Spacing. Zcash Improvement Proposal 208. Created January 10, 2019. URL: https://zips.z.cash/zip-0208 (visited on 2019-08-28) (↑ p83, 94, 112). 135

[ZIP-209] Sean Bowe. Prohibit Negative Shielded Value Pool Balances. Zcash Improvement Proposal 209. Created February 25, 2019. URL: https://zips.z.cash/zip-0209 (visited on 2020-11-05) (↑ p39, 107). [ZIP-211] Daira Hopwood. Disabling Addition of New Value to the Sprout Value Pool. Zcash Improvement Proposal 211. Created March 29, 2019. URL: https : / / zips . z . cash / zip - 0211 (visited on 2020-06-01) (↑ p34, 83, 108, 110). [ZIP-212] Sean Bowe. Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext. Zcash Improvement Proposal 212. Created March 31, 2019. URL: https://zips.z.cash/zip- 0212 (visited on 2020-06-01) (↑ p83, 87, 109, 110). [ZIP-213] Jack Grigg. Shielded Coinbase. Zcash Improvement Proposal 213. Created March 30, 2019. URL: https://zips.z.cash/zip-0213 (visited on 2020-03-20) (↑ p83, 87, 99). [ZIP-214] Daira Hopwood. Consensus rules for a Zcash Development Fund. Zcash Improvement Proposal 214. Created February 28, 2020. URL: https://zips.z.cash/zip-0214 (visited on 2020-03-24) (↑ p83, 99, 108, 110). [ZIP-215] Henry de Valance. Explicitly Defining and Modifying Ed25519 Validation Rules. Zcash Improve- ment Proposal 215. Created April 27, 2020. URL: https://zips.z.cash/zip-0215 (visited on 2020-05-27) (↑ p83, 109, 110, 160). [ZIP-221] Jack Grigg. FlyClient - Consensus-Layer Changes. Zcash Improvement Proposal 221. Created March 30, 2019. URL: https://zips.z.cash/zip-0221 (visited on 2020-03-19) (↑ p83, 91). [ZIP-243] Jack Grigg and Daira Hopwood. Transaction Signature Validation for Sapling. Zcash Improvement Proposal 243. Created April 10, 2018. URL: https://zips.z.cash/zip-0243 (visited on 2019-08- 28) (↑ p38, 40, 42, 55, 83). [ZIP-250] Daira Hopwood. Deployment of the Heartwood Network Upgrade. Zcash Improvement Proposal 250. Created February 28, 2020. URL: https://zips.z.cash/zip-0250 (visited on 2020-03-20) (↑ p38, 83). [ZIP-251] Daira Hopwood. Deployment of the Canopy Network Upgrade. Zcash Improvement Proposal 251. Created February 28, 2020. URL: https://zips.z.cash/zip-0251 (visited on 2020-03-24) (↑ p38, 83, 110). [ZIP-302] Jay Graber and Jack Grigg. Standardized Memo Field Format. Zcash Improvement Proposal 302 (in progress). URL: https://github.com/zcash/zips/pull/105 (visited on 2020-02-13) (↑ p77, 110). 136

Appendices A Circuit Design A.1 Quadratic Constraint Programs Sapling defines two circuits, Spend and Output, each implementing an abstract statement described in § 4.15.2 ‘Spend Statement (Sapling)’ on p. 44 and § 4.15.3 ‘Output Statement (Sapling)’ on p. 45 respectively. It also adds a Groth16 circuit for the JoinSplit statement described in § 4.15.1 ‘JoinSplit Statement (Sprout)’ on p. 43. At the next lower level, each circuit is defined in terms of a quadratic constraint program (specifying a Rank 1 Constraint System), as detailed in this section. In the BCTV14 or Groth16 proving systems, this program is translated to a Quadratic Arithmetic Program [BCTV2014a, section 2.3] [WCBTV2015]. The circuit descriptions given here are necessary to compute witness elements for each circuit, as well as the proving and verifying keys. Let F𝑟 S be the finite field over which Jubjub is defined, as given in § 5.4.8.3 ‘Jubjub’ on p. 73. A quadratic constraint program consists of a set of constraints over variables in F𝑟 S , each of the form: (︀ )︀ (︀ )︀ (︀ )︀ 𝐴 𝐵 = 𝐶 where 𝐴 , 𝐵 , and 𝐶 are linear combinations of variables and constants in F𝑟 S . (︀ )︀ (︀ )︀ (︀ )︀ Here and · both represent multiplication in the field F𝑟 S , but we use for multiplications corresponding to gates of the circuit, and · for multiplications by constants in the terms of a linear combination. should not be confused with × which is defined as cartesian product in § 2 ‘Notation’ on p. 9. A.2 Elliptic curve background The Sapling circuits make use of a complete twisted Edwards elliptic curve (“ctEdwards curve”) Jubjub, defined in § 5.4.8.3 ‘Jubjub’ on p. 73, and also a Montgomery elliptic curve M that is birationally equivalent to Jubjub. Following the notation in [BL2017] we use (𝑢, v) for affine coordinates on the ctEdwards curve, and (𝑥, 𝑦) for affine coordinates on the Montgomery curve. A point 𝑃 is normally represented by two F𝑟 S variables, which we name as (𝑃 𝑢 , 𝑃 v ) for an affine-ctEdwards point, for instance. The implementations of scalar multiplication require the scalar to be represented as a bit sequence. We there- fore allow the notation [𝑘⋆] 𝑃 meaning [LEBS2IPlength(𝑘⋆) (𝑘⋆)] 𝑃 . There will be no ambiguity because variables representing bit sequences are named with a ⋆ suffix. The Montgomery curve M has parameters 𝐴 M = 40962 and 𝐵 M = 1. We use an affine representation of this curve with the formula: 𝐵 M ·𝑦 2 = 𝑥3 + 𝐴 M ·𝑥2 + 𝑥 Usually, elliptic curve arithmetic over prime fields is implemented using some form of projective coordinates, in order to reduce the number of expensive inversions required. In the circuit, it turns out that a division can be implemented at the same cost as a multiplication, i.e. one constraint. Therefore it is beneficial to use affine coordinates for both curves. We define the following types representing affine-ctEdwards and affine-Montgomery coordinates respectively: AffineCtEdwardsJubjub := (𝑢 F𝑟 S ) × (v F𝑟 S ) : 𝑎J ·𝑢2 + v2 = 1 + 𝑑J ·𝑢2 ·v2 ◦ ◦ ◦ ◦ AffineMontJubjub := (𝑥 F𝑟 S ) × (𝑦 F𝑟 S ) : 𝐵M ·𝑦 2 = 𝑥3 + 𝐴 M ·𝑥2 + 𝑥 ◦ ◦ ◦ ◦ 137

We also define a type representing compressed, not necessarily valid, ctEdwards coordinates: 𝑢 B) × (v F𝑟 S ) CompressedCtEdwardsJubjub := (˜ ◦ ◦ ◦ ◦ See § 5.4.8.3 ‘Jubjub’ on p. 73 for how this type is represented as a byte sequence in external encodings. We use affine-Montgomery arithmetic in parts of the circuit because it is more efficient, in terms of the number of constraints, than affine-ctEdwards arithmetic. An important consideration when using Montgomery arithmetic is that the addition formula is not complete, that is, there are cases where it produces the wrong answer. We must ensure that these cases do not arise. We will need the theorem below about 𝑦-coordinates of points on Montgomery curves. Fact: 𝐴 M 2 − 4 is a nonsquare in F𝑟 S . Theorem A.2.1. (0, 0) is the only point with 𝑦 = 0 on certain Montgomery curves. Let 𝑃 = (𝑥, 𝑦) be a point other than (0, 0) on a Montgomery curve 𝐸Mont(𝐴,𝐵) over F𝑟 , such that 𝐴2 − 4 is a nonsquare in F𝑟 . Then 𝑦 ̸= 0. Proof. Substituting 𝑦 = 0 into the Montgomery curve equation gives 0 = 𝑥3 + 𝐴 · 𝑥2 + 𝑥 = 𝑥 · (𝑥2 + 𝐴 · 𝑥 + 1). So either 𝑥 = 0 or 𝑥2 + 𝐴 · 𝑥 + 1 = 0. Since 𝑃 ̸= (0, 0), the case 𝑥 = 0 is excluded. In the other case, complete the square for 𝑥2 + 𝐴 · 𝑥 + 1 = 0 to give the equivalent (2 · 𝑥 + 𝐴)2 = 𝐴2 − 4. The left-hand side is a square, so if the right-hand side is a nonsquare, then there are no solutions for 𝑥. A.3 Circuit Components Each of the following sections describes how to implement a particular component of the circuit, and counts the number of constraints required. Some components make use of others; the order of presentation is “bottom-up”. It is important for security to ensure that variables intended to be of boolean type are boolean-constrained; and for efficiency that they are boolean-constrained only once. We explicitly state for the boolean inputs and outputs of each component whether they are boolean-constrained by the component, or are assumed to have been boolean-constrained separately. Affine coordinates for elliptic curve points are assumed to represent points on the relevant curve, unless otherwise specified. In this section, variables have type F𝑟 S unless otherwise specified. In contrast to most of this document, we use zero-based indexing in order to more closely match the implementation. A.3.1 Operations on individual bits A.3.1.1 Boolean constraints A boolean constraint 𝑏 ∈ B can be implemented as: (︀ )︀ (︀ )︀ (︀ )︀ 1−𝑏 𝑏 = 0 138

A.3.1.2 Conditional equality The constraint “either 𝑎 = 0 or 𝑏 = 𝑐” can be implemented as: (︀ )︀ (︀ )︀ (︀ )︀ 𝑎 𝑏−𝑐 = 0 A.3.1.3 Selection constraints A selection constraint (𝑏 ? 𝑥 : 𝑦) = 𝑧, where 𝑏 B has been boolean-constrained, can be implemented as: ◦ ◦ (︀ )︀ (︀ )︀ (︀ )︀ 𝑏 𝑦−𝑥 = 𝑦−𝑧 A.3.1.4 Nonzero constraints Since only nonzero elements of F𝑟 S have a multiplicative inverse, the assertion 𝑎 ̸= 0 can be implemented by witnessing the inverse, 𝑎inv = 𝑎−1 (mod 𝑟S ): (︀ )︀ (︀ )︀ (︀ )︀ 𝑎inv 𝑎 = 1 This technique comes from [SVPBABW2012, Appendix D.1]. Non-normative note: A global optimization allows to use a single inverse computation outside the circuit for any number of nonzero constraints. Suppose that we have 𝑛 variables (or linear combinations) that are supposed ∏︀𝑛−1 to be nonzero: 𝑎0 .. 𝑛−1 . Multiply these together (using 𝑛−1 constraints) to give 𝑎* = 𝑖=0 𝑎𝑖 ; then, constrain 𝑎* to be nonzero. This works because the product 𝑎* is nonzero if and only if all of 𝑎0 .. 𝑛−1 are nonzero. However, the Sapling circuit does not use this optimization. A.3.1.5 Exclusive-or constraints An exclusive-or operation 𝑎 ⊕ 𝑏 = 𝑐, where 𝑎, 𝑏 B are already boolean-constrained, can be implemented in one ◦ ◦ constraint as: (︀ )︀ (︀ )︀ (︀ )︀ 2·𝑎 𝑏 = 𝑎+𝑏−𝑐 This automatically boolean-constrains 𝑐. Its correctness can be seen by checking the truth table of (𝑎, 𝑏). A.3.2 Operations on multiple bits A.3.2.1 [Un]packing modulo 𝑟S Let 𝑛 N+ be a constant. The operation of converting a field element, 𝑎 F𝑟 S , to a sequence of boolean variables ◦ ◦ ◦ ◦ ∑︀𝑛−1 𝑏0 .. 𝑛−1 B[𝑛] such that 𝑎 = ◦ ◦ 𝑖=0 𝑏𝑖 · 2𝑖 (mod 𝑟S ), is called “unpacking ”. The inverse operation is called “packing ”. In the quadratic constraint program these are the same operation (but see the note about canonical representation below). We assume that the variables 𝑏0 .. 𝑛−1 are boolean-constrained separately. (︃ 𝑛−1 )︃ (︃ 𝑛−1 )︃ ∑︁ ∑︁ We have 𝑎 mod 𝑟S = 𝑏𝑖 · 2𝑖 mod 𝑟S = 𝑏𝑖 · (2𝑖 mod 𝑟S ) mod 𝑟S . 𝑖=0 𝑖=0 139

This can be implemented in one constraint: (︃ 𝑛−1 )︃ ∑︁ 𝑖 (︀ )︀ (︀ )︀ 𝑏𝑖 · (2 mod 𝑟S ) 1 = 𝑎 𝑖=0 Notes: • The bit length 𝑛 is not limited by the field element size. • Since the constraint has only a trivial multiplication, it is possible to eliminate it by merging it into the boolean constraint of one of the output bits, expressing that bit as a linear combination of the others and 𝑎. However, this optimization requires substitutions that would interfere with the modularity of the circuit implementation (for a saving of only one constraint per unpacking operation), and so we do not use it for the Sapling circuit. • In the case 𝑛 = 255, for 𝑎 < 2255 − 𝑟S there are two possible representations of 𝑎 F𝑟 S as a sequence of 255 ◦ ◦ bits, corresponding to I2LEBSP255 (𝑎) and I2LEBSP255 (𝑎 + 𝑟S ). This is a potential hazard, but it may or may not be necessary to force use of the canonical representation I2LEBSP255 (𝑎), depending on the context in which the [un]packing operation is used. We therefore do not consider this to be part of the [un]packing operation itself. A.3.2.2 Range check ∑︀𝑛−1 Let 𝑛 ◦ ◦ N+ be a constant, and let 𝑎 = 𝑖=0 𝑎𝑖 · 2𝑖 ◦ ◦ N. Suppose we want to constrain 𝑎 ≤ 𝑐 for some constant ∑︀𝑛−1 𝑖 𝑐= 𝑖=0 𝑐𝑖 · 2 ◦ ◦ N. Without loss of generality we can assume that 𝑐𝑛−1 = 1, because if it were not then we would decrease 𝑛 accordingly. Note that since 𝑎 and 𝑐 are provided in binary representation, their bit length 𝑛 is not limited by the field element size. We do not assume that the bits 𝑎0 .. 𝑛−1 are already boolean-constrained. ∏︀𝑛−1 Define Π𝑚 = (𝑐 = 0 ∨ 𝑎𝑖 = 1) for 𝑚 ∈ {0 .. 𝑛 − 1}. Notice that for any 𝑚 < 𝑛 − 1 such that 𝑐𝑚 = 0, we have 𝑖=𝑚 𝑖 Π𝑚 = Π𝑚+1 , and so it is only necessary to allocate separate variables for the Π𝑚 such that 𝑚 < 𝑛 − 1 and 𝑐𝑚 = 1. Furthermore if 𝑐𝑛−2 .. 0 has 𝑡 > 0 trailing 1 bits, then we do not need to allocate variables for Π0 .. 𝑡−1 because those variables will not be used below. More explicitly: Let Π𝑛−1 = 𝑎𝑛−1 . For 𝑖 from 𝑛 − 2 down to 𝑡, • if 𝑐𝑖 = 0, then let Π𝑖 = Π𝑖+1 ; • if 𝑐𝑖 = 1, then constrain Π𝑖+1 𝑎𝑖 = Π𝑖 . (︀ )︀ (︀ )︀ (︀ )︀ Then we constrain the 𝑎𝑖 as follows: For 𝑖 from 𝑛 − 1 down to 0, • if 𝑐𝑖 = 0, constrain 1 − Π𝑖+1 − 𝑎𝑖 𝑎𝑖 = 0 ; (︀ )︀ (︀ )︀ (︀ )︀ • if 𝑐𝑖 = 1, boolean-constrain 𝑎𝑖 as in § A.3.1.1 ‘Boolean constraints’ on p. 138. Note that the constraints corresponding to zero bits of 𝑐 are in place of boolean constraints on bits of 𝑎𝑖 . This costs 𝑛 + 𝑘 constraints, where 𝑘 is the number of non-trailing 1 bits in 𝑐𝑛−2 .. 0 . 140

Theorem A.3.1. Correctness of a constraint system for range checks. ∑︀𝑛−1 ∑︀𝑛−1 Assume 𝑐0 .. 𝑛−1 B[𝑛] and 𝑐𝑛−1 = 1. Define 𝐴𝑚 := ◦ ◦ 𝑎 · 2𝑖 and 𝐶𝑚 := 𝑖=𝑚 𝑖 𝑐 · 2𝑖 . For any 𝑚 ∈ {0 .. 𝑛 − 1}, 𝑖=𝑚 𝑖 𝐴𝑚 ≤ 𝐶𝑚 iff the restriction of the above constraint system to 𝑖 ∈ {𝑚 .. 𝑛 − 1} is satisfied. Furthermore the system at least boolean-constrains 𝑎0 .. 𝑛−1 . Proof. For 𝑖 ∈ {0 .. 𝑛 − 1} such that 𝑐𝑖 = 1, the corresponding 𝑎𝑖 are unconditionally boolean-constrained. This implies that the )︀ system (︀ )︀ constrains Π𝑖 ∈ B for all 𝑖 ∈ {0 .. 𝑛 − 1}. For 𝑖 ∈ {0 .. 𝑛 − 1} such that 𝑐𝑖 = 0, the constraint 𝑎𝑖 = 0 constrains 𝑎𝑖 to be 0 if Π𝑖+1 = 1, otherwise it constrains 𝑎𝑖 ∈ B. So all of 𝑎0 .. 𝑛−1 are (︀ (︀ )︀ 1 − Π𝑖+1 − 𝑎𝑖 at least boolean-constrained. To prove the rest of the theorem we proceed by induction on decreasing 𝑚, i.e. taking successively longer prefixes of the big-endian binary representations of 𝑎 and 𝑐. Base case 𝑚 = 𝑛 − 1: since 𝑐𝑛−1 = 1, the constraint system has just one boolean constraint on 𝑎𝑛−1 , which fulfils the theorem since 𝐴𝑛−1 ≤ 𝐶𝑛−1 is always satisfied. Inductive case 𝑚 < 𝑛 − 1: • If 𝐴𝑚+1 > 𝐶𝑚+1 , then by the inductive hypothesis the constraint system must fail, which fulfils the theorem regardless of the value of 𝑎𝑚 . • If 𝐴𝑚+1 ≤ 𝐶𝑚+1 , then by the inductive hypothesis the constraint system restricted to 𝑖 ∈ {𝑚 + 1 .. 𝑛 − 1} ∏︀𝑛−1 ∏︀𝑛−1 succeeds. We have Π𝑚+1 = (𝑐 = 0 ∨ 𝑎𝑖 = 1) = 𝑖=𝑚+1 𝑖 𝑖=𝑚+1 (𝑎𝑖 ≥ 𝑐𝑖 ). – If 𝐴𝑚+1 = 𝐶𝑚+1 , then 𝑎𝑖 = 𝑐𝑖 for all 𝑖 ∈ {𝑚 + 1 .. 𝑛 − 1} and so Π𝑚+1 = 1. Also 𝐴𝑚 ≤ 𝐶𝑚 iff 𝑎𝑚 ≤ 𝑐𝑚 . When 𝑐𝑚 = 1, only a boolean constraint is added for 𝑎𝑚 which fulfils the theorem. When 𝑐𝑚 = 0, 𝑎𝑚 is constrained to be 0 which fulfils the theorem. – If 𝐴𝑚+1 < 𝐶𝑚+1 , then it cannot be the case that 𝑎𝑖 ≥ 𝑐𝑖 for all 𝑖 ∈ {𝑚 + 1 .. 𝑛 − 1}, so Π𝑚+1 = 0. This implies that the constraint on 𝑎𝑚 is always equivalent to a boolean constraint, which fulfils the theorem because 𝐴𝑚 ≤ 𝐶𝑚 must be true regardless of the value of 𝑎𝑚 . This covers all cases. Correctness of the full constraint system follows by taking 𝑚 = 0 in the above theorem. The algorithm in § A.3.3.2 ‘ctEdwards [de]compression and validation’ on p. 142 uses range checks with 𝑐 = 𝑟S − 1 to validate ctEdwards compressed encodings. In that case 𝑛 = 255 and 𝑘 = 132, so the cost of each such range check is 387 constraints. Non-normative note: It is possible to optimize the computation of Π𝑡 .. 𝑛−2 further. Notice that Π𝑚 is only used when 𝑚 is the index of the last bit of a run of 1 bits in 𝑐. So for each such run of 1 bits 𝑐𝑚 .. 𝑚+𝑁 −2 of length 𝑁 − 1, ∏︀𝑁 −1 it is sufficient to compute an 𝑁 -ary AND of 𝑎𝑚 .. 𝑚+𝑁 −2 and Π𝑚+𝑁 −1 : 𝑅 = 𝑖=0 𝑋𝑖 . This can be computed in 3 constraints for any 𝑁 ; boolean-constrain the output 𝑅, and then add constraints (︁ ∑︀𝑁 −1 )︁ (︀ )︀ (︀ ∑︀𝑁 −1 to enforce that 𝑋𝑖 ̸= 𝑁 when 𝑅 = 0; )︀ 𝑁− 𝑖=0 𝑋 𝑖 inv = 1 − 𝑅 𝑖=0 (︁ ∑︀𝑁 −1 )︁ (︀ )︀ (︀ )︀ ∑︀𝑁 −1 𝑁− 𝑖=0 𝑋𝑖 𝑅 = 0 to enforce that 𝑖=0 𝑋𝑖 = 𝑁 when 𝑅 = 1. (︁ ∑︀𝑁 −1 −1 )︁ where inv is witnessed as 𝑁 − 𝑖=0 𝑋𝑖 if 𝑅 = 0 or is unconstrained otherwise. (Since 𝑁 < 𝑟S , the sums cannot overflow.) In fact the last constraint is not needed in this context because it is sufficient to compute an upper bound on each Π𝑚 (i.e. it does not benefit a malicious prover to witness 𝑅 = 1 when the result of the AND should be 0). So the cost of computing Π variables for an arbitrarily long run of 1 bits can be reduced to 2 constraints. For example, for 𝑐 = 𝑟S − 1 the overall cost would be reduced to 255 + 68 = 323 constraints. These optimizations are not used in Sapling. 141

A.3.3 Elliptic curve operations A.3.3.1 Checking that Affine-ctEdwards coordinates are on the curve To check that (𝑢, v) is a point on the ctEdwards curve, the Sapling circuit uses 4 constraints: (︀ )︀ (︀ )︀ (︀ )︀ 𝑢 𝑢 = 𝑢𝑢 (︀ )︀ (︀ )︀ (︀ )︀ v v = vv (︀ )︀ (︀ )︀ (︀ )︀ 𝑢𝑢 vv = 𝑢𝑢vv (︀ )︀ (︀ )︀ (︀ )︀ 𝑎J ·𝑢𝑢 + vv 1 = 1 + 𝑑J ·𝑢𝑢vv Non-normative note: The last two constraints can be combined into 𝑑J ·𝑢𝑢 vv = 𝑎J ·𝑢𝑢 + vv − 1 . The (︀ )︀ (︀ )︀ (︀ )︀ Sapling circuit does not use this optimization. A.3.3.2 ctEdwards [de]compression and validation Define DecompressValidate CompressedCtEdwardsJubjub → AffineCtEdwardsJubjub as follows: ◦ ◦ DecompressValidate(˜ 𝑢, v) : // Prover supplies the 𝑢-coordinate. Let 𝑢 F𝑟 S . ◦ ◦ // § A.3.3.1 ‘Checking that Affine-ctEdwards coordinates are on the curve’ on p. 142. Check that (𝑢, v) is a point on the ctEdwards curve. // § A.3.2.1 ‘[Un]packing modulo 𝑟 S’ on p. 139. ∑︀254 Unpack 𝑢 to 𝑖=0 𝑖 𝑢 · 2𝑖 , equating 𝑢 ˜ with 𝑢0 . // § A.3.2.2 ‘Range check’ on p. 140. ∑︀254 Check that 𝑖=0 𝑖 𝑢 · 2𝑖 ≤ 𝑟S − 1. Return (𝑢, v). This costs 4 constraints for the curve equation check, 1 constraint for the unpacking, and 387 constraints for the range check (as computed in § A.3.2.2 ‘Range check’ on p. 140) for a total of 392 constraints. The cost of the range check includes boolean-constraining 𝑢0 .. 254 . The same quadratic constraint program is used for compression and decompression. Non-normative note: The point-on-curve check could be omitted if (𝑢, v) were already known to be on the curve. However, the Sapling circuit never omits it; this provides a consistency check on the elliptic curve arithmetic. A.3.3.3 ctEdwards ↔ Montgomery conversion Define CtEdwardsToMont AffineCtEdwardsJubjub → AffineMontJubjub as follows: ◦ ◦ 1+v √ (︁ )︁ 1+v CtEdwardsToMont(𝑢, v) = , + −40964 · [1 − v ̸= 0 and 𝑢 ̸= 0] 1−v (1 − v) · 𝑢 Define MontToCtEdwards AffineMontJubjub → AffineCtEdwardsJubjub as follows: ◦ ◦ (︁√ )︁ 𝑥 𝑥−1 MontToCtEdwards(𝑥, 𝑦) = + −40964 · , [𝑥 + 1 ̸= 0 and 𝑦 ̸= 0] 𝑦 𝑥+1 142

Either of these conversions can be implemented by the same quadratic constraint program: (︁√ )︁ 𝑢 = + −40964 · 𝑥 (︀ )︀ (︀ )︀ 𝑦 (︀ )︀ (︀ )︀ (︀ )︀ 𝑥+1 v = 𝑥−1 The above conversions should only be used if the input is guaranteed to be a point on the relevant curve. If that is the case, the theorems below enumerate all exceptional inputs that may violate the side-conditions. Theorem A.3.2. Exceptional points (ctEdwards → Montgomery). Let (𝑢, v) be an affine point on a ctEdwards curve 𝐸ctEdwards(𝑎,𝑑) . Then the only points with 𝑢 = 0 or 1 − v = 0 are (0, 1) = 𝒪J , and (0, −1) of order 2. Proof. The curve equation is 𝑎·𝑢2 + v2 = 1 + 𝑑·𝑢2 ·v2 with 𝑎 ̸= 𝑑 (see [BBJLP2008, Definition 2.1]). By substituting 𝑢 = 0 we obtain v = ±1, and by substituting v = 1 and using 𝑎 ̸= 𝑑 we obtain 𝑢 = 0. Theorem A.3.3. Exceptional points (Montgomery → ctEdwards). Let (𝑥, 𝑦) be an affine point on a Montgomery curve 𝐸Mont(𝐴,𝐵) over F𝑟 with parameters 𝐴 and 𝐵 such that 𝐴2 − 4 is a nonsquare in F𝑟 , that is birationally equivalent to a ctEdwards curve. Then 𝑥 + 1 ̸= 0, and the only point (𝑥, 𝑦) with 𝑦 = 0 is (0, 0) of order 2. Proof. That the only point with 𝑦 = 0 is (0, 0) is proven by Theorem A.2.1 on p. 138. If 𝑥 + 1 = 0, then subtituting 𝑥 = −1 into the Montgomery curve equation gives 𝐵 · 𝑦 2 = 𝑥3 + 𝐴 · 𝑥2 + 𝑥 = 𝐴 − 2. So in that case 𝑦 2 = (𝐴−2)/𝐵. The right-hand-side is equal to the parameter 𝑑 of a particular ctEdwards curve birationally equivalent to the Montgomery curve (see [BL2017, section 4.3.5]). For all ctEdwards curves, 𝑑 is nonsquare, so this equation has no solutions for 𝑦, hence 𝑥 + 1 ̸= 0. (When the theorem is applied with 𝐸Mont(𝐴,𝐵) = M defined in § A.2 ‘Elliptic curve background’ on p. 137, the ctEdwards curve referred to in the proof is an isomorphic rescaling of the Jubjub curve.) A.3.3.4 Affine-Montgomery arithmetic The incomplete affine-Montgomery addition formulae given in [BL2017, section 4.3.2] are: 𝑥3 = 𝐵M ·𝜆2 − 𝐴 M − 𝑥1 − 𝑥2 𝑦3 = (𝑥1 − 𝑥3 )·𝜆 − 𝑦1 ⎧ 2 ⎨ 3·𝑥1 + 2·𝐴M ·𝑥1 + 1 , if 𝑥1 = 𝑥2 where 𝜆 = 𝑦 − 𝑦2·𝐵M ·𝑦1 ⎩ 2 1, otherwise. 𝑥2 − 𝑥1 The following theorem helps to determine when these incomplete addition formulae can be safely used: Theorem A.3.4. Distinct-𝑥 theorem. Let 𝑄 be a point of odd-prime order 𝑠 on a Montgomery curve M = 𝐸Mont(𝐴M ,𝐵 M ) over F𝑟 S . Let 𝑘1 .. 2 be integers in − 𝑠−1 𝑠−1 {︀ }︀ 2 .. 2 ∖ {0}. Let 𝑃𝑖 = [𝑘𝑖 ] 𝑄 = (𝑥𝑖 , 𝑦𝑖 ) for 𝑖 ∈ {1 .. 2}, with 𝑘2 ̸= ±𝑘1 . Then the non-unified addition constraints (︀ )︀ (︀ )︀ (︀ )︀ 𝑥2 − 𝑥1 𝜆 = 𝑦2 − 𝑦1 (︀ )︀ (︀ )︀ (︀ )︀ 𝐵 M ·𝜆 𝜆 = 𝐴 M + 𝑥1 + 𝑥2 + 𝑥3 (︀ )︀ (︀ )︀ (︀ )︀ 𝑥1 − 𝑥3 𝜆 = 𝑦3 + 𝑦1 implement the affine-Montgomery addition 𝑃1 + 𝑃2 = (𝑥3 , 𝑦3 ) for all such 𝑃1 .. 2 . 143

Proof. The given constraints are equivalent to the Montgomery addition formulae under the side condition that 𝑥1 ̸= 𝑥2 . (Note that neither 𝑃𝑖 can be the zero point since 𝑘1 .. 2 ̸= 0 (mod 𝑠).) Assume for a contradiction that 𝑥1 = 𝑥2 . For any 𝑃1 = [𝑘1 ] 𝑄, there can be only one other point −𝑃1 with the same 𝑥-coordinate. (This follows from{︀ the fact that }︀ the curve equation determines ±𝑦 as a{︀ function of}︀𝑥.) But −𝑃1 = [−1] [𝑘1 ] 𝑄 = [−𝑘1 ] 𝑄. Since 𝑘 ◦ ◦ − 𝑠−1 2 .. 𝑠−1 2 ↦ → [𝑘] 𝑄 M is ◦ ◦ injective and 𝑘 1 .. 2 are in − 𝑠−1 2 .. 𝑠−1 2 , then 𝑘2 = ±𝑘1 (contradiction). The conditions of this theorem are called the distinct-𝑥 criterion. In particular, if 𝑘1 .. 2 are integers in 1 .. 𝑠−1 then it is sufficient to require 𝑘2 ̸= 𝑘1 , since that implies 𝑘2 ̸= ±𝑘1 . {︀ }︀ 2 Affine-Montgomery doubling can be implemented as: (︀ )︀ (︀ )︀ (︀ )︀ 𝑥 𝑥 = 𝑥𝑥 (︀ )︀ (︀ )︀ (︀ )︀ 2·𝐵M ·𝑦 𝜆 = 3·𝑥𝑥 + 2·𝐴 M ·𝑥 + 1 (︀ )︀ (︀ )︀ (︀ )︀ 𝐵 M ·𝜆 𝜆 = 𝐴 M + 2·𝑥 + 𝑥3 (︀ )︀ (︀ )︀ (︀ )︀ 𝑥 − 𝑥3 𝜆 = 𝑦3 + 𝑦 This doubling formula is valid when 𝑦 ̸= 0, which is the case when (𝑥, 𝑦) is not the point (0, 0) (the only point of order 2), as proven in Theorem A.2.1 on p. 138. A.3.3.5 Affine-ctEdwards arithmetic Formulae for affine-ctEdwards addition are given in [BBJLP2008, section 6]. With a change of variable names to match our convention, the formulae for (𝑢1 , v1 ) + (𝑢2 , v2 ) = (𝑢3 , v3 ) are: 𝑢1 ·v2 + v1 ·𝑢2 𝑢3 = 1 + 𝑑J ·𝑢1 ·𝑢2 ·v1 ·v2 v1 ·v2 − 𝑎J ·𝑢1 ·𝑢2 v3 = 1 − 𝑑J ·𝑢1 ·𝑢2 ·v1 ·v2 We use an optimized implementation found by Daira Hopwood making use of an observation by Bernstein and Lange in [BL2017, last paragraph of section 4.5.2]: (︀ )︀ (︀ )︀ (︀ )︀ 𝑢1 + v1 v2 − 𝑎J ·𝑢2 = 𝑇 (︀ )︀ (︀ )︀ (︀ )︀ 𝑢1 v2 = 𝐴 (︀ )︀ (︀ )︀ (︀ )︀ v1 𝑢2 = 𝐵 (︀ )︀ (︀ )︀ (︀ )︀ 𝑑J ·𝐴 𝐵 = 𝐶 (︀ )︀ (︀ )︀ (︀ )︀ 1+𝐶 𝑢3 = 𝐴 + 𝐵 (︀ )︀ (︀ )︀ (︀ )︀ 1−𝐶 v3 = 𝑇 − 𝐴 + 𝑎J ·𝐵 The correctness of this implementation can be seen by expanding 𝑇 − 𝐴 + 𝑎J ·𝐵: 𝑇 − 𝐴 + 𝑎J ·𝐵 = (𝑢1 + v1 ) · (v2 − 𝑎J ·𝑢2 ) − 𝑢1 ·v2 + 𝑎J ·v1 ·𝑢2 = v1 ·v2 − 𝑎J ·𝑢1 ·𝑢2 + 𝑢1 ·v2 − 𝑎J ·v1 ·𝑢2 − 𝑢1 ·v2 + 𝑎J ·v1 ·𝑢2 = v1 ·v2 − 𝑎J ·𝑢1 ·𝑢2 144

The above addition formulae are “unified”, that is, they can also be used for doubling. Affine-ctEdwards doubling [2] (𝑢, v) = (𝑢3 , v3 ) can also be implemented slightly more efficiently as: (︀ )︀ (︀ )︀ (︀ )︀ 𝑢+v v − 𝑎J ·𝑢 = 𝑇 (︀ )︀ (︀ )︀ (︀ )︀ 𝑢 v = 𝐴 (︀ )︀ (︀ )︀ (︀ )︀ 𝑑J ·𝐴 𝐴 = 𝐶 (︀ )︀ (︀ )︀ (︀ )︀ 1+𝐶 𝑢3 = 2·𝐴 (︀ )︀ (︀ )︀ (︀ )︀ 1−𝐶 v3 = 𝑇 + (𝑎J − 1)·𝐴 This implementation is obtained by specializing the addition formulae to (𝑢, v) = (𝑢1 , v1 ) = (𝑢2 , v2 ) and observing that 𝑢 · v = 𝐴 = 𝐵. A.3.3.6 Affine-ctEdwards nonsmall-order check In order to avoid small-subgroup attacks, we check that certain points used in the circuit are not of small order. In practice the Sapling circuit uses this in combination with a check that the coordinates are on the curve (§ A.3.3.1 ‘Checking that Affine-ctEdwards coordinates are on the curve’ on p. 142), so we combine the two operations. The Jubjub curve has a large prime-order subgroup with a cofactor of 8. To check for a point 𝑃 of order 8 or less, the Sapling circuit doubles three times (as in § A.3.3.5 ‘Affine-ctEdwards arithmetic’ on p. 144) and checks that the resulting 𝑢-coordinate is not 0 (as in § A.3.1.4 ‘Nonzero constraints’ on p. 139). On a ctEdwards curve, only the zero point 𝒪J , and the unique point of order 2 at (0, −1) have zero 𝑢-coordinate. The point of order 2 cannot occur as the result of three doublings. So this 𝑢-coordinate check rejects only 𝒪J . The total cost, including the curve check, is 4 + 3 · 5 + 1 = 20 constraints. Note: This does not ensure that the point is in the prime-order subgroup. Non-normative notes: • It would have been sufficient to do two doublings rather than three, because the check that the 𝑢-coordinate is nonzero would reject both 𝒪J and the point of order 2. • It is possible to reduce the cost to 8 constraints by eliminating the redundant constraint in the curve point check (as mentioned in § A.3.3.1 ‘Checking that Affine-ctEdwards coordinates are on the curve’ on p. 142); merging the first doubling with the curve point check; and then optimizing the second doubling based on the fact that we only need to check whether the resulting 𝑢-coordinate is zero. The Sapling circuit does not use these optimizations. A.3.3.7 Fixed-base Affine-ctEdwards scalar multiplication If the base point 𝐵 is fixed for a given scalar multiplication [𝑘] 𝐵, we can fully precompute window tables for each window position. It is most efficient to use 3-bit fixed windows. Since the length of 𝑟J is 252 bits, we need 84 windows. 83 ∑︁ Express 𝑘 in base 8, i.e. 𝑘 = 𝑘𝑖 ·8𝑖 . 𝑖=0 83 ∑︁ Then [𝑘] 𝐵 = 𝑤(𝐵, 𝑖, 𝑘𝑖 ) , where 𝑤(𝐵, 𝑖, 𝑘𝑖 ) = [𝑘𝑖 ·8𝑖 ] 𝐵. 𝑖=0 We precompute all of 𝑤(𝐵, 𝑖, 𝑠) for 𝑖 ∈ {0 .. 83}, 𝑠 ∈ {0 .. 7}. 145

To look up a given window entry 𝑤(𝐵, 𝑖, 𝑠) = (𝑢𝑠 , v𝑠 ), where 𝑠 = 4·𝑠2 + 2·𝑠1 + 𝑠0 , we use: (︀ )︀ (︀ )︀ (︀ )︀ 𝑠1 𝑠2 = 𝑠î (︀ )︀ (︀ 𝑠0 − 𝑢0 ·𝑠î + 𝑢0 ·𝑠2 + 𝑢0 ·𝑠1 − 𝑢0 + 𝑢2 ·𝑠î − 𝑢2 ·𝑠1 + 𝑢4 ·𝑠î − 𝑢4 ·𝑠2 − 𝑢6 ·𝑠î )︀ (︀ + 𝑢1 ·𝑠î − 𝑢1 ·𝑠2 − 𝑢1 ·𝑠1 + 𝑢1 − 𝑢3 ·𝑠î + 𝑢3 ·𝑠1 − 𝑢5 ·𝑠î + 𝑢5 ·𝑠2 + 𝑢7 ·𝑠î)︀ = 𝑢𝑠 − 𝑢0 ·𝑠î + 𝑢0 ·𝑠2 + 𝑢0 ·𝑠1 − 𝑢0 + 𝑢2 ·𝑠î − 𝑢2 ·𝑠1 + 𝑢4 ·𝑠î − 𝑢4 ·𝑠2 − 𝑢6 ·𝑠î (︀ )︀ (︀ 𝑠0 − v 0 ·𝑠î + v 0 ·𝑠2 + v 0 ·𝑠1 − v 0 + v 2 ·𝑠î − v 2 ·𝑠1 + v 4 ·𝑠î − v 4 ·𝑠2 − v 6 ·𝑠î )︀ (︀ + v 1 ·𝑠î − v 1 ·𝑠2 − v 1 ·𝑠1 + v 1 − v 3 ·𝑠î + v 3 ·𝑠1 − v 5 ·𝑠î + v 5 ·𝑠2 + v 7 ·𝑠î)︀ = v 𝑠 − v 0 ·𝑠î + v 0 ·𝑠2 + v 0 ·𝑠1 − v 0 + v 2 ·𝑠î − v 2 ·𝑠1 + v 4 ·𝑠î − v 4 ·𝑠2 − v 6 ·𝑠î For a full-length (252-bit) scalar this costs 3 constraints for each of 84 window lookups, plus 6 constraints for each of 83 ctEdwards additions (as in § A.3.3.5 ‘Affine-ctEdwards arithmetic’ on p. 144), for a total of 750 constraints. Fixed-base scalar multiplication is also used in two places with shorter scalars: • § A.3.6 ‘Homomorphic Pedersen Commitment’ on p. 150 uses a 64-bit scalar for the v input to ValueCommit, requiring 22 windows at a cost of 3·22 − 1 + 6·21 = 191 constraints; • § A.3.3.10 ‘Mixing Pedersen hash’ on p. 149 uses a 32-bit scalar for the pos input to MixingPedersenHash, requir- ing 11 windows at a cost of 3·11 − 1 + 6·10 = 92 constraints. None of these costs include the cost of boolean-constraining the scalar. Non-normative notes: • It would be more efficient to use arithmetic on the Montgomery curve, as in § A.3.3.9 ‘Pedersen hash’ on p. 147. However since there are only three instances of fixed-base scalar multiplication in the Spend circuit and two in the Output circuit 7 , the additional complexity was not considered justified for Sapling. • For the multiplications with 64-bit and 32-bit scalars, the scalar is padded to a multiple of 3 bits with zeros. This causes the computation of 𝑠î in the lookup for the most significant window to be optimized out, which is where the “− 1” comes from in the above cost calculations. No further optimization is done for this lookup. A.3.3.8 Variable-base Affine-ctEdwards scalar multiplication When the base point 𝐵 is not fixed, the method in the preceding section cannot be used. Instead we use a naïve double-and-add method. ∑︀250 Given 𝑘 = 𝑖=0 𝑖 𝑘 ·2𝑖 , we calculate 𝑅 = [𝑘] 𝐵 using: // Base𝑖 = [2𝑖 ] 𝐵 let Base0 = 𝐵 let Acc𝑢0 = 𝑘0 ? Base𝑢0 : 0 let Acc0v = 𝑘0 ? Base0v : 1 for 𝑖 from 1 up to 250: let Base𝑖 = [2] Base𝑖−1 // select Base𝑖 or 𝒪J depending on the bit 𝑘𝑖 let Addend𝑢𝑖 = 𝑘𝑖 ? Base𝑢𝑖 : 0 let Addend𝑖v = 𝑘𝑖 ? Base𝑖v : 1 let Acc𝑖 = Acc𝑖−1 + Addend𝑖 let 𝑅 = Acc250 . 7 A Pedersen commitment uses fixed-base scalar multiplication as a subcomponent. 146

This costs 5 constraints for each of 250 ctEdwards doublings, 6 constraints for each of 250 ctEdwards additions, and 2 constraints for each of 251 point selections, for a total of 3252 constraints. Non-normative note: It would be more efficient to use 2-bit fixed windows, and/or to use arithmetic on the Montgomery curve in a similar way to § A.3.3.9 ‘Pedersen hash’ on p. 147. However since there are only two instances of variable-base scalar multiplication in the Spend circuit and one in the Output circuit , the additional complexity was not considered justified for Sapling. A.3.3.9 Pedersen hash The specification of the Pedersen hashes used in Sapling is given in § 5.4.1.7 ‘Pedersen Hash Function’ on p. 58. It is based on the scheme from [CvHP1991, section 5.2] –for which a tighter security reduction to the Discrete Logarithm Problem was given in [BGG1995]– but tailored to allow several optimizations in the circuit implementation. Pedersen hashes are the single most commonly used primitive in the Sapling circuits. MerkleDepthSapling Pedersen hash instances are used in the Spend circuit to check a Merkle path to the note commitment of the note being spent. We also reuse the Pedersen hash implementation to construct the commitment scheme NoteCommitSapling . This motivates considerable attention to optimizing this circuit implementation of this primitive, even at the cost of complexity. First, we use a windowed scalar multiplication algorithm with signed digits. Each 3-bit message chunk corresponds to a window; the chunk is encoded as an integer from the set Digits = {−4 .. 4} ∖ {0}. This allows a more efficient lookup of the window entry for each chunk than if the set {1 .. 8} had been used, because a point can be conditionally negated using only a single constraint. Next, we optimize the cost of point addition by allowing as many additions as possible to be performed on the Montgomery curve. An incomplete Montgomery addition costs 3 constraints, in comparison with a ctEdwards addition which costs 6 constraints. However, we cannot do all additions on the Montgomery curve because the Montgomery addition is incomplete. In order to be able to prove that exceptional cases do not occur, we need to ensure that the distinct-𝑥 criterion from § A.3.3.4 ‘Affine-Montgomery arithmetic’ on p. 143 is met. This requires splitting the input into segments (each using an independent generator), calculating an intermediate result for each segment, and then converting to the ctEdwards curve and summing the intermediate results using ctEdwards addition. Abstracting away the changes of curve, this calculation can be written as: 𝑁 ∑︁ PedersenHashToPoint(𝐷, 𝑀 ) = [⟨𝑀𝑗 ⟩] ℐ𝐷 𝑗 𝑗=1 where ⟨∙⟩ and ℐ𝐷 𝑗 are defined as in § 5.4.1.7 ‘Pedersen Hash Function’ on p. 58. We have to prove that: • the Montgomery-to-ctEdwards conversions can be implemented without exceptional cases; • the distinct-𝑥 criterion is met for all Montgomery additions within a segment. 𝑟 − 1 𝑟J − 1 {︁ }︁ The proof of Theorem 5.4.1 on p. 59 showed that all indices of addition inputs are in the range − J .. ∖ {0}. 2 2 (𝑟)* Because the ℐ𝐷 𝑗 (which are outputs of GroupHash J ) are all of prime order, and ⟨𝑀𝑗 ⟩ = ̸ 0 (mod 𝑟J ), it is guaranteed 𝐷 that all of the terms [⟨𝑀𝑗 ⟩] ℐ 𝑗 to be converted to ctEdwards form are of prime order. From Theorem A.3.3 on p. 143, we can infer that the conversions will not encounter exceptional cases. We also need to show that the indices of addition inputs are all distinct disregarding sign. 147

Theorem A.3.5. Concerning addition inputs in the Pedersen circuit. For all disjoint nonempty subsets 𝑆 and 𝑆 ′ of {1 .. 𝑐}, all 𝑚 ∈ B[3][𝑐] , and all Θ ∈ {−1, 1}: ′ −1) ∑︁ ∑︁ enc(𝑚𝑗 ) · 24·(𝑗−1) ̸= Θ · enc(𝑚𝑗 ′ ) · 24·(𝑗 . ′ ′ 𝑗∈𝑆 𝑗 ∈𝑆 Proof. Suppose for a contradiction that 𝑆, 𝑆 ′ , 𝑚, Θ is a counterexample. Taking the multiplication by Θ on the right hand side inside the summation, we have: ′ −1) ∑︁ ∑︁ enc(𝑚𝑗 ) · 24·(𝑗−1) = Θ · enc(𝑚𝑗 ′ ) · 24·(𝑗 . ′ ′ 𝑗∈𝑆 𝑗 ∈𝑆 Define enc′ {−1, 1} × B[3] → {0 .. 8} ∖ {4} as enc′𝜃 (𝑚𝑖 ) := 4 + 𝜃 · enc(𝑚𝑖 ). ◦ ◦ ∑︀𝑐 Let Δ = 4 · 𝑖=1 24·(𝑖−1) as in the proof of Theorem 5.4.1 on p. 59. By adding Δ to both sides, we get ′ ′ enc′1 (𝑚𝑗 ) · 24·(𝑗−1) + enc′Θ (𝑚𝑗 ′ ) · 24·(𝑗 −1) −1) ∑︁ ∑︁ ∑︁ ∑︁ 4 · 24·(𝑗−1) = + 4 · 24·(𝑗 ′ ′ ′ ′ 𝑗∈𝑆 𝑗∈{1 .. 𝑐}∖𝑆 𝑗 ∈𝑆 𝑗 ∈{1 .. 𝑐}∖𝑆 where all of the enc′1 (𝑚𝑗 ) and enc′Θ (𝑚𝑗 ′ ) are in {0 .. 8} ∖ {4}. Each term on the left and on the right affects the single hex digit indexed by 𝑗 and 𝑗 ′ respectively. Since 𝑆 and 𝑆 ′ are disjoint subsets of {1 .. 𝑐} and 𝑆 is nonempty, 𝑆 ∩ ({1 .. 𝑐} ∖ 𝑆 ′ ) is nonempty. Therefore the left hand side has at least one hex digit not equal to 4 such that the corresponding right hand side digit is 4; contradiction. This implies that the terms in the Montgomery addition –as well as any intermediate results formed from adding a distinct subset of terms– have distinct indices disregarding sign, hence distinct 𝑥-coordinates by Theorem A.3.4 on p. 143. (We make no assumption about the order of additions.) We now describe the subcircuit used to process each chunk, which contributes most of the constraint cost of the hash. This subcircuit is used to perform a lookup of a Montgomery point in a 2-bit window table, conditionally negate the result, and add it to an accumulator holding another Montgomery point. Suppose that the bits of the chunk, [𝑠0 , 𝑠1 , 𝑠2 ], are already boolean-constrained. We aim to compute 𝐶 = 𝐴 + [(1 − 2 · 𝑠2 ) · (1 + 𝑠0 + 2 · 𝑠1 )] 𝑃 for some fixed base point 𝑃 and accumulated sum 𝐴. We first compute 𝑠î = 𝑠0 î 𝑠1 : (︀ )︀ (︀ )︀ (︀ )︀ 𝑠0 𝑠1 = 𝑠î Let (𝑥𝑘 , 𝑦𝑘 ) = [𝑘] 𝑃 for 𝑘 ∈ {1 .. 4}. Define each coordinate of (𝑥𝑆 , 𝑦𝑅 ) = [1 + 𝑠0 + 2 · 𝑠1 ] 𝑃 as a linear combination of 𝑠0 , 𝑠1 , and 𝑠î: let 𝑥𝑆 = 𝑥1 + (𝑥2 − 𝑥1 ) · 𝑠0 + (𝑥3 − 𝑥1 ) · 𝑠1 + (𝑥4 + 𝑥1 − 𝑥2 − 𝑥3 ) · 𝑠î let 𝑦𝑅 = 𝑦 1 + (𝑦 2 − 𝑦 1 ) · 𝑠0 + (𝑦 3 − 𝑦 1 ) · 𝑠1 + (𝑦 4 + 𝑦 1 − 𝑦 2 − 𝑦 3 ) · 𝑠î We implement the conditional negation as 2 · 𝑦𝑅 𝑠2 = 𝑦𝑅 − 𝑦𝑆 . After substitution of 𝑦𝑅 this becomes: (︀ )︀ (︀ )︀ (︀ )︀ (︀ )︀ (︀ )︀ 2 · (︀(𝑦1 + (𝑦2 − 𝑦1 ) · 𝑠0 + (𝑦3 − 𝑦1 ) · 𝑠1 + (𝑦4 + 𝑦1 − 𝑦2 − 𝑦3 ) · 𝑠î) )︀𝑠2 = 𝑦1 + (𝑦2 − 𝑦1 ) · 𝑠0 + (𝑦3 − 𝑦1 ) · 𝑠1 + (𝑦4 + 𝑦1 − 𝑦2 − 𝑦3 ) · 𝑠î − 𝑦𝑆 148

Then we substitute 𝑥𝑆 into the Montgomery addition constraints from § A.3.3.4 ‘Affine-Montgomery arithmetic’ on p. 143, as follows: (︀ )︀ (︀ )︀ (︀ )︀ 𝑥1 + (𝑥2 − 𝑥1 ) · 𝑠0 + (𝑥3 − 𝑥1 ) · 𝑠1 + (𝑥4 + 𝑥1 − 𝑥2 − 𝑥3 ) · 𝑠î − 𝑥𝐴 𝜆 = 𝑦𝑆 − 𝑦𝐴 (︀ )︀ (︀ )︀ (︀ )︀ 𝐵 M ·𝜆 𝜆 = 𝐴 M + 𝑥𝐴 + 𝑥1 + (𝑥2 − 𝑥1 ) · 𝑠0 + (𝑥3 − 𝑥1 ) · 𝑠1 + (𝑥4 + 𝑥1 − 𝑥2 − 𝑥3 ) · 𝑠î + 𝑥𝐶 (︀ )︀ (︀ )︀ (︀ )︀ 𝑥𝐴 − 𝑥𝐶 𝜆 = 𝑦𝐶 + 𝑦𝐴 (In the sapling-crypto implementation, linear combinations are first-class values, so these substitutions do not need to be done “by hand”.) For the first addition in each segment, both sides are looked up and substituted into the Montgomery addition, so the first lookup takes only 2 constraints. When these hashes are used in the circuit, the first 6 bits of the input are fixed. For example, in the Merkle tree hashes they represent the layer number. This would allow a precomputation for the first two windows, but that optimization is not done in Sapling. The cost of (︁ a)︁Pedersen hash over ℓ bits (where ℓ includes(︁ the )︁fixed bits) is as follows. The number of chunks is ℓ ℓ 𝑐 = ceiling and the number of segments is 𝑛 = ceiling . 3 3 · 63 The cost is then: • 2·𝑐 constraints for the lookups; • 3·(𝑐 − 𝑛) constraints for incomplete additions on the Montgomery curve; • 2·𝑛 constraints for Montgomery-to-ctEdwards conversions; • 6·(𝑛 − 1) constraints for ctEdwards additions; for a total of 5·𝑐 + 5·𝑛 − 6 constraints. This does not include the cost of boolean-constraining inputs. In particular, • for the Merkle tree hashes ℓ = 516, so 𝑐 = 172, 𝑛 = 3, and the cost is 869 constraints; • when a Pedersen hash is used to implement part of a Pedersen commitment for NoteCommitSapling (§ 5.4.7.2 ‘Windowed Pedersen commitments’ on p. 68), ℓ = 6 + ℓvalue + 2·ℓJ = 582, 𝑐 = 194, and 𝑛 = 4, so the cost of the hash alone is 984 constraints. A.3.3.10 Mixing Pedersen hash A mixing Pedersen hash is used to compute ρ from cm and pos in § 4.14 ‘Note Commitments and Nullifiers’ on p. 42. It takes as input a Pedersen commitment 𝑃 , and hashes it with another input 𝑥. Let 𝒥 be as defined in § 5.4.1.8 ‘Mixing Pedersen Hash Function’ on p. 60. We define MixingPedersenHash {0 .. 𝑟J − 1} × J → J by: ◦ ◦ MixingPedersenHash(𝑃, 𝑥) := 𝑃 + [𝑥] 𝒥 . This costs 92 constraints for a scalar multiplication (§ A.3.3.7 ‘Fixed-base Affine-ctEdwards scalar multiplication’ on p. 145), and 6 constraints for a ctEdwards addition (§ A.3.3.5 ‘Affine-ctEdwards arithmetic’ on p. 144), for a total of 98 constraints. 149

A.3.4 Merkle path check Checking each layer of a Merkle authentication path, as described in § 4.8 ‘Merkle Path Validity’ on p. 37, requires to: • boolean-constrain the path bit specifying whether the previous node is a left or right child; • conditionally swap the previous-layer and sibling hashes (as F𝑟 elements) depending on the path bit; • unpack the left and right hash inputs to two sequences of 255 bits; • compute the Merkle hash for this node. The unpacking need not be canonical in the sense discussed in § A.3.2.1 ‘[Un]packing modulo 𝑟 S’ on p. 139; that is, it is not necessary to ensure that the left or right inputs to the hash represent integers in the range {0 .. 𝑟S − 1}. Since the root of the Merkle tree is calculated outside the circuit using the canonical representations, and since the Pedersen hashes are collision-resistant on arbitrary bit-sequence inputs, an attempt by an adversarial prover to use a non-canonical input would result in the wrong root being calculated, and the overall path check would fail. For each layer, the cost is 1 + 2·255 boolean constraints, 2 constraints for the conditional swap (implemented as two selection constraints), and 869 constraints for the Merkle hash (§ A.3.3.9 ‘Pedersen hash’ on p. 147), for a total of 1380 constraints. Non-normative note: The conditional swap (𝑎0 , 𝑎1 ) ↦→ (𝑐0 , 𝑐1 ) could be implemented in only one constraint by substituting 𝑐1 = 𝑎0 + 𝑎1 − 𝑐0 into the uses of 𝑐1 . The Sapling circuit does not use this optimization. A.3.5 Windowed Pedersen Commitment We construct windowed Pedersen commitments by reusing the Pedersen hash implementation described in § A.3.3.9 ‘Pedersen hash’ on p. 147, and adding a randomized point: (𝑟)* WindowedPedersenCommit𝑟 (𝑠) = PedersenHashToPoint(“Zcash_PH”, 𝑠) + [𝑟] FindGroupHashJ (“Zcash_PH”, “r”) This can be implemented in: (︁ )︁ ℓ • 5·𝑐 + 5·𝑛 − 6 constraints for the Pedersen hash applied to ℓ = 6 + length(𝑠) bits, where 𝑐 = ceiling and (︁ )︁ 3 ℓ 𝑛 = ceiling ; 3 · 63 • 750 constraints for the fixed-base scalar multiplication; • 6 constraints for the final ctEdwards addition. When WindowedPedersenCommit is used to instantiate NoteCommitSapling , the cost of the Pedersen hash is 984 con- straints as calculated in § A.3.3.9 ‘Pedersen hash’ on p. 147, and so the total cost in that case is 1740 constraints. This does not include the cost of boolean-constraining the input 𝑠 or the randomness 𝑟. A.3.6 Homomorphic Pedersen Commitment The windowed Pedersen commitments defined in the preceding section are highly efficient, but they do not support the homomorphic property we need when instantiating ValueCommit. 150

In order to support this property, we also define homomorphic Pedersen commitments as follows: (𝑟)* (𝑟)* HomomorphicPedersenCommitrcv (𝐷, v) = [v] FindGroupHashJ (𝐷, “v”) + [rcv] FindGroupHashJ (𝐷, “r”) In the case that we need for ValueCommit, v has 64 bits 8 . This value is given as a bit representation, which does not need to be constrained equal to an integer. ValueCommit can be implemented in: • 750 constraints for the 252-bit fixed-base multiplication by rcv; • 191 constraints for the 64-bit fixed-base multiplication by v; • 6 constraints for the ctEdwards addition for a total cost of 947 constraints. This does not include the cost to boolean-constrain the input v or randomness rcv. A.3.7 BLAKE2s hashes BLAKE2s is defined in [ANWW2013]. Its main subcomponent is a “𝐺 function”, defined as follows: 𝐺 {0 .. 9} × {0 .. 232 −1}[4] → {0 .. 232 −1}[4] ◦ ◦ 𝐺(𝑎, 𝑏, 𝑐, 𝑑, 𝑥, 𝑦) = (𝑎′′ , 𝑏′′ , 𝑐′′ , 𝑑′′ ) where 𝑎′ = (𝑎 + 𝑏 + 𝑥) mod 232 𝑑′ = (𝑑 ⊕ 𝑎′ ) ≫ 16 𝑐′ = (𝑐 + 𝑑′ ) mod 232 𝑏′ = (𝑏 ⊕ 𝑐′ ) ≫ 12 𝑎′′ = (𝑎′ + 𝑏′ + 𝑦) mod 232 𝑑′′ = (𝑑′ ⊕ 𝑎′′ ) ≫ 8 𝑐′′ = (𝑐′ + 𝑑′′ ) mod 232 𝑏′′ = (𝑏′ ⊕ 𝑐′′ ) ≫ 7 The following table is used to determine which message words the 𝑥 and 𝑦 arguments to 𝐺 are selected from: 𝜎0 = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ] 𝜎1 = [ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ] 𝜎2 = [ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 ] 𝜎3 = [ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 ] 𝜎4 = [ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 ] 𝜎5 = [ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 ] 𝜎6 = [ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 ] 𝜎7 = [ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 ] 𝜎8 = [ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 ] 𝜎9 = [ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 ] 8 It would be sufficient to use 51 bits, which accomodates the range {0 .. MAX_MONEY}, but the Sapling circuit uses 64. 151

The Initialization Vector is defined as: IV {0 .. 232 −1}[8] := [ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A ◦ ◦ 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ] The full hash function applied to an 8-byte personalization string and a single 64-byte block, in sequential mode with 32-byte output, can be expressed as follows. Define BLAKE2s-256 (𝑝 BY[8] ) × (𝑥 BY[64] ) → BY[32] as: ◦ ◦ ◦ ◦ ◦ ◦ let PB BY[32] = [32, 0, 1, 1] || [0x00]20 || 𝑝 ◦ ◦ let [ 𝑡0 , 𝑡1 , 𝑓0 , 𝑓1 ] {0 .. 232 −1}[4] = [ 0, 0, 0, 0xFFFFFFFF, 0 ] ◦ ◦ let ℎ {0 .. 232 −1}[8] = [ LEOS2IP32 (PB4·𝑖 .. 4·𝑖 + 3 ) ⊕ IV𝑖 for 𝑖 from 0 up to 7 ] ◦ ◦ let 𝑚 {0 .. 232 −1}[16] = [ LEOS2IP32 (𝑥4·𝑖 .. 4·𝑖 + 3 ) for 𝑖 from 0 up to 15 ] ◦ ◦ let mutable 𝑣 {0 .. 232 −1}[16] := ℎ || [ IV0 , IV1 , IV2 , IV3 , 𝑡0 ⊕ IV4 , 𝑡1 ⊕ IV5 , 𝑓0 ⊕ IV6 , 𝑓1 ⊕ IV7 ] ◦ ◦ for 𝑟 from 0 up to 9: set (𝑣0 , 𝑣4 , 𝑣8 , 𝑣12 ) := 𝐺(𝑣0 , 𝑣4 , 𝑣8 , 𝑣12 , 𝑚𝜎𝑟,0 , 𝑚𝜎𝑟,1 ) set (𝑣1 , 𝑣5 , 𝑣9 , 𝑣13 ) := 𝐺(𝑣1 , 𝑣5 , 𝑣9 , 𝑣13 , 𝑚𝜎𝑟,2 , 𝑚𝜎𝑟,3 ) set (𝑣2 , 𝑣6 , 𝑣10 , 𝑣14 ) := 𝐺(𝑣2 , 𝑣6 , 𝑣10 , 𝑣14 , 𝑚𝜎𝑟,4 , 𝑚𝜎𝑟,5 ) set (𝑣3 , 𝑣7 , 𝑣11 , 𝑣15 ) := 𝐺(𝑣3 , 𝑣7 , 𝑣11 , 𝑣15 , 𝑚𝜎𝑟,6 , 𝑚𝜎𝑟,7 ) set (𝑣0 , 𝑣5 , 𝑣10 , 𝑣15 ) := 𝐺(𝑣0 , 𝑣5 , 𝑣10 , 𝑣15 , 𝑚𝜎𝑟,8 , 𝑚𝜎𝑟,9 ) set (𝑣1 , 𝑣6 , 𝑣11 , 𝑣12 ) := 𝐺(𝑣1 , 𝑣6 , 𝑣11 , 𝑣12 , 𝑚𝜎𝑟,10 , 𝑚𝜎𝑟,11 ) set (𝑣2 , 𝑣7 , 𝑣8 , 𝑣13 ) := 𝐺(𝑣2 , 𝑣7 , 𝑣8 , 𝑣13 , 𝑚𝜎𝑟,12 , 𝑚𝜎𝑟,13 ) set (𝑣3 , 𝑣4 , 𝑣9 , 𝑣14 ) := 𝐺(𝑣3 , 𝑣4 , 𝑣9 , 𝑣14 , 𝑚𝜎𝑟,14 , 𝑚𝜎𝑟,15 ) return LEBS2OSP256 (concatB ([[ I2LEBSP32 (ℎ𝑖 ⊕ 𝑣𝑖 ⊕ 𝑣𝑖+8 ) for 𝑖 from 0 up to 7 ] )) In practice the message and output will be expressed as bit sequences. In the Sapling circuit, the personalization string will be constant for each use. Each 32-bit exclusive-or is implemented in 32 constraints, one for each bit position 𝑎 ⊕ 𝑏 = 𝑐 as in § A.3.1.5 ‘Exclusive-or constraints’ on p. 139. Additions not involving a message word, i.e. (𝑎 + 𝑏) mod 232 = 𝑐, are implemented using 33 constraints and a 33-bit ∑︀𝑖=31 ∑︀𝑖=32 equality check: constrain 33 boolean variables 𝑐0 .. 32 , and then check 𝑖=0 (𝑎𝑖 + 𝑏𝑖 ) · 2𝑖 = 𝑖=0 𝑐𝑖 · 2𝑖 . Additions involving a message word, i.e. (𝑎 + 𝑏 + 𝑚) mod 232 = 𝑐, are implemented using 34 constraints and a 34-bit ∑︀𝑖=31 ∑︀𝑖=33 equality check: constrain 34 boolean variables 𝑐0 .. 33 , and then check 𝑖=0 (𝑎𝑖 + 𝑏𝑖 + 𝑚𝑖 ) · 2𝑖 = 𝑖=0 𝑐𝑖 · 2𝑖 . For each addition, only 𝑐0 .. 31 are used subsequently. The equality checks are batched; as many sets of 33 or 34 boolean variables as will fit in a F𝑟 S field element are equated together using one constraint. This allows 7 such checks per constraint. Each 𝐺 evaluation requires 262 constraints: • 4 · 32 = 128 constraints for ⊕ operations; • 2 · 33 = 66 constraints for 32-bit additions not involving message words (excluding equality checks); • 2 · 34 = 68 constraints for 32-bit additions involving message words (excluding equality checks). 152

The overall cost is 21006 constraints: • 10 · 8 · 262 − 4 · 2 · 32 = 20704 constraints for 80 𝐺 evaluations, excluding equality checks (the deduction of 4 · 2 · 32 is because 𝑣 is constant at the start of the first round, so in the first four calls to 𝐺, the parameters 𝑏 and 𝑑 are constant, eliminating the constraints for the first two XORs in those four calls to 𝐺); (︁ )︁ 10 · 8 · 4 • ceiling = 46 constraints for equality checks; 7 • 8 · 32 = 256 constraints for final 𝑣𝑖 ⊕ 𝑣𝑖+8 operations (the ℎ𝑖 words are constants so no additional constraints are required to exclusive-or with them). This cost includes boolean-constraining the hash output bits (done implicitly by the final ⊕ operations), but not the message bits. Non-normative notes: • The equality checks could be eliminated entirely by substituting each check into a boolean constraint for 𝑐0 , for instance, but this optimization is not done in Sapling. • It should be clear that BLAKE2s is very expensive in the circuit compared to elliptic curve operations. This is primarily because it is inefficient to use F𝑟 S elements to represent single bits. However Pedersen hashes do not have the necessary cryptographic properties for the two cases where the Spend circuit uses BLAKE2s. While it might be possible to use variants of functions with low circuit cost such as MiMC [AGRRT2017], it was felt that they had not yet received sufficient cryptanalytic attention to confidently use them for Sapling. 153

A.4 The Sapling Spend circuit The Sapling Spend statement is defined in § 4.15.2 ‘Spend Statement (Sapling)’ on p. 44. The primary input is rt B[ℓMerkleSapling ] , (︀ ◦ ◦ cvold ValueCommit.Output, ◦ ◦ nf old BY[ℓPRFnfSapling /8] , ◦ ◦ rk SpendAuthSig.Public , ◦ )︀ ◦ which is encoded as 8 F𝑟 S elements (starting with the fixed element 1 required by Groth16): [1, 𝑢(rk), v(rk), 𝑢(cvold ), v(cvold ), LEBS2IPℓMerkleSapling (rt) , LEBS2IP254 nf ⋆ 0 .. 253 , LEBS2IP2 nf ⋆ 254 .. 255 ] (︀ old )︀ (︀ old )︀ old where nf ⋆ = LEOS2BSPℓPRFnfSapling (nf old ). The auxiliary input is Sapling path B[ℓMerkle ][MerkleDepth ] (︀ ◦ ◦ , Sapling MerkleDepth pos {0 .. 2 ◦ ◦ −1}, gd J, ◦ ◦ pkd J, ◦ ◦ vold {0 .. 2ℓvalue −1}, ◦ ◦ rcvold {0 .. 2ℓscalar −1}, ◦ ◦ cmold J, ◦ ◦ rcmold {0 .. 2ℓscalar −1}, ◦ ◦ 𝛼 {0 .. 2ℓscalar −1}, ◦ ◦ ak SpendAuthSig.Public, ◦ ◦ nsk {0 .. 2ℓscalar −1} . ◦ )︀ ◦ ValueCommit.Output and SpendAuthSig.Public are of type J, so we have cvold , cmold , rk, gd , pkd , and ak that represent Jubjub curve points. However, • cvold will be constrained to an output of ValueCommit; • cmold will be constrained to an output of NoteCommitSapling ; • rk will be constrained to [𝛼] 𝒢 + ak; • pkd will be constrained to [ivk] gd so cvold , cmold , rk, and pkd do not need to be explicitly checked to be on the curve. In addition, nk⋆ and ρ⋆ used in Nullifier integrity are compressed representations of Jubjub curve points. TODO: explain why these are implemented as § A.3.3.2 ‘ctEdwards [de]compression and validation’ on p. 142 even though the statement spec doesn’t explicitly say to do validation. Therefore we have gd , ak, nk, and ρ that need to be constrained to valid Jubjub curve points as described in § A.3.3.2 ‘ctEdwards [de]compression and validation’ on p. 142. 154

In order to aid in comparing the implementation with the specification, we present the checks needed in the order in which they are implemented in the sapling-crypto code: Check Implements Cost Reference ak is on the curve TODO: FIXME also ak SpendAuthSig.Public ◦ ◦ 4 § A.3.3.1 on p. 142 decompressed below ak is not small order Small order checks 16 § A.3.3.6 on p. 145 [ℓscalar ] ℓscalar 𝛼⋆ B ◦ ◦ 𝛼 {0 .. 2 ◦ ◦ −1} 252 § A.3.1.1 on p. 138 ′ 𝛼 = [𝛼⋆] 𝒢 Spend authority 750 § A.3.3.7 on p. 145 ′ rk = 𝛼 + ak 6 § A.3.3.5 on p. 144 inputize rk TODO: not ccteddecompress- rk SpendAuthSig.Public ◦ ◦ 392? § A.3.3.2 on p. 142 validate => wrong count nsk⋆ B[ℓscalar ] ◦ ◦ nsk {0 .. 2ℓscalar −1} ◦ ◦ 252 § A.3.1.1 on p. 138 nk = [nsk⋆] ℋ Nullifier integrity 750 § A.3.3.7 on p. 145 ak⋆ = reprJ (ak J) ◦ ◦ Diversified address integrity 392 § A.3.3.2 on p. 142 nk⋆ = reprJ (nk) TODO: spec doesn’t say Nullifier integrity 392 § A.3.3.2 on p. 142 to validate nk since it’s calculated ivk⋆ = I2LEBSP251 CRHivk (ak, nk) † § A.3.7 on p. 151 (︀ )︀ Diversified address integrity 21006 gd is on the curve gd J ◦ ◦ 4 § A.3.3.1 on p. 142 gd is not small order Small order checks 16 § A.3.3.6 on p. 145 pkd = [ivk⋆] gd Diversified address integrity 3252 § A.3.3.8 on p. 146 old [64] old 64 v⋆ ◦ ◦ B v ◦ ◦ {0 .. 2 −1} 64 § A.3.1.1 on p. 138 [ℓscalar ] ℓscalar rcv⋆ B ◦ ◦ rcv {0 .. 2 ◦ ◦ −1} 252 § A.3.1.1 on p. 138 old cv = ValueCommitrcv (v ) Value commitment integrity 947 § A.3.6 on p. 150 inputize cv ? [ℓscalar ] ℓscalar rcm⋆ B ◦ ◦ rcm {0 .. 2 ◦ ◦ −1} 252 § A.3.1.1 on p. 138 cm = NoteCommitSapling rcm (gd , pkd , vold ) Note commitment integrity 1740 § A.3.5 on p. 150 cm𝑢 = ExtractJ(𝑟) (cm) Merkle path validity 0 ′ rt is the root of a Merkle tree with 32 · 1380 § A.3.4 on p. 150 leaf cm𝑢 , and authentication path (path, pos⋆) pos⋆ = I2LEBSPMerkleDepthSapling (pos) 1 § A.3.2.1 on p. 139 old ′ if v ̸= 0 then rt = rt 1 § A.3.1.2 on p. 139 inputize rt ? ρ = MixingPedersenHash(cmold , pos) Nullifier integrity 98 § A.3.3.10 on p. 149 ρ⋆ = reprJ (ρ) TODO: spec doesn’t say to 392 § A.3.3.2 on p. 142 validate ρ since it’s calculated nf old = PRFnfSapling nk⋆ (ρ⋆) 21006 § A.3.7 on p. 151 pack nf old 0 .. 253 and nf old 254 .. 255 into two input encoding 2 § A.3.2.1 on p. 139 F𝑟 S inputs † This is implemented by taking the output of BLAKE2s-256 as a bit sequence and dropping the most significant 5 bits, not by converting to an integer and back to a bit sequence as literally specified. 155

old Note: The implementation represents 𝛼⋆, nsk⋆, ivk⋆, rcm⋆, rcv⋆, and v⋆ as bit sequences rather than integers. It represents nf as a bit sequence rather than a byte sequence. A.5 The Sapling Output circuit The Sapling Output statement is defined in § 4.15.3 ‘Output Statement (Sapling)’ on p. 45. The primary input is (︀ new cv ValueCommit.Output, ◦ ◦ cm𝑢 B)︀[ℓMerkleSapling ] , ◦ ◦ epk J , ◦ ◦ which is encoded as 6 F𝑟 S elements (starting with the fixed element 1 required by Groth16): [1, 𝑢(cvnew ), v(cvnew ), 𝑢(epk), v(epk), LEBS2IPℓMerkleSapling (cm𝑢 )] The auxiliary input is (gd J,◦ ◦ pk⋆d B[ℓJ ] , ◦ ◦ vnew {0 .. 2ℓvalue −1}, ◦ ◦ rcvnew {0 .. 2ℓscalar −1}, ◦ ◦ rcmnew {0 .. 2ℓscalar −1}, ◦ ◦ esk {0 .. 2ℓscalar −1}) ◦ ◦ ValueCommit.Output is of type J, so we have cvnew , epk, and gd that represent Jubjub curve points. However, • cvnew will be constrained to an output of ValueCommit; • epk will be constrained to [esk] gd so cvnew and epk do not need to be explicitly checked to be on the curve. Therefore we have only gd that needs to be constrained to a valid Jubjub curve point as described in § A.3.3.2 ‘ctEdwards [de]compression and validation’ on p. 142. Note: pk⋆d is not checked to be a valid compressed representation of a Jubjub curve point. 156

In order to aid in comparing the implementation with the specification, we present the checks needed in the order in which they are implemented in the sapling-crypto code: Check Implements Cost Reference old [64] old 64 v⋆ ◦ ◦ B v ◦ ◦ {0 .. 2 −1} 64 § A.3.1.1 on p. 138 [ℓscalar ] ℓscalar rcv⋆ B ◦ ◦ rcv {0 .. 2 ◦ ◦ −1} 252 § A.3.1.1 on p. 138 old cv = ValueCommitrcv (v ) Value commitment integrity 947 § A.3.6 on p. 150 inputize cv ? g⋆d = reprJ (gd J) ◦ ◦ Note commitment integrity 392 § A.3.3.2 on p. 142 gd is not small order Small order checks 16 § A.3.3.6 on p. 145 [ℓscalar ] ℓscalar esk⋆ B ◦ ◦ esk {0 .. 2 ◦ ◦ −1} 252 § A.3.1.1 on p. 138 epk = [esk⋆] gd Ephemeral public key integrity 3252 § A.3.3.8 on p. 146 inputize epk ? [ℓJ ] [ℓJ ] pk⋆d B ◦ ◦ pk⋆d B ◦ ◦ 256 § A.3.1.1 on p. 138 [ℓscalar ] ℓscalar rcm⋆ B ◦ ◦ rcm {0 .. 2 ◦ ◦ −1} 252 § A.3.1.1 on p. 138 cm = NoteCommitSapling rcm (gd , pkd , vold ) Note commitment integrity 1740 § A.3.5 on p. 150 pack inputs ? old Note: The implementation represents esk⋆, pk⋆d , rcm⋆, rcv⋆, and v⋆ as bit sequences rather than integers. B Batching Optimizations B.1 RedDSA batch validation The reference validation algorithm for RedDSA signatures is defined in § 5.4.6 ‘RedDSA and RedJubjub’ on p. 65. Let the RedDSA parameters G (defining a subgroup G(𝑟) of order 𝑟G , a cofactor ℎG , a group operation +, an additive identity 𝒪G , a bit-length ℓG , a representation function reprG , and an abstraction function abstG ); 𝒫G G; ℓH N; ◦ ◦ ◦ ◦ H BY[N] → BY[ℓH /8] ; and the derived hash function H~ BY[N] → F𝑟G be as defined in that section. ◦ ◦ ◦ ◦ Implementations MAY alternatively use the optimized procedure described in this section to perform faster validation of a batch of signatures, i.e. to determine whether all signatures in a batch are valid. Its input is a sequence of 𝑁 signature batch entries, each of which is a (validating key , message, signature) triple. Let LEOS2BSP, LEOS2IP, and LEBS2OSP be as defined in § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53. Define RedDSA.BatchEntry := RedDSA.Public × RedDSA.Message × RedDSA.Signature. 157

Define RedDSA.BatchValidate (entry0 .. 𝑁 −1 RedDSA.BatchEntry[𝑁 ] ) → B as: ◦ ◦ ◦ ◦ For each 𝑗 ∈ {0 .. 𝑁 − 1}: Let (vk𝑗 , 𝑀𝑗 , 𝜎𝑗 ) = entry𝑗 . Let 𝑅𝑗 be the first ceiling ℓG /8 bytes of 𝜎𝑗 , and let 𝑆𝑗 be the remaining ceiling (bitlength(𝑟G )/8) bytes. (︀ )︀ Let 𝑅𝑗 = abstG LEOS2BSPℓG (𝑅𝑗 ) , and let 𝑆𝑗 = LEOS2IP8·length(𝑆𝑗 ) (𝑆𝑗 ). (︀ )︀ Let vk𝑗 = LEBS2OSPℓG reprG (vk𝑗 ) . (︀ )︀ Let 𝑐𝑗 = H~ (𝑅𝑗 || vk𝑗 || 𝑀𝑗 ). R Choose random 𝑧𝑗 F*𝑟G ← {1 .. 2128 − 1}. ◦ ◦ Return 1 if • for all 𝑗 ∈ {0 .. 𝑁 − 1}, 𝑅𝑗 ̸= ⊥ and 𝑆𝑗 < 𝑟G ; and (︁ [︁ ∑︀𝑁 −1 ]︁ ∑︀𝑁 −1 ∑︀𝑁 −1 )︁ • [ℎG ] − 𝑗=0 (𝑧𝑗 · 𝑆𝑗 ) (mod 𝑟G ) 𝒫G + 𝑗=0 [𝑧𝑗 ] 𝑅 𝑗 + 𝑗=0 [𝑧𝑗 · 𝑐 𝑗 (mod 𝑟G )] vk 𝑗 = 𝒪G , otherwise 0. The 𝑧𝑗 values MUST be chosen independently of the signature batch entries. The performance benefit of this approach arises partly from replacing the per-signature scalar multiplication of the base 𝒫G with one such multiplication per batch, and partly from using an efficient algorithm for multiscalar multiplication such as Pippinger’s method [Bernstein2001] or the Bos–Coster method [deRooij1995], as explained in [BDLSY2012, section 5]. Note: Spend authorization signatures (§ 5.4.6.1 ‘Spend Authorization Signature’ on p. 67) and binding signatures (§ 5.4.6.2 ‘Binding Signature’ on p. 68) use different bases 𝒫G . It is straightforward to adapt the above procedure [︁ ∑︀ ]︁ to handle multiple bases; there will be one − 𝑗 (𝑧𝑗 · 𝑆𝑗 ) (mod 𝑟G ) 𝒫 term for each base 𝒫. The benefit of this relative to using separate batches is that the multiscalar multiplication can be extended across a larger batch. B.2 Groth16 batch verification The reference verification algorithm for Groth16 proofs is defined in § 5.4.9.2 ‘Groth16’ on p. 76. The batch verification algorithm in this section applies techniques from [BFIJSV2010, section 4]. (𝑟) (𝑟)* Let 𝑞S , 𝑟S , S1,2,𝑇 , S1,2,𝑇 , 𝒫S1,2,𝑇 , 1S , and 𝑒^S be as defined in § 5.4.8.2 ‘BLS12-381’ on p. 71. (𝑟) (𝑟) (𝑟) (𝑟) (𝑟) Define MillerLoopS S1 × S2 → S𝑇 and FinalExpS ◦ ◦ ◦ ◦ S𝑇 → S𝑇 to be the Miller loop and final exponentiation respectively of the 𝑒^S pairing computation, so that: 𝑒^S (𝑃, 𝑄) = FinalExpS (MillerLoopS (𝑃, 𝑄)) where FinalExpS (𝑅) = 𝑅𝑡 for some fixed 𝑡. (𝑟)* (𝑟)* (𝑟)* Define Groth16 S .Proof := S1 × S2 × S1 . A Groth16 S proof consists of a tuple (𝜋𝐴 , 𝜋𝐵 , 𝜋𝐶 ) Groth16 S .Proof. ◦ ◦ Verification of a single Groth16 S proof against an instance encoded as 𝑎0 .. ℓ F𝑟 S [ℓ+1] requires checking the equation ◦ ◦ (︁ ∑︀ℓ )︁ 𝑒^S (𝜋𝐴 , 𝜋𝐵 ) = 𝑒^S (𝜋𝐶 , Δ) · 𝑒^S 𝑖=0 [𝑎𝑖 ] Ψ 𝑖 , Γ ·𝑌 [︁ ]︁ 𝛽 ·𝑢𝑖 (𝑥) + 𝛼·𝑣𝑖 (𝑥) + 𝑤𝑖 (𝑥) where Δ = [𝛿] 𝒫S2 , Γ = [𝛾] 𝒫S2 , 𝑌 = [𝛼·𝛽] 𝒫S𝑇 , and Ψ𝑖 = 𝒫S1 for 𝑖 ∈ {0 .. ℓ} are elements of 𝛾 the verification key, as described (with slightly different notation) in [Groth2016, section 3.2]. 158

This can be written as: (︁ ∑︀ℓ )︁ 𝑒^S (𝜋𝐴 , −𝜋𝐵 ) · 𝑒^S (𝜋𝐶 , Δ) · 𝑒^S 𝑖=0 [𝑎𝑖 ] Ψ 𝑖 , Γ · 𝑌 = 1S . Raising to the power of random 𝑧 ̸= 0 gives: (︁ ∑︀ℓ )︁ 𝑒^S ([𝑧] 𝜋𝐴 , −𝜋𝐵 )· 𝑒^S ([𝑧] 𝜋𝐶 , Δ)· 𝑒^S 𝑖=0 [𝑧 · 𝑎𝑖 ] Ψ 𝑖 , Γ · 𝑌 𝑧 = 1S . This justifies the following optimized procedure for performing faster verification of a batch of Groth16 S proofs. Implementations MAY use this procedure to determine whether all proofs in a batch are valid. Define a type Groth16 S .BatchEntry := Groth16 S .Proof × Groth16 S .PrimaryInput representing proof batch entries. Define Groth16 S .BatchVerify (entry0 .. 𝑁 −1 Groth16 S .BatchEntry[𝑁 ] ) → B as: ◦ ◦ ◦ ◦ For each 𝑗 ∈ {0 .. 𝑁 − 1}: Let ((𝜋𝑗,𝐴 , 𝜋𝑗,𝐵 , 𝜋𝑗,𝐶 ), 𝑎𝑗, 0 .. ℓ ) = entry𝑗 . R Choose random 𝑧𝑗 F*𝑟 S ← {1 .. 2128 − 1}. ◦ ◦ ∏︀𝑁 −1 Let Accum𝐴𝐵 = MillerLoopS [𝑧𝑗 ] 𝜋𝑗,𝐴 , −𝜋𝑗,𝐵 . (︀ )︀ 𝑗=0 ∑︀𝑁 −1 Let AccumΔ = 𝑗=0 [𝑧𝑗 ] 𝜋𝑗,𝐶 . ∑︀𝑁 −1 Let AccumΓ,𝑖 = 𝑗=0 (𝑧𝑗 · 𝑎𝑗,𝑖 ) (mod 𝑟S ) for 𝑖 ∈ {0 .. ℓ}. ∑︀𝑁 −1 Let Accum𝑌 = 𝑗=0 𝑧𝑗 (mod 𝑟S ). Return 1 if (︂ (︁ ∑︀ℓ )︁)︂ [AccumΓ,𝑖 ] Ψ𝑖 , Γ · 𝑌 Accum𝑌 = 1 S , (︀ )︀ FinalExpS Accum𝐴𝐵 · MillerLoopS AccumΔ , Δ · MillerLoopS 𝑖=0 otherwise 0. The 𝑧𝑗 values MUST be chosen independently of the proof batch entries. The performance benefit of this approach arises from computing two of the three Miller loops, and the final exponentation, per batch instead of per proof. For the multiplications by 𝑧𝑗 , an efficient algorithm for multiscalar multiplication such as Pippinger’s method [Bernstein2001] or the Bos–Coster method [deRooij1995] may be used. Note: Spend proofs (of the statement in § 4.15.2 ‘Spend Statement (Sapling)’ on p. 44) and output proofs (of the statement in § 4.15.3 ‘Output Statement (Sapling)’ on p. 45) use different verification keys, with different parameters Δ, Γ, 𝑌 , and Ψ0 .. ℓ . It is straightforward to adapt the above procedure to handle multiple verification keys; the accumulator variables AccumΔ , AccumΓ,𝑖 , and Accum𝑌 are duplicated, with one term in the verification equation for each variable, while Accum𝐴𝐵 is shared. (𝑟) Neglecting multiplications in S𝑇 and F𝑟 S , and other trivial operations, the cost of batched verification is therefore • for each proof: the cost of decoding the proof representation to the form Groth16 S .Proof, which requires (𝑟)* (𝑟)* three point decompressions and three subgroup checks (two for S1 and one for S2 ); (𝑟) • for each successfully decoded proof: a Miller loop; and a 128-bit scalar multiplication by 𝑧𝑗 in S1 ; (𝑟) (𝑟) • for each verification key: two Miller loops; an exponentiation in S𝑇 ; a multiscalar multiplication in S1 with (𝑟) 𝑁 128-bit scalars to compute AccumΔ ; and a multiscalar multiplication in S1 with ℓ + 1 255-bit scalars to ∑︀ℓ compute 𝑖=0 [AccumΓ,𝑖 ] Ψ𝑖 ; • one final exponentiation. 159

B.3 Ed25519 batch validation The reference validation algorithm for Ed25519 signatures is defined in § 5.4.5 ‘Ed25519’ on p. 63. [Canopy onward] Implementations MAY alternatively use the optimized procedure described in this section to perform faster validation of a batch of signatures, i.e. to determine whether all signatures in a batch are valid. The correctness of this procedure is dependent on the Ed25519 validation changes made for the Canopy network upgrade in [ZIP-215] (in particular the change to use the cofactor variant of the validation equation). The input is a sequence of 𝑁 signature batch entries, each of which is a (validating key , message, signature) triple. Let ℓ, 𝐵, abstBytesEd25519 , and reprBytesEd25519 be as defined in § 5.4.5 ‘Ed25519’ on p. 63. Let LEOS2IP be as defined in § 5.2 ‘Integers, Bit Sequences, and Endianness’ on p. 53. SHA-512 is defined in § 5.4.1.1 ‘SHA-256, SHA-256d, SHA256Compress, and SHA-512 Hash Functions’ on p. 55. Define Ed25519.BatchEntry := Ed25519.Public × Ed25519.Message × Ed25519.Signature. Define Ed25519.BatchValidate (entry0 .. 𝑁 −1 Ed25519.BatchEntry[𝑁 ] ) → B as: ◦ ◦ ◦ ◦ For each 𝑗 ∈ {0 .. 𝑁 − 1}: Let (𝐴𝑗 , 𝑀𝑗 , 𝜎𝑗 ) = entry𝑗 . Let 𝑅𝑗 be the first 32 bytes of 𝜎𝑗 , and let 𝑆𝑗 be the remaining 32 bytes. Let 𝑅𝑗 = abstBytesEd25519 (𝑅𝑗 ), and let 𝑆𝑗 = LEOS2IP256 (𝑆𝑗 ). Let 𝐴𝑗 = reprBytesEd25519 (𝐴𝑗 ). Let 𝑐𝑗 = LEOS2IP512 SHA-512(𝑅𝑗 || 𝐴𝑗 || 𝑀𝑗 ) . (︀ )︀ R Choose random 𝑧𝑗 F*ℓ ← {1 .. 2128 − 1}. ◦ ◦ Return 1 if • for all 𝑗 ∈ {0 .. 𝑁 − 1}, 𝑅𝑗 ̸= ⊥ and 𝑆𝑗 < ℓ; and (︁ [︁ ∑︀𝑁 −1 ]︁ ∑︀𝑁 −1 ∑︀𝑁 −1 )︁ • [8] − 𝑗=0 (𝑧𝑗 · 𝑆𝑗 ) (mod ℓ) 𝐵 + 𝑗=0 [𝑧𝑗 ] 𝑅 𝑗 + 𝑗=0 [𝑧𝑗 · 𝑐 𝑗 (mod ℓ)] 𝐴 𝑗 = 𝒪Ed25519 , otherwise 0. The 𝑧𝑗 values MUST be chosen independently of the signature batch entries. The performance benefits of this approach are the same as for § B.1 ‘RedDSA batch validation’ on p. 157. 160

List of Theorems and Lemmata Theorem 5.4.1 The encoding function ⟨∙⟩ is injective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 Sapling Theorem 5.4.2 Uncommitted is not in the range of PedersenHash . . . . . . . . . . . . . . . . . . . . . . . . 60 (𝑟) Lemma / J(𝑟) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4.3 Let 𝑃 = (𝑢, v) ∈ J . Then (𝑢, −v) ∈ 74 Theorem 5.4.4 𝑢 is injective on J(𝑟) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Theorem A.2.1 (0, 0) is the only point with 𝑦 = 0 on certain Montgomery curves . . . . . . . . . . . . . . . . . 138 Theorem A.3.1 Correctness of a constraint system for range checks . . . . . . . . . . . . . . . . . . . . . . . . . 141 Theorem A.3.2 Exceptional points (ctEdwards → Montgomery) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Theorem A.3.3 Exceptional points (Montgomery → ctEdwards) . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Theorem A.3.4 Distinct-𝑥 theorem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Theorem A.3.5 Concerning addition inputs in the Pedersen circuit . . . . . . . . . . . . . . . . . . . . . . . . . 148 Index account, 34 block hash, 18 activation block, 18, 19 block header, 15, 55, 90, 91–93, 95, 121, 123, 125 activation block height, 84, 87, 99, 111 block height, 15, 18, 48, 49, 83–86, 88, 89, 91, 93–99, 107, ALL CAPS, 7 113 anchor, 15, 16, 17, 31, 32, 43, 44 block subsidy, 18, 83, 95, 98, 108, 125 authenticated one-time symmetric encryption, 20, block target spacing, 93, 94, 99 21, 62 block timestamp, 90 auxiliary input, 28, 36, 37, 42–46, 116 block version number, 90, 91–92, 113, 122 Blossom, 1, 7, 18, 38, 83, 90, 91, 94, 98, 99, 110–113 balancing value, 39, 40, 118 BLS12-381, 29, 71, 77, 106, 118 BCTV14, 29, 32, 37, 41, 75, 76, 85, 88, 106, 113, 117, 137 BN-254, 29, 70, 72, 76 bellman, 76, 83 Bulletproofs, 41 best valid block chain, 15, 47, 49, 123 Canopy, 1, 7, 18, 32, 34, 38, 49, 50, 65, 78, 83, 87, 97–99, bilateral consensus rule change, 84 107–110, 160 binding (commitment scheme), 25 chain value pool balance (Sapling), 39, 107 binding signature, 17, 23, 38, 39, 40, 41, 67, 104, 119 chain value pool balance (Sprout), 39, 107 binding signature scheme, 65, 68 chunks (of a Pedersen hash input), 59 Bitcoin, 1, 7, 8, 15, 17, 18, 22, 37–39, 78, 79, 83, 85–88, coinbase transaction, 18, 39, 86, 87, 96–99, 107–109, 90–93, 100, 106, 108, 123, 125, 126 119, 121, 125 block, 15–18, 29, 31, 32, 35, 39, 48, 49, 83, 84, 86, 87, 90, coins (in Zerocash), 8 91–95, 100, 110, 112, 113, 123, 124 collision resistance, 19, 20, 27, 56–62, 68, 102, 103, 105, block chain, 8, 9, 13, 14, 15, 16, 18, 39, 42, 47, 49, 51, 52, 106, 121, 126, 150 75–77, 87, 91, 94, 95, 100, 102, 110, 112, 113, 121, commitment scheme, 25, 69, 117, 147 123 commitment trapdoor, 13, 25, 35, 41, 101, 117 block chain branch, 87 complete twisted Edwards affine coordinates, 60, 137, block chain reorganization, 47, 49, 84 138, 144, 145 161

complete twisted Edwards compressed encoding, 74, incoming viewing key, 12, 13, 19, 30, 46–48, 51, 57, 58, 80, 81, 141 78, 80, 81, 122 complete twisted Edwards elliptic curve, 11, 35, 64, 73, incremental Merkle tree, 17, 37, 56, 58, 110, 126 74, 112, 137, 142, 143, 145, 147 index (of a Merkle tree node), 17, 37 consensus branch ID, 38 internal node (of a Merkle tree), 37 consensus rule change, 84 JoinSplit circuit, 82, 83 CryptoNote, 9, 126 JoinSplit description, 8, 14, 16, 18, 22, 23, 31, 32, 34–36, ctEdwards, 11, 73 38, 39, 42, 46, 47, 51, 76, 77, 85–88, 100, 102, 105, 107, 116, 121, 123 Decentralized Anonymous Payment scheme, 1, 7 JoinSplit proof, 36 default diversified payment address, 30, 75 JoinSplit signature, 23, 38, 125 distinct-𝑥 criterion, 121, 144, 147 JoinSplit signing key, 34 diversified base, 19, 30, 35, 48, 57 JoinSplit statement, 8, 16, 29, 32, 36, 38, 41, 43, 75, 102, diversified payment address, 12, 13, 14, 30, 31, 36, 57, 103, 105, 106, 117, 122, 137 58, 103, 106, 112, 114 JoinSplit transfer, 16, 17–18, 31, 35, 37, 39, 88, 100–102, diversified transmission key, 13, 30, 33, 35, 47, 48, 77 104, 106, 123, 126 diversifier, 13, 19, 30, 31, 57, 58 Jubjub, 27, 35, 45, 46, 49, 50, 57, 58, 60, 62, 63, 65, 68, 73, dummy note, 35, 36, 101, 102 74, 81, 89, 103, 104, 109, 112, 116, 119, 121, 122, 137, 143, 145, 154, 156 Ed25519, 55, 63–65, 86, 109, 110, 119, 122, 125, 160 key agreement scheme, 21, 29, 46, 47, 62, 63 ephemeral private key, 33, 35, 48 Key Derivation Function, 21, 46, 47, 63 ephemeral public key, 21, 46, 47, 104 key privacy, 9, 22, 57, 104–106, 112, 114 Equihash, 1, 19, 60, 90, 91, 92, 93, 106, 113, 116, 122, 124, 125 layer (of a Merkle tree), 17, 37, 45 expanded spending key, 12 leaf node (of a Merkle tree), 37 extended spending key, 12, 111 libsnark (Zcash fork), 75, 76, 82, 106 linear combination, 137, 139 family of group hashes into a subgroup, 27 Founders’ Reward, 18, 86, 95, 96, 98, 112, 119, 123–125 Mainnet, 18, 19, 54, 79–83, 86, 91, 92, 94, 96, 99, 100, 108, full node, 121 113, 124 MAY, 7, 31, 41, 42, 49, 65, 67, 157, 159, 160 full validator, 15, 18, 91, 121 median-time-past, 90, 91, 110 full viewing key, 9, 12, 13, 30, 33, 42, 52, 81, 117 memo field, 15, 46, 47, 51, 52, 77, 100, 110, 121, 125 funding stream, 18, 86, 87, 95, 98, 99, 112 mempool, 49, 50, 107 genesis block, 15, 18, 86, 90, 91, 98, 100, 107, 124 Merkle path, 36, 37, 43, 44, 147 Groth16, 29, 32, 37, 40, 41, 76, 77, 85, 88, 106, 113, 115, 117, Mimblewimble, 41 137, 154, 156, 158 miner subsidy, 18, 39, 86, 95, 125 group hash, 27, 74 monomorphism, 24, 110 Montgomery affine coordinates, 137, 138, 143, 144 halving, 83, 98, 99 Montgomery elliptic curve, 114, 137, 138, 143, 146, 147, hash extractor, 26 149, 161 hash function, 15, 19, 29, 55, 58–62, 64, 65, 105, 118 MUST, 7, 15–18, 32–35, 39, 45, 46, 48–50, 65, 67, 76, 77, hash value (of a Merkle tree node), 17, 37, 56 80, 81, 84, 86, 87, 89, 91, 93, 97–99, 109, 115, 158–160 Heartwood, 1, 7, 19, 38, 83, 86, 87, 90, 91, 99, 107, 110 MUST NOT, 7, 18, 33, 49, 65, 71, 72, 74, 76, 86, 87, 91, 116 hiding (commitment scheme), 25 Hierarchical Deterministic Wallet, 12 network upgrade, 18, 83, 84, 87, 99 homomorphic Pedersen commitment, 69, 151 node (of a Merkle tree), 17, 37 Human-Readable Part, 80, 81–82 nonmalleability (of proofs), 28 162

nonmalleability (of signatures), 23 proving key (for a zk-SNARK), 28, 29, 82, 83 note, 8, 9, 13, 14–17, 19, 20, 23, 25, 31–37, 39, 41, 42, proving system (preprocessing zk-SNARK), 1, 7, 8, 17, 46–52, 62, 77, 88, 89, 100–103, 105, 107, 109, 28, 29, 75, 76, 101, 114, 125 119, 147 Pseudo Random Function, 14, 20, 29, 31, 55, 61, 62, 68, note commitment, 8, 14, 16, 17, 32, 33, 37, 42, 47, 48, 50, 103, 105, 121 88, 89, 101–103, 105, 118, 123, 147 Pseudo Random Permutation, 58 note commitment tree, 14, 15, 17, 37, 42, 56, 88–91, 102, public key, 13, 21, 32, 33, 46, 48, 57, 62, 79, 80, 88, 89, 121 104, 105 note plaintext, 14, 15, 33, 46, 48, 52, 77, 78, 86, 87, 107, 109 Quadratic Arithmetic Program, 75, 76, 137 note plaintext lead byte, 35, 87, 109 quadratic constraint program, 7, 75, 76, 122, 137, 139, 142, 143 note position, 8, 14, 17, 42, 52, 102 note traceability set, 9, 119 randomized Spend validating key, 119 nullifier, 8, 9, 13, 14, 16, 17, 18, 19, 31, 32, 42, 51, 52, 62, 88, randomizer, 23, 24, 41 89, 101–103, 105, 107, 108, 119, 123 Rank 1 Constraint System, 137 nullifier deriving key, 8, 14, 42, 49 raw encoding, 46, 48, 78, 79–82, 107 nullifier private key, 12 receiving key, 9, 12, 122 nullifier set, 15, 18, 42, 47, 49 RECOMMENDED, 7, 31 represented group, 26, 65, 73, 119 one-time (authenticated symmetric encryption), 21 represented pairing, 27, 70, 71, 119 one-time (signature scheme), 23 represented subgroup, 26, 27 open (a commitment), 25 root (of a Merkle tree), 17, 37, 88–91 OPTIONAL, 7, 34 RPC byte order, 18, 83 Orchard, 83, 107 outgoing cipher key, 35, 48, 61 Sapling, 1, 7–9, 12–23, 26, 27, 29, 30, 32, 34–39, 41, 42, outgoing viewing key, 12, 30, 34, 35, 48, 50, 81, 86, 116, 47–49, 52, 53, 55–58, 61, 62, 73, 75–78, 80–82, 117 83, 85–91, 98, 99, 101–122, 137, 139–142, 145–147, 149–154, 156 Output ciphertext, 48, 61, 119 segments (of a Pedersen hash input), 59 Output circuit, 83, 119, 146, 147 serial numbers (in Zerocash), 8 Output description, 8, 9, 14, 16, 17, 23, 26, 33, 34–35, 39–41, 48, 50, 52, 76, 77, 85–87, 89, 107, 116, 117, SHA-256, 55, 56, 61, 68, 82, 83, 102, 121 120, 121 SHA-256d, 55, 90, 92, 93 Output statement, 17, 29, 33, 35, 41, 45, 76, 116, 119 SHA-512, 55, 64, 108, 160 Output transfer, 16, 17, 22, 33, 39, 85, 100, 101, 103 SHA256Compress, 55, 56, 61, 68, 78–80, 103–105, 121, 123 Overwinter, 1, 7, 38, 55, 83, 84, 86–88, 91, 113, 116, 117, shielded, 8, 16, 34, 87, 100, 101 120–122 shielded input, 8, 16, 17, 36 shielded output, 8, 16, 17, 46, 47, 87, 109 packing, 139 shielded payment address, 8, 9, 12, 13, 19, 20, 35, 36, 41, paying key, 13, 36 48, 51, 52, 57, 58, 78, 79, 80, 87, 98, 104, 108, Pedersen commitment, 17, 40, 41, 58, 60, 68, 103, 120, 124, 125 121, 146, 149 shielded transfer, 8 Pedersen hash, 27, 58, 60, 68, 102, 104, 118, 120, 121, 147, SHOULD, 7, 34, 35, 40, 58, 76, 77, 87, 88, 91 149, 150 SHOULD NOT, 7, 77, 113 Pedersen value commitment, 17, 101 SIGHASH algorithm, 38 positioned note, 14, 42, 49, 102 SIGHASH transaction hash, 33, 37, 38, 40–42, 55, 85, primary input, 28, 32, 33, 42–45, 115 99, 100, 110, 116, 124 private key, 8, 9, 21, 23, 41, 51, 62, 80, 104 SIGHASH type, 38, 40, 42, 116, 126 proof authorizing key, 8, 12, 30, 42, 61 signature batch entry, 157, 158, 160 proof batch entry, 159 signature scheme, 22, 23–24, 55, 63, 65, 67, 68, 119 163

signature scheme with key monomorphism, 24, 68, transmission key, 9, 13, 14, 21, 34, 46, 47, 51, 77, 108 110 transmitted note ciphertext (Sapling), 33, 35, 48, signature scheme with re-randomizable keys, 23, 29, 49–50, 52, 89 41, 67 transmitted notes ciphertext (Sprout), 32, 34, 46, 51, 88 signing key, 22, 23–24, 38, 40, 117, 119 transparent, 8, 15–17, 38, 79, 85–87, 96–101, 113, 124 slanted text, 7 transparent address, 78 spend authorization address key, 41 transparent input, 15, 37–39, 110 spend authorization private key, 42 transparent output, 15, 39, 86, 107, 110 spend authorization randomizer, 42, 114 treestate, 15, 16–18, 31, 32, 42, 90, 91, 116, 123, 126 spend authorization signature, 14, 32, 33, 38, 39, 41, 42, 104, 114, 119 Uniform Random String, 27, 117 spend authorization signature scheme, 65, 67 unpacking, 139 Spend authorizing key, 12, 30, 61 unspent transaction output set, 17 Spend circuit, 33, 83, 119, 146, 147, 153 Spend description, 8, 16, 17, 18, 23, 26, 32, 33, 39–42, valid block chain, 15, 18, 102 52, 76, 85–87, 89, 116, 117, 120, 121 valid Equihash solution, 91, 92 Spend statement, 17, 19, 29, 32, 36, 41, 42, 44, 45, 57, 76, validating key (for a signature scheme), 22, 23–24, 116, 118 31–33, 38, 41, 64, 65, 67, 68, 74, 79, 85, 86, 89, Spend transfer, 16, 17–18, 22, 32, 37, 39, 85, 101, 102 109, 117–119, 122, 157, 160 spending key, 8, 9, 12, 13–14, 20, 29, 30, 36, 41, 42, 47, 51, value commitment, 8, 17, 23, 32, 33, 39–41, 48, 50, 89 52, 78–80, 81, 82, 82, 101, 102, 105, 107, 120, value commitment scheme, 41 124, 125 verifying key (for a zk-SNARK), 28, 29, 82, 83 Sprout, 7, 8, 12–18, 20, 21, 25, 29, 34, 36, 37, 39, 42, 46, 47, 51–53, 56, 76–82, 83, 88, 102–106, 108–122 version group ID, 86, 87, 107 statement, 17, 28, 41, 43, 105, 120, 137, 154, 156, 159 weak PRF, 104 synthetic blinding factor, 41 windowed, 68 target threshold, 90, 93, 94 windowed Pedersen commitment, 150 TAZ, 18, 19 Testnet, 18, 19, 54, 79–82, 86, 91, 92, 94, 97, 99, 100, 108, zatoshi, 13, 19, 39, 54, 95, 97, 99 111, 113, 123, 124 Zcash, 1, 7–9, 12, 16, 18, 19, 22, 28, 29, 37–39, 53, 55, 67, transaction, 8, 9, 13, 15, 16–18, 22, 23, 31–35, 37, 38, 39, 72, 75, 76, 78–80, 82, 83, 85, 87, 90, 92, 93, 40–42, 47–52, 84, 85, 86–91, 100–102, 107, 113, 99–103, 105–107, 109, 116, 124, 126 115, 116, 121, 126 zcashd, 12, 31, 65, 80, 91, 92, 94, 103, 107, 108, 110–112, 121, transaction binding validating key, 40, 86 122 transaction fee, 18, 86, 108 ZEC, 13, 18, 19 transaction value pool (Sapling), 39 Zerocash, 1, 7, 8, 20, 39, 100–106, 122, 124–126 transaction value pool (transparent), 15, 16, 31, 39, 88 zk-SNARK circuit, 58, 73, 83 transaction version number, 37, 76, 85, 86, 87–88, 107, zk-SNARK proof, 14, 16, 17, 23, 28, 32, 33, 41, 42, 76, 88, 122 89, 102–104, 116, 124 164