tx.rs 11 KB

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