diff --git a/zk_prover/src/merkle_sum_tree/mod.rs b/zk_prover/src/merkle_sum_tree/mod.rs index 0c6b631f..db7b43b7 100644 --- a/zk_prover/src/merkle_sum_tree/mod.rs +++ b/zk_prover/src/merkle_sum_tree/mod.rs @@ -6,11 +6,18 @@ mod tree; pub mod utils; use halo2_proofs::halo2curves::bn256::Fr as Fp; +/// A struct representing a Merkle Proof. +/// +/// Fields: +/// * `entry`: The entry for which the proof is generated +/// * `root`: The root of the Merkle Sum Tree +/// * `sibling_leaf_node_hash_preimage`: The hash preimage of the sibling leaf node. The hash preimage is equal to `[sibling_username, sibling.balance[0], sibling.balance[1], ... sibling.balance[N_ASSETS - 1]]` +/// * `sibling_middle_node_hash_preimages`: The hash preimages of the sibling middle nodes. The hash preimage is equal to `[sibling_left_child.balance[0] + sibling_right_child.balance[0], sibling_left_child.balance[1] + sibling_right_child.balance[1], ..., sibling_left_child.balance[N_ASSETS - 1] + sibling_right_child.balance[N_ASSETS - 1], sibling_left_child.hash, sibling_right_child.hash]` #[derive(Clone, Debug)] pub struct MerkleProof where [usize; N_ASSETS + 1]: Sized, - [usize; N_ASSETS + 2]: Sized, + [usize; N_ASSETS + 2]: Sized, { pub entry: Entry, pub root: Node, diff --git a/zk_prover/src/merkle_sum_tree/mst.rs b/zk_prover/src/merkle_sum_tree/mst.rs index 64b0150b..d658ad16 100644 --- a/zk_prover/src/merkle_sum_tree/mst.rs +++ b/zk_prover/src/merkle_sum_tree/mst.rs @@ -8,8 +8,8 @@ use num_bigint::BigUint; /// /// A Merkle Sum Tree is a binary Merkle Tree with the following properties: /// * Each Entry of a Merkle Sum Tree is a pair of a username and #N_ASSETS balances. -/// * Each Leaf Node contains a hash and #N_ASSETS balances. The hash is equal to `H(username, balance[0], balance[1], ... balance[N_ASSETS])`. The balances are equal to the balances associated to the entry -/// * Each Middle Node contains a hash and #N_ASSETS balances. The hash is equal to `H(LeftChild.balance[0] + RightChild.balance[0], LeftChild.balance[1] + RightChild.balance[1], ..., LeftChild.balance[N_ASSETS] + RightChild.balance[N_ASSETS], LeftChild.hash, RightChild.hash)`. The balances are equal to the sum of the balances of the child nodes per each asset. +/// * Each Leaf Node contains a hash and #N_ASSETS balances. The hash is equal to `H(username, balance[0], balance[1], ... balance[N_ASSETS - 1])`. The balances are equal to the balances associated to the entry +/// * Each Middle Node contains a hash and #N_ASSETS balances. The hash is equal to `H(LeftChild.balance[0] + RightChild.balance[0], LeftChild.balance[1] + RightChild.balance[1], ..., LeftChild.balance[N_ASSETS - 1] + RightChild.balance[N_ASSETS - 1], LeftChild.hash, RightChild.hash)`. The balances are equal to the sum of the balances of the child nodes per each asset. /// * The Root Node represents the committed state of the Tree and contains the sum of all the entries' balances per each asset. /// /// # Type Parameters diff --git a/zk_prover/src/merkle_sum_tree/node.rs b/zk_prover/src/merkle_sum_tree/node.rs index 519e4d1f..0185377c 100644 --- a/zk_prover/src/merkle_sum_tree/node.rs +++ b/zk_prover/src/merkle_sum_tree/node.rs @@ -10,7 +10,35 @@ pub struct Node { pub balances: [Fp; N_ASSETS], } impl Node { + /// Builds a leaf-level node of the MST + /// The leaf node hash is equal to `H(username, balance[0], balance[1], ... balance[N_ASSETS - 1])` + /// The balances are equal to `balance[0], balance[1], ... balance[N_ASSETS - 1]` + pub fn leaf(username: &BigUint, balances: &[BigUint; N_ASSETS]) -> Node + where + [usize; N_ASSETS + 1]: Sized, + { + Node { + hash: Self::poseidon_hash_leaf( + big_uint_to_fp(username), + balances + .iter() + .map(big_uint_to_fp) + .collect::>() + .try_into() + .unwrap(), + ), + //Map the array of balances using big_int_to_fp: + balances: balances + .iter() + .map(big_uint_to_fp) + .collect::>() + .try_into() + .unwrap(), + } + } /// Builds a "middle" (non-leaf-level) node of the MST + /// The middle node hash is equal to `H(LeftChild.balance[0] + RightChild.balance[0], LeftChild.balance[1] + RightChild.balance[1], ..., LeftChild.balance[N_ASSETS - 1] + RightChild.balance[N_ASSETS - 1], LeftChild.hash, RightChild.hash)` + /// The balances are equal to `LeftChild.balance[0] + RightChild.balance[0], LeftChild.balance[1] + RightChild.balance[1], ..., LeftChild.balance[N_ASSETS - 1] + RightChild.balance[N_ASSETS - 1]` pub fn middle(child_l: &Node, child_r: &Node) -> Node where [(); N_ASSETS + 2]: Sized, @@ -36,31 +64,6 @@ impl Node { } } - /// Builds a leaf-level node of the MST - pub fn leaf(username: &BigUint, balances: &[BigUint; N_ASSETS]) -> Node - where - [usize; N_ASSETS + 1]: Sized, - { - Node { - hash: Self::poseidon_hash_leaf( - big_uint_to_fp(username), - balances - .iter() - .map(big_uint_to_fp) - .collect::>() - .try_into() - .unwrap(), - ), - //Map the array of balances using big_int_to_fp: - balances: balances - .iter() - .map(big_uint_to_fp) - .collect::>() - .try_into() - .unwrap(), - } - } - pub fn leaf_node_from_preimage(preimage: [Fp; N_ASSETS + 1]) -> Node where [usize; N_ASSETS + 1]: Sized,