tx.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. use bellman::groth16;
  2. use bls12_381::Bls12;
  3. use ff::{Field, PrimeField};
  4. use rand::rngs::OsRng;
  5. use std::path::Path;
  6. use drk::crypto::{
  7. coin::Coin,
  8. load_params,
  9. merkle::{CommitmentTree, IncrementalWitness},
  10. merkle_node::MerkleNode,
  11. note::{EncryptedNote, Note},
  12. nullifier::Nullifier,
  13. save_params, setup_mint_prover, setup_spend_prover,
  14. };
  15. use drk::serial::{Decodable, Encodable};
  16. use drk::state::{state_transition, ProgramState, StateUpdate};
  17. use drk::tx;
  18. struct MemoryState {
  19. // The entire merkle tree state
  20. tree: CommitmentTree<MerkleNode>,
  21. // List of all previous and the current merkle roots
  22. // This is the hashed value of all the children.
  23. merkle_roots: Vec<MerkleNode>,
  24. // Nullifiers prevent double spending
  25. nullifiers: Vec<Nullifier>,
  26. // All received coins
  27. // NOTE: we need maybe a flag to keep track of which ones are spent
  28. // Maybe the spend field links to a tx hash:input index
  29. // We should also keep track of the tx hash:output index where this
  30. // coin was received
  31. own_coins: Vec<(Coin, Note, jubjub::Fr, IncrementalWitness<MerkleNode>)>,
  32. // Mint verifying key used by ZK
  33. mint_pvk: groth16::PreparedVerifyingKey<Bls12>,
  34. // Spend verifying key used by ZK
  35. spend_pvk: groth16::PreparedVerifyingKey<Bls12>,
  36. // Public key of the cashier
  37. cashier_public: jubjub::SubgroupPoint,
  38. // List of all our secret keys
  39. secrets: Vec<jubjub::Fr>,
  40. }
  41. impl ProgramState for MemoryState {
  42. fn is_valid_cashier_public_key(&self, public: &jubjub::SubgroupPoint) -> bool {
  43. public == &self.cashier_public
  44. }
  45. fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
  46. self.merkle_roots.iter().any(|m| *m == *merkle_root)
  47. }
  48. fn nullifier_exists(&self, nullifier: &Nullifier) -> bool {
  49. self.nullifiers.iter().any(|n| n.repr == nullifier.repr)
  50. }
  51. fn mint_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  52. &self.mint_pvk
  53. }
  54. fn spend_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
  55. &self.spend_pvk
  56. }
  57. }
  58. impl MemoryState {
  59. fn apply(&mut self, mut update: StateUpdate) {
  60. // Extend our list of nullifiers with the ones from the update
  61. self.nullifiers.append(&mut update.nullifiers);
  62. // Update merkle tree and witnesses
  63. for (coin, enc_note) in update.coins.into_iter().zip(update.enc_notes.into_iter()) {
  64. // Add the new coins to the merkle tree
  65. let node = MerkleNode::from_coin(&coin);
  66. self.tree.append(node).expect("Append to merkle tree");
  67. // Keep track of all merkle roots that have existed
  68. self.merkle_roots.push(self.tree.root());
  69. // Also update all the coin witnesses
  70. for (_, _, _, witness) in self.own_coins.iter_mut() {
  71. witness.append(node).expect("append to witness");
  72. }
  73. if let Some((note, secret)) = self.try_decrypt_note(enc_note) {
  74. // We need to keep track of the witness for this coin.
  75. // This allows us to prove inclusion of the coin in the merkle tree with ZK.
  76. // Just as we update the merkle tree with every new coin, so we do the same with
  77. // the witness.
  78. // Derive the current witness from the current tree.
  79. // This is done right after we add our coin to the tree (but before any other
  80. // coins are added)
  81. // Make a new witness for this coin
  82. let witness = IncrementalWitness::from_tree(&self.tree);
  83. self.own_coins.push((coin, note, secret, witness));
  84. }
  85. }
  86. }
  87. fn try_decrypt_note(&self, ciphertext: EncryptedNote) -> Option<(Note, jubjub::Fr)> {
  88. // Loop through all our secret keys...
  89. for secret in &self.secrets {
  90. // ... attempt to decrypt the note ...
  91. match ciphertext.decrypt(secret) {
  92. Ok(note) => {
  93. // ... and return the decrypted note for this coin.
  94. return Some((note, secret.clone()));
  95. }
  96. Err(_) => {}
  97. }
  98. }
  99. // We weren't able to decrypt the note with any of our keys.
  100. None
  101. }
  102. }
  103. fn main() {
  104. // Auto create trusted ceremony parameters if they don't exist
  105. if !Path::new("mint.params").exists() {
  106. let params = setup_mint_prover();
  107. save_params("mint.params", &params).unwrap();
  108. }
  109. if !Path::new("spend.params").exists() {
  110. let params = setup_spend_prover();
  111. save_params("spend.params", &params).unwrap();
  112. }
  113. // Load trusted setup parameters
  114. let (mint_params, mint_pvk) = load_params("mint.params").expect("params should load");
  115. let (spend_params, spend_pvk) = load_params("spend.params").expect("params should load");
  116. // Cashier creates a secret key
  117. let cashier_secret = jubjub::Fr::random(&mut OsRng);
  118. // This is their public key
  119. let cashier_public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * cashier_secret;
  120. // Wallet 1 creates a secret key
  121. let secret = jubjub::Fr::random(&mut OsRng);
  122. // This is their public key
  123. let public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
  124. let mut state = MemoryState {
  125. tree: CommitmentTree::empty(),
  126. merkle_roots: vec![],
  127. nullifiers: vec![],
  128. own_coins: vec![],
  129. mint_pvk,
  130. spend_pvk,
  131. cashier_public,
  132. secrets: vec![secret.clone()],
  133. };
  134. // Step 1: Cashier deposits to wallet1's address
  135. // Create the deposit for 110 BTC
  136. // Clear inputs are visible to everyone on the network
  137. let builder = tx::TransactionBuilder {
  138. clear_inputs: vec![tx::TransactionBuilderClearInputInfo {
  139. value: 110,
  140. signature_secret: cashier_secret,
  141. }],
  142. inputs: vec![],
  143. outputs: vec![tx::TransactionBuilderOutputInfo { value: 110, public }],
  144. };
  145. // We will 'compile' the tx, and then serialize it to this Vec<u8>
  146. let mut tx_data = vec![];
  147. {
  148. // Build the tx
  149. let tx = builder.build(&mint_params, &spend_params);
  150. // Now serialize it
  151. tx.encode(&mut tx_data).expect("encode tx");
  152. }
  153. // Step 1 is completed.
  154. // Tx data is posted to the blockchain
  155. // Step 2: wallet1 receive's payment from the cashier
  156. // Wallet1 is receiving tx, and for every new coin it finds, it adds to its
  157. // merkle tree
  158. {
  159. // Here we simulate 5 fake random coins, adding them to our tree.
  160. let tree = &mut state.tree;
  161. for _i in 0..5 {
  162. // Don't worry about any of the code in this block
  163. // We're just filling the tree with fake coins
  164. let cmu = MerkleNode::new(bls12_381::Scalar::random(&mut OsRng).to_repr());
  165. tree.append(cmu).unwrap();
  166. let root = tree.root();
  167. state.merkle_roots.push(root.into());
  168. }
  169. }
  170. // Now we receive the tx data
  171. {
  172. let tx = tx::Transaction::decode(&tx_data[..]).unwrap();
  173. let update = state_transition(&state, tx).expect("step 2 state transition failed");
  174. // Our state impl is memory online for this demo
  175. // but in the real version, this function will be async
  176. // and using the databases.
  177. state.apply(update);
  178. }
  179. // Wallet1 has received payment from the cashier.
  180. // Step 2 is complete.
  181. assert_eq!(state.own_coins.len(), 1);
  182. //let (coin, note, secret, witness) = &mut state.own_coins[0];
  183. let merkle_path = {
  184. let tree = &mut state.tree;
  185. let (coin, _, _, witness) = &mut state.own_coins[0];
  186. // Check this is the 6th coin we added
  187. assert_eq!(witness.position(), 5);
  188. assert_eq!(tree.root(), witness.root());
  189. // Add some more random coins in
  190. for _i in 0..10 {
  191. // Don't worry about any of the code in this block
  192. // We're just filling the tree with fake coins
  193. let cmu = MerkleNode::new(bls12_381::Scalar::random(&mut OsRng).to_repr());
  194. tree.append(cmu).unwrap();
  195. witness.append(cmu).unwrap();
  196. assert_eq!(tree.root(), witness.root());
  197. let root = tree.root();
  198. state.merkle_roots.push(root.into());
  199. }
  200. assert_eq!(state.merkle_roots.len(), 16);
  201. // This is the value we need to spend the coin
  202. // We use the witness and the merkle root (both in sync with each other)
  203. // to prove our coin exists inside the tree.
  204. // The coin is not revealed publicly but is proved to exist inside
  205. // a merkle tree. Only the root will be revealed, and then the
  206. // verifier checks that merkle root actually existed before.
  207. let merkle_path = witness.path().unwrap();
  208. // Just test the path is good because we just added a bunch of fake coins
  209. let node = MerkleNode::from_coin(&coin);
  210. let root = tree.root();
  211. drop(tree);
  212. drop(witness);
  213. assert_eq!(merkle_path.root(node), root);
  214. let root = root.into();
  215. assert!(state.is_valid_merkle(&root));
  216. merkle_path
  217. };
  218. // Step 3: wallet1 sends payment to wallet2
  219. // Wallet1 now wishes to send the coin to wallet2
  220. // The receiving wallet has a secret key
  221. let secret2 = jubjub::Fr::random(&mut OsRng);
  222. // This is their public key to receive payment
  223. let public2 = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret2;
  224. // Make a spend tx
  225. // Construct a new tx spending the coin
  226. // We need the decrypted note and our private key
  227. let builder = tx::TransactionBuilder {
  228. clear_inputs: vec![],
  229. inputs: vec![tx::TransactionBuilderInputInfo {
  230. merkle_path,
  231. secret: secret.clone(),
  232. note: state.own_coins[0].1.clone(),
  233. }],
  234. // We can add more outputs to this list.
  235. // The only constraint is that sum(value in) == sum(value out)
  236. outputs: vec![tx::TransactionBuilderOutputInfo {
  237. value: 110,
  238. public: public2,
  239. }],
  240. };
  241. // Build the tx
  242. let mut tx_data = vec![];
  243. {
  244. let tx = builder.build(&mint_params, &spend_params);
  245. tx.encode(&mut tx_data).expect("encode tx");
  246. }
  247. // Verify it's valid
  248. {
  249. let tx = tx::Transaction::decode(&tx_data[..]).unwrap();
  250. let update = state_transition(&state, tx).expect("step 3 state transition failed");
  251. state.apply(update);
  252. }
  253. }