Skip to content

Commit

Permalink
feat(avm): merkle tree gadget
Browse files Browse the repository at this point in the history
  • Loading branch information
IlyasRidhuan committed Oct 24, 2024
1 parent 07d6dc2 commit 8f022b7
Show file tree
Hide file tree
Showing 19 changed files with 1,231 additions and 515 deletions.
76 changes: 76 additions & 0 deletions barretenberg/cpp/pil/avm/gadgets/merkle_tree.pil
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
include "./poseidon2_full.pil";

// Handles membership and insertion into a merkle tree
namespace merkle_tree(256);

pol commit sel_merkle_tree;
sel_merkle_tree * (1 - sel_merkle_tree) = 0;
// Will probably used in permutation with other traces
pol commit sel_update_op;
sel_update_op * (1 - sel_update_op) = 0;
pol commit sel_membership_op;
sel_membership_op * (1 - sel_membership_op) = 0;
// Gotta stop using clk for things that are more like foreign keys
pol commit clk;
// Inputs to the gadget
pol commit leaf_value;
pol commit leaf_index;
pol commit path_len;
pol commit expected_tree_root;
// Output of the gadget
// Boolean result of the membership check
pol commit is_member;
is_member * (1 - is_member) = 0;

// These are all hinted
pol commit sibling_value;

