diff --git a/risc0-selective-privacy-poc/core/src/account.rs b/risc0-selective-privacy-poc/core/src/account.rs index f76e82c..1083ca6 100644 --- a/risc0-selective-privacy-poc/core/src/account.rs +++ b/risc0-selective-privacy-poc/core/src/account.rs @@ -47,13 +47,23 @@ pub fn hash(bytes: &[u32]) -> [u32; 8] { Impl::hash_words(bytes).as_words().try_into().unwrap() } -/// Dummy implementation -pub fn is_in_tree( - _commitment: Commitment, - _auth_path: &AuthenticationPath, - _tree_root: [u32; 8], -) -> bool { - true +pub fn is_in_tree(commitment: Commitment, path: &AuthenticationPath, root: [u32; 8]) -> bool { + const HASH_ONE: [u32; 8] = [ + 789771595, 3310634292, 3140410939, 3820475020, 3591004369, 2777006897, 1021496535, + 2588247415, + ]; + + let mut hash = HASH_ONE; + let mut current_index = commitment; + for path_value in path.iter() { + if current_index & 1 == 0 { + hash = hash_two(&hash, path_value); + } else { + hash = hash_two(path_value, &hash); + } + current_index >>= 1; + } + root == hash } /// Returns Hash(Commitment || private_key) @@ -64,7 +74,14 @@ pub fn compute_nullifier(commitment: &Commitment, private_key: &Key) -> Nullifie hash(&bytes_to_hash) } -pub fn bytes_to_words(bytes: [u8; 32]) -> [u32; 8] { +fn hash_two(left: &[u32; 8], right: &[u32; 8]) -> [u32; 8] { + let mut bytes_to_hash = [0; 16]; + bytes_to_hash[..8].copy_from_slice(left); + bytes_to_hash[8..].copy_from_slice(right); + hash(&bytes_to_hash) +} + +pub fn bytes_to_words(bytes: &[u8; 32]) -> [u32; 8] { let mut words = [0; 8]; for (i, chunk) in bytes.chunks(4).enumerate() { words[i] = u32::from_le_bytes(chunk.try_into().unwrap()); diff --git a/risc0-selective-privacy-poc/src/private_execution.rs b/risc0-selective-privacy-poc/src/private_execution.rs index 2d476f2..60a52c1 100644 --- a/risc0-selective-privacy-poc/src/private_execution.rs +++ b/risc0-selective-privacy-poc/src/private_execution.rs @@ -3,7 +3,7 @@ use rand::{rngs::OsRng, Rng}; use risc0_zkvm::{default_prover, ExecutorEnv, Receipt}; use sparse_merkle_tree::SparseMerkleTree; use toy_example_core::{ - account::{bytes_to_words, Account, Address, Commitment, Nonce, Nullifier}, + account::{bytes_to_words, Account, Address, AuthenticationPath, Commitment, Nonce, Nullifier}, input::InputVisibiility, }; use transfer_methods::{TRANSFER_ELF, TRANSFER_ID}; @@ -31,9 +31,15 @@ fn run_private_execution_of_transfer_program() { account.balance = 150; account }; + let commitment_tree = SparseMerkleTree::new([sender.commitment()].into_iter().collect()); - let root = bytes_to_words(commitment_tree.root()); - let auth_path = commitment_tree.get_authentication_path_for_value(sender.commitment()); + let root = bytes_to_words(&commitment_tree.root()); + let auth_path: Vec<[u32; 8]> = commitment_tree + .get_authentication_path_for_value(sender.commitment()) + .iter() + .map(bytes_to_words) + .collect(); + let auth_path: AuthenticationPath = auth_path.try_into().unwrap(); let balance_to_move: u128 = 3; @@ -46,7 +52,7 @@ fn run_private_execution_of_transfer_program() { let (inner_receipt, inputs_outputs) = prove_inner(&sender, &receiver, balance_to_move); let visibilities = vec![ - InputVisibiility::Private(Some((sender_private_key, [[0; 8]; 32]))), + InputVisibiility::Private(Some((sender_private_key, auth_path))), InputVisibiility::Private(None), ];