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 12, 2024
1 parent a421532 commit 76f5435
Show file tree
Hide file tree
Showing 21 changed files with 1,131 additions and 517 deletions.
63 changes: 63 additions & 0 deletions barretenberg/cpp/pil/avm/gadgets/merkle_tree.pil
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
include "./poseidon2_full.pil";

// Returns 1 or 0 (true / false) if the leaf value is at the leaf index of a given tree
namespace merkle_tree(256);

pol commit sel_merkle_tree;
// 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
pol commit is_member;

// 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;
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;
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;
pol 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 DIFF == 0
LAST_COMPUTE * (DIFF * (is_member * (1 - diff_inv) + diff_inv) - 1 + is_member) = 0;

#[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: 1 addition & 1 deletion barretenberg/cpp/pil/avm/gadgets/poseidon2.pil
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace poseidon2(256);
sel_poseidon_perm_immediate * (1 - sel_poseidon_perm_immediate) = 0;

// If poseidon perm is active, it must be either a mem op or immediate but not both
sel_poseidon_perm * (1 - sel_poseidon_perm_mem_op + sel_poseidon_perm_immediate) = 0;
sel_poseidon_perm * (1 - sel_poseidon_perm_mem_op - sel_poseidon_perm_immediate) = 0;
// If inactive the mem op or immediate selectors must be 0
(1 - sel_poseidon_perm) * (sel_poseidon_perm_mem_op + sel_poseidon_perm_immediate) = 0;

Expand Down
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 @@ -85,3 +85,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 @@ -13,6 +13,7 @@ include "gadgets/poseidon2_full.pil";
include "gadgets/keccakf1600.pil";
include "gadgets/pedersen.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 @@ -351,6 +351,21 @@ 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_merkle_tree.set_if_valid_index(i, rows[i].merkle_tree_sel_merkle_tree);
polys.merkle_tree_sibling_value.set_if_valid_index(i, rows[i].merkle_tree_sibling_value);
polys.pedersen_clk.set_if_valid_index(i, rows[i].pedersen_clk);
polys.pedersen_input.set_if_valid_index(i, rows[i].pedersen_input);
polys.pedersen_output.set_if_valid_index(i, rows[i].pedersen_output);
Expand Down Expand Up @@ -646,6 +661,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 76f5435

Please sign in to comment.