// If we are not done, the path_len decrements by 1
sel_merkle_tree * (1 - latch) * (path_len' - path_len + 1) = 0;

pol commit latch;
latch * (1 - latch) = 0;
pol commit path_len_inv;
// latch == 1 when the path_len == 0
sel_merkle_tree * (path_len * (latch * (1 - path_len_inv) + path_len_inv) - 1 + latch) = 0;

pol commit leaf_index_is_even;
leaf_index_is_even * (1 - leaf_index_is_even) = 0;
pol LEAF_INDEX_IS_ODD = (1 - leaf_index_is_even);
// If we are not done, the next leaf index is half the current leaf index;
sel_merkle_tree * (1 - latch) * (leaf_index' * 2 + LEAF_INDEX_IS_ODD - leaf_index) = 0;

// These are what are sent to poseidon2
// These arrange the leaf_value and sibling_value in the correct order
pol commit left_hash;
pol commit right_hash;
// I dont think these can be safely combined
// if the leaf index is even, the leaf value is the left hash and the sibling value is the right hash
// vice-versa
sel_merkle_tree * (leaf_index_is_even * (left_hash - leaf_value) + LEAF_INDEX_IS_ODD * (right_hash - leaf_value)) = 0;
sel_merkle_tree * (leaf_index_is_even * (right_hash - sibling_value) + LEAF_INDEX_IS_ODD * (left_hash - sibling_value)) = 0;
pol commit output_hash;

// If we are not done, the output hash is the next value in
sel_merkle_tree * (1 - latch) * (leaf_value' - output_hash) = 0;

pol LAST_COMPUTE = sel_merkle_tree * latch;

// Membership check
pol ROOT_DIFF = output_hash - expected_tree_root;
// Need an additional helper that holds the inverse of the difference;
pol commit diff_inv;
// is_member == 1 if ROOT_DIFF == 0
sel_membership_op * LAST_COMPUTE * (ROOT_DIFF * (is_member * (1 - diff_inv) + diff_inv) - 1 + is_member) = 0;

// Permutation to the full poseidon2 gadget
#[PERM_MERKLE_POSEIDON2]
sel_merkle_tree { clk, left_hash, right_hash, output_hash } is
poseidon2_full.sel_merkle_tree {poseidon2_full.clk, poseidon2_full.input_0, poseidon2_full.input_1, poseidon2_full.output };







2 changes: 2 additions & 0 deletions barretenberg/cpp/pil/avm/gadgets/poseidon2_full.pil
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,5 @@ namespace poseidon2_full(256);
{ poseidon2.clk, poseidon2.a_0, poseidon2.a_1, poseidon2.a_2, poseidon2.a_3,
poseidon2.b_0, poseidon2.b_1, poseidon2.b_2, poseidon2.b_3 };

// ======== Merkle Tree Selector ======================
pol commit sel_merkle_tree;
1 change: 1 addition & 0 deletions barretenberg/cpp/pil/avm/main.pil
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ include "gadgets/poseidon2.pil";
include "gadgets/poseidon2_full.pil";
include "gadgets/keccakf1600.pil";
include "gadgets/mem_slice.pil";
include "gadgets/merkle_tree.pil";

namespace main(256);
//===== CONSTANT POLYNOMIALS ==================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,23 @@ AvmCircuitBuilder::ProverPolynomials AvmCircuitBuilder::compute_polynomials() co
polys.mem_tsp.set_if_valid_index(i, rows[i].mem_tsp);
polys.mem_val.set_if_valid_index(i, rows[i].mem_val);
polys.mem_w_in_tag.set_if_valid_index(i, rows[i].mem_w_in_tag);
polys.merkle_tree_clk.set_if_valid_index(i, rows[i].merkle_tree_clk);
polys.merkle_tree_diff_inv.set_if_valid_index(i, rows[i].merkle_tree_diff_inv);
polys.merkle_tree_expected_tree_root.set_if_valid_index(i, rows[i].merkle_tree_expected_tree_root);
polys.merkle_tree_is_member.set_if_valid_index(i, rows[i].merkle_tree_is_member);
polys.merkle_tree_latch.set_if_valid_index(i, rows[i].merkle_tree_latch);
polys.merkle_tree_leaf_index.set_if_valid_index(i, rows[i].merkle_tree_leaf_index);
polys.merkle_tree_leaf_index_is_even.set_if_valid_index(i, rows[i].merkle_tree_leaf_index_is_even);
polys.merkle_tree_leaf_value.set_if_valid_index(i, rows[i].merkle_tree_leaf_value);
polys.merkle_tree_left_hash.set_if_valid_index(i, rows[i].merkle_tree_left_hash);
polys.merkle_tree_output_hash.set_if_valid_index(i, rows[i].merkle_tree_output_hash);
polys.merkle_tree_path_len.set_if_valid_index(i, rows[i].merkle_tree_path_len);
polys.merkle_tree_path_len_inv.set_if_valid_index(i, rows[i].merkle_tree_path_len_inv);
polys.merkle_tree_right_hash.set_if_valid_index(i, rows[i].merkle_tree_right_hash);
polys.merkle_tree_sel_membership_op.set_if_valid_index(i, rows[i].merkle_tree_sel_membership_op);
polys.merkle_tree_sel_merkle_tree.set_if_valid_index(i, rows[i].merkle_tree_sel_merkle_tree);
polys.merkle_tree_sel_update_op.set_if_valid_index(i, rows[i].merkle_tree_sel_update_op);
polys.merkle_tree_sibling_value.set_if_valid_index(i, rows[i].merkle_tree_sibling_value);
polys.poseidon2_B_10_0.set_if_valid_index(i, rows[i].poseidon2_B_10_0);
polys.poseidon2_B_10_1.set_if_valid_index(i, rows[i].poseidon2_B_10_1);
polys.poseidon2_B_10_2.set_if_valid_index(i, rows[i].poseidon2_B_10_2);
Expand Down Expand Up @@ -639,6 +656,7 @@ AvmCircuitBuilder::ProverPolynomials AvmCircuitBuilder::compute_polynomials() co
i, rows[i].poseidon2_full_num_perm_rounds_rem_inv);
polys.poseidon2_full_output.set_if_valid_index(i, rows[i].poseidon2_full_output);
polys.poseidon2_full_padding.set_if_valid_index(i, rows[i].poseidon2_full_padding);
polys.poseidon2_full_sel_merkle_tree.set_if_valid_index(i, rows[i].poseidon2_full_sel_merkle_tree);
polys.poseidon2_full_sel_poseidon.set_if_valid_index(i, rows[i].poseidon2_full_sel_poseidon);
polys.poseidon2_full_start_poseidon.set_if_valid_index(i, rows[i].poseidon2_full_start_poseidon);
polys.poseidon2_input_addr.set_if_valid_index(i, rows[i].poseidon2_input_addr);
Expand Down
Loading

0 comments on commit 8f022b7

Please sign in to comment.