Skip to content

Commit

Permalink
fix: modify MstInclusionCircuit struct
Browse files Browse the repository at this point in the history
  • Loading branch information
enricobottazzi committed Nov 21, 2023
1 parent ac0cecd commit e3ba8e6
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 38 deletions.
2 changes: 1 addition & 1 deletion zk_prover/benches/full_solvency_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use summa_solvency::{
};

const SAMPLE_SIZE: usize = 10;
const LEVELS: usize = 15;
const LEVELS: usize = 20;
const N_ASSETS: usize = 1;
const PATH_NAME: &str = "one_asset";
const N_BYTES: usize = 14;
Expand Down
49 changes: 17 additions & 32 deletions zk_prover/src/circuits/merkle_sum_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,14 @@ use snark_verifier_sdk::CircuitExt;
///
/// # Fields
///
/// * `entry`: The entry to be verified inclusion of.
/// * `path_indices`: The boolean indices of the path elements from the leaf to the root. 0 indicates that the element is on the right to the path, 1 indicates that the element is on the left to the path. The length of this vector is LEVELS
/// * `sibling_leaf_node_hash_preimage`: The preimage of the hash that corresponds to the Sibling Leaf Node (part of the Merkle Proof).
/// * `sibling_middle_node_hash_preimages`: The preimages of the hashes that corresponds to the Sibling Middle Nodes (part of the Merkle Proof).
/// * `root`: The root of the Merkle Sum Tree
/// * `merkle_proof`: Merkle Proof of the entry to be verified inclusion of
#[derive(Clone)]
pub struct MstInclusionCircuit<const LEVELS: usize, const N_ASSETS: usize, const N_BYTES: usize>
where
[usize; N_ASSETS + 1]: Sized,
[usize; N_ASSETS + 2]: Sized,
{
pub entry: Entry<N_ASSETS>,
pub path_indices: Vec<Fp>,
pub sibling_leaf_node_hash_preimage: [Fp; N_ASSETS + 1],
pub sibling_middle_node_hash_preimages: Vec<[Fp; N_ASSETS + 2]>,
pub root: Node<N_ASSETS>,
pub merkle_proof: MerkleProof<N_ASSETS, N_BYTES>,
}

impl<const LEVELS: usize, const N_ASSETS: usize, const N_BYTES: usize> CircuitExt<Fp>
Expand All @@ -51,8 +43,11 @@ where
}
/// Returns the values of the public inputs of the circuit. Namely the leaf hash to be verified inclusion of and the root hash of the merkle sum tree.
fn instances(&self) -> Vec<Vec<Fp>> {
let mut instance = vec![self.entry.compute_leaf().hash, self.root.hash];
instance.extend_from_slice(&self.root.balances);
let mut instance = vec![
self.merkle_proof.entry.compute_leaf().hash,
self.merkle_proof.root.hash,
];
instance.extend_from_slice(&self.merkle_proof.root.balances);
vec![instance]
}
}
Expand All @@ -73,11 +68,7 @@ where
{
pub fn init_empty() -> Self {
Self {
entry: Entry::init_empty(),
path_indices: vec![Fp::zero(); LEVELS],
sibling_leaf_node_hash_preimage: [Fp::zero(); N_ASSETS + 1],
sibling_middle_node_hash_preimages: vec![[Fp::zero(); N_ASSETS + 2]; LEVELS],
root: Node::init_empty(),
merkle_proof: MerkleProof::init_empty(),
}
}

Expand All @@ -92,13 +83,7 @@ where
merkle_proof.sibling_middle_node_hash_preimages.len(),
LEVELS - 1
);
Self {
entry: merkle_proof.entry,
path_indices: merkle_proof.path_indices,
sibling_leaf_node_hash_preimage: merkle_proof.sibling_leaf_node_hash_preimage,
sibling_middle_node_hash_preimages: merkle_proof.sibling_middle_node_hash_preimages,
root: merkle_proof.root,
}
Self { merkle_proof }
}
}

