zk-inclusion-proof.rs
1 /* This file is part of DarkFi (https://dark.fi) 2 * 3 * Copyright (C) 2020-2022 Dyne.org foundation 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Affero General Public License as 7 * published by the Free Software Foundation, either version 3 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Affero General Public License for more details. 14 * 15 * You should have received a copy of the GNU Affero General Public License 16 * along with this program. If not, see <https://www.gnu.org/licenses/>. 17 */ 18 19 // ../zkas simple.zk 20 21 use darkfi::{ 22 zk::{ 23 proof::{Proof, ProvingKey, VerifyingKey}, 24 vm::{Witness, ZkCircuit}, 25 vm_heap::empty_witnesses, 26 }, 27 zkas::decoder::ZkBinary, 28 Result, 29 }; 30 use darkfi_sdk::{ 31 bridgetree::Hashable, 32 crypto::{poseidon_hash, MerkleNode, MerkleTree}, 33 pasta::{group::ff::Field, pallas}, 34 }; 35 use darkfi_serial::Encodable; 36 use halo2_proofs::circuit::Value; 37 use rand::rngs::OsRng; 38 39 fn main() -> Result<()> { 40 let mut tree = MerkleTree::new(1); 41 42 // Add 10 random things to the tree 43 for _ in 0..10 { 44 let random_leaf = pallas::Base::random(&mut OsRng); 45 let node = MerkleNode::from(random_leaf); 46 tree.append(node); 47 } 48 49 let leaf = pallas::Base::random(&mut OsRng); 50 let node = MerkleNode::from(leaf); 51 tree.append(node); 52 53 let leaf_position = tree.mark().unwrap(); 54 55 // Add 10 more random things to the tree 56 for _ in 0..10 { 57 let random_leaf = pallas::Base::random(&mut OsRng); 58 let node = MerkleNode::from(random_leaf); 59 tree.append(node); 60 } 61 62 // Now begin zk proof API 63 let bincode = include_bytes!("../proof/inclusion_proof.zk.bin"); 64 let zkbin = ZkBinary::decode(bincode)?; 65 66 // ====== 67 // Prover 68 // ====== 69 // Bigger k = more rows, but slower circuit 70 // Number of rows is 2^k 71 let k = zkbin.k; 72 println!("k = {}", k); 73 74 // Witness values 75 let merkle_path = tree.witness(leaf_position, 0).unwrap(); 76 let leaf_position: u64 = leaf_position.into(); 77 let blind = pallas::Base::random(&mut OsRng); 78 79 let prover_witnesses = vec![ 80 Witness::Base(Value::known(leaf)), 81 Witness::Uint32(Value::known(leaf_position.try_into().unwrap())), 82 Witness::MerklePath(Value::known(merkle_path.clone().try_into().unwrap())), 83 Witness::Base(Value::known(blind)), 84 ]; 85 86 // Create the public inputs 87 let merkle_root = { 88 let position: u64 = leaf_position.into(); 89 let mut current = MerkleNode::from(leaf); 90 for (level, sibling) in merkle_path.iter().enumerate() { 91 let level = level as u8; 92 current = if position & (1 << level) == 0 { 93 MerkleNode::combine(level.into(), ¤t, sibling) 94 } else { 95 MerkleNode::combine(level.into(), sibling, ¤t) 96 }; 97 } 98 current 99 }; 100 101 let enc_leaf = poseidon_hash([leaf, blind]); 102 let public_inputs = vec![merkle_root.inner(), enc_leaf]; 103 104 // Create the circuit 105 let circuit = ZkCircuit::new(prover_witnesses, &zkbin.clone()); 106 107 let now = std::time::Instant::now(); 108 let proving_key = ProvingKey::build(k, &circuit); 109 println!("ProvingKey built [{} s]", now.elapsed().as_secs_f64()); 110 let now = std::time::Instant::now(); 111 let proof = Proof::create(&proving_key, &[circuit], &public_inputs, &mut OsRng)?; 112 println!("Proof created [{} s]", now.elapsed().as_secs_f64()); 113 114 // ======== 115 // Verifier 116 // ======== 117 118 // Construct empty witnesses 119 let verifier_witnesses = empty_witnesses(&zkbin)?; 120 121 // Create the circuit 122 let circuit = ZkCircuit::new(verifier_witnesses, &zkbin); 123 124 let now = std::time::Instant::now(); 125 let verifying_key = VerifyingKey::build(k, &circuit); 126 println!("VerifyingKey built [{} s]", now.elapsed().as_secs_f64()); 127 let now = std::time::Instant::now(); 128 proof.verify(&verifying_key, &public_inputs)?; 129 println!("proof verify [{} s]", now.elapsed().as_secs_f64()); 130 131 let mut data = vec![]; 132 proof.encode(&mut data)?; 133 println!("proof size: {}", data.len()); 134 135 Ok(()) 136 }