Expand Down Expand Up @@ -243,7 +228,7 @@ where
// Assign the entry username to the witness
let username = self.assign_value_to_witness(
layouter.namespace(|| "assign entry username"),
big_uint_to_fp(self.entry.username_as_big_uint()),
big_uint_to_fp(self.merkle_proof.entry.username_as_big_uint()),
"entry username",
config.advices[0],
)?;
Expand All @@ -254,7 +239,7 @@ where
for i in 0..N_ASSETS {
let balance = self.assign_value_to_witness(
layouter.namespace(|| format!("assign entry balance {}", i)),
big_uint_to_fp(&self.entry.balances()[i]),
big_uint_to_fp(&self.merkle_proof.entry.balances()[i]),
"entry balance",
config.advices[1],
)?;
Expand Down Expand Up @@ -303,7 +288,7 @@ where
// Assign username from sibling leaf node hash preimage to the circuit
let sibling_leaf_node_username = self.assign_value_to_witness(
layouter.namespace(|| format!("sibling leaf node username")),
self.sibling_leaf_node_hash_preimage[0],
self.merkle_proof.sibling_leaf_node_hash_preimage[0],
"sibling leaf node username",
config.advices[0],
)?;
Expand All @@ -312,7 +297,7 @@ where
for asset in 0..N_ASSETS {
let leaf_node_sibling_balance = self.assign_value_to_witness(
layouter.namespace(|| format!("sibling leaf node balance {}", asset)),
self.sibling_leaf_node_hash_preimage[asset + 1],
self.merkle_proof.sibling_leaf_node_hash_preimage[asset + 1],
"sibling leaf balance",
config.advices[1],
)?;
Expand Down Expand Up @@ -349,7 +334,7 @@ where
for asset in 0..N_ASSETS {
let middle_node_sibling_balance = self.assign_value_to_witness(
layouter.namespace(|| format!("sibling node balance {}", asset)),
self.sibling_middle_node_hash_preimages[level - 1][asset],
self.merkle_proof.sibling_middle_node_hash_preimages[level - 1][asset],
"sibling node balance",
config.advices[1],
)?;
Expand All @@ -359,15 +344,15 @@ where
// Assign middle_node_sibling_child_left_hash from middle node hash preimage to the circuit
let middle_node_sibling_child_left_hash = self.assign_value_to_witness(
layouter.namespace(|| format!("sibling left hash")),
self.sibling_middle_node_hash_preimages[level - 1][N_ASSETS],
self.merkle_proof.sibling_middle_node_hash_preimages[level - 1][N_ASSETS],
"sibling left hash",
config.advices[2],
)?;

// Assign middle_node_sibling_child_right_hash from middle node hash preimage to the circuit
let middle_node_sibling_child_right_hash = self.assign_value_to_witness(
layouter.namespace(|| format!("sibling right hash")),
self.sibling_middle_node_hash_preimages[level - 1][N_ASSETS + 1],
self.merkle_proof.sibling_middle_node_hash_preimages[level - 1][N_ASSETS + 1],
"sibling right hash",
config.advices[2],
)?;
Expand Down Expand Up @@ -398,7 +383,7 @@ where
// For each level assign the swap bit to the circuit
let swap_bit_level = self.assign_value_to_witness(
layouter.namespace(|| format!("{}: assign swap bit", namespace_prefix)),
self.path_indices[level],
self.merkle_proof.path_indices[level],
"swap bit",
config.advices[0],
)?;
Expand Down
13 changes: 8 additions & 5 deletions zk_prover/src/circuits/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,13 @@ mod test {
let invalid_leaf_balances = [1000.to_biguint().unwrap(), 1000.to_biguint().unwrap()];

// invalidate user entry
let invalid_entry =
Entry::new(circuit.entry.username().to_string(), invalid_leaf_balances).unwrap();
let invalid_entry = Entry::new(
circuit.merkle_proof.entry.username().to_string(),
invalid_leaf_balances,
)
.unwrap();

circuit.entry = invalid_entry;
circuit.merkle_proof.entry = invalid_entry;

let invalid_prover = MockProver::run(K, &circuit, instances).unwrap();
assert_eq!(
Expand Down Expand Up @@ -289,7 +292,7 @@ mod test {
let instances = circuit.instances();

// invalidate path index inside the circuit
circuit.path_indices[0] = Fp::from(2);
circuit.merkle_proof.path_indices[0] = Fp::from(2);

let invalid_prover = MockProver::run(K, &circuit, instances).unwrap();

Expand Down Expand Up @@ -410,7 +413,7 @@ mod test {
let instances = circuit.instances();

// swap indices
circuit.path_indices[0] = Fp::from(1);
circuit.merkle_proof.path_indices[0] = Fp::from(1);

let invalid_prover = MockProver::run(K, &circuit, instances).unwrap();

Expand Down
25 changes: 25 additions & 0 deletions zk_prover/src/merkle_sum_tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ mod tree;
pub mod utils;
use halo2_proofs::halo2curves::bn256::Fr as Fp;

/// # Fields
///
/// * `entry`: The entry to be verified inclusion of.
/// * `path_indices`: The boolean indices of the path elements from the leaf to the root. 0 indicates that the element is on the right to the path, 1 indicates that the element is on the left to the path. The length of this vector is LEVELS
/// * `sibling_leaf_node_hash_preimage`: The preimage of the hash that corresponds to the Sibling Leaf Node (part of the Merkle Proof).
/// * `sibling_middle_node_hash_preimages`: The preimages of the hashes that corresponds to the Sibling Middle Nodes (part of the Merkle Proof).
/// * `root`: The root of the Merkle Sum Tree
#[derive(Clone, Debug)]
pub struct MerkleProof<const N_ASSETS: usize, const N_BYTES: usize>
where
Expand All @@ -19,6 +27,23 @@ where
pub path_indices: Vec<Fp>,
}

// Add iniit_empyt method to MerkleProof
impl<const N_ASSETS: usize, const N_BYTES: usize> MerkleProof<N_ASSETS, N_BYTES>
where
[usize; N_ASSETS + 1]: Sized,
[usize; N_ASSETS + 2]: Sized,
{
pub fn init_empty() -> MerkleProof<N_ASSETS, N_BYTES> {
MerkleProof {
entry: Entry::init_empty(),
root: Node::init_empty(),
sibling_leaf_node_hash_preimage: [Fp::zero(); N_ASSETS + 1],
sibling_middle_node_hash_preimages: Vec::new(),
path_indices: Vec::new(),
}
}
}

pub use entry::Entry;
pub use mst::MerkleSumTree;
pub use node::Node;
Expand Down

0 comments on commit e3ba8e6

Please sign in to comment.