diff --git a/barretenberg/cpp/pil/vm2/merkle_check.pil b/barretenberg/cpp/pil/vm2/merkle_check.pil index d28f06b857de..e12e4aff8ab7 100644 --- a/barretenberg/cpp/pil/vm2/merkle_check.pil +++ b/barretenberg/cpp/pil/vm2/merkle_check.pil @@ -2,44 +2,51 @@ include "./poseidon2_hash.pil"; include "./precomputed.pil"; /** - * A merkle membership check to compute a root from a leaf and sibling path. - * One sibling pair is processed per row. + * A gadget that checks a merkle read or a write. + * One sibling node is processed per row, performing 1 hash if it's a merkle read + * or 2 hashes if it's a merkle write. * * WARNING: This gadget will break if used with `tree_height >= 254` * - * Usage: - * caller_sel { leaf, leaf_index, tree_height, expected_root } - * in merkle_check.end { merkle_check.leaf, merkle_check.leaf_index, merkle_check.tree_height, merkle_check.output_hash } + * Read usage: + * caller_sel { read_leaf, leaf_index, tree_height, expected_root } + * in merkle_check.start { merkle_check.read_node, merkle_check.index, merkle_check.path_len, merkle_check.read_root } * - * Inputs (stay constant for all rows in a single merkle check) - * @column leaf The value of the leaf being checked. - * @column leaf_index The index of the leaf being checked. - * @column tree_height The height from leaf not including root. + * Write usage: + * caller_sel { one, prev_leaf_value, next_leaf_value, + * leaf_index, tree_height, prev_root, next_root } + * in merkle_check.start { merkle_check.write, merkle_check.read_node, merkle_check.write_node, + * merkle_check.index, merkle_check.path_len, merkle_check.read_root, merkle_check.write_root } * - * Outputs - * @column output_hash The hash of the current node and sibling. When `end == 1`, this is the root. + * Common inputs + * @column read_node The value of the node being read. When `start == 1`, this is the leaf. + * @column index The index of the node being operated on. When `start == 1`, this is the leaf index. + * @column path_len The size of the path at this layer. When `start == 1`, this is the tree height. + * @column read_root The merkle root the value is read from. This will be propagated down to be matched internally on `end`. + * + * Write specific inputs + * @column write Whether this is a write operation. + * @column write_node The value of the node being written. When `start == 1`, this is the new leaf. + * @column write_root The merkle root that results of replacing the leaf with the new leaf at the index provided in the read_root. This will be propagated down to be matched internally on `end`. * * Internals/hints - * @column current_node The value of the current node being processed (alongside its `sibling`). When `end == 0`, the next `current_node` is the `output_hash` of the current row. - * @column current_index_in_layer The index of the current node in the current layer. This is halved each layer until `end == 1`. Constrained to be 0 or 1 on end. - * @column remaining_path_len The remaining path len to process, not including this layer. Starts at `tree_height - 1`, and decrements per layer until `end == 1`. When this is 0, `output_hash` is the root. - * @column sibling The value of the sibling node to be hashed with `current_node`. + * @column sibling The value of the sibling node to be hashed with `read_node`. * @column index_is_even Whether the current index is even. * * Interactions - * @lookup to `poseidon2_hash` to constrain that `hash(left_node, right_node) == output_hash` for the current layer - * - * <--inputs propagated down-----> - * +------+----------+-------------+--------------+---------------+--------------+---------+-------+-----+---------------+-----------+------------+-------------+ - * | leaf | leaf_idx | tree_height | current_node | current_index | rem_path_len | sibling | start | end | index_is_even | left_node | right_node | output_hash | - * +------+----------+-------------+--------------+---------------+--------------+---------+-------+-----+---------------+-----------+------------+-------------+ - * | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | - * | 27 | 42 | 4 | 27 | 42 | 3 | s0 | 1 | 0 | 1 | 27 | s0 | h(27,s0) | - * | 27 | 42 | 4 | n1 | 21 | 2 | s1 | 0 | 0 | 0 | s1 | n1 | h(s1,n1) | - * | 27 | 42 | 4 | n2 | 10 | 1 | s2 | 0 | 0 | 1 | n2 | s2 | h(n2,s2) | - * | 27 | 42 | 4 | n3 | 5 | 0 | s3 | 0 | 1 | 0 | s3 | n3 | h(s3,n3) | - * | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | - * +------+----------+-------------+--------------+---------------+--------------+---------+-------+-----+---------------+-----------+------------+-------------+ + * @lookup to `poseidon2_hash` to constrain that `hash(read_left_node, read_right_node) == read_output_hash` for the current layer + * @lookup to `poseidon2_hash` to constrain that `hash(write_left_node, write_right_node) == write_output_hash` for the current layer. Only active when write is on. + * <----------------------------------------write only--------------------------------------> + * +-----------+-------+----------+---------+---------------+----------------+-----------------+------------------+-----------+-------+------------+-----------------+------------------+-------------------+------------+-------+-----+-----+ + * | read_node | index | path_len | sibling | index_is_even | read_left_node | read_right_node | read_output_hash | read_root | write | write_node | write_left_node | write_right_node | write_output_hash | write_root | start | end | sel | + * +-----------+-------+----------+---------+---------------+----------------+-----------------+------------------+-----------+-------+------------+-----------------+------------------+-------------------+------------+-------+-----+-----+ + * | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + * | 27 | 10 | 4 | s0 | 1 | 27 | s0 | h(27,s0)=n1 | n4 | 1 | 28 | 28 | s0 | h(28,s0)=n5 | n8 | 1 | 0 | 1 | + * | n1 | 5 | 3 | s1 | 0 | s1 | n1 | h(s1,n1)=n2 | n4 | 1 | n5 | s1 | n5 | h(s1,n5)=n6 | n8 | 0 | 0 | 1 | + * | n2 | 2 | 2 | s2 | 1 | n2 | s2 | h(n2,s2)=n3 | n4 | 1 | n6 | n6 | s2 | h(n6,s2)=n7 | n8 | 0 | 0 | 1 | + * | n3 | 1 | 1 | s3 | 0 | s3 | n3 | h(s3,n3)=n4 | n4 | 1 | n7 | s3 | n7 | h(s3,n7)=n8 | n8 | 0 | 1 | 1 | + * | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | + * +-----------+-------+----------+---------+---------------+----------------+-----------------+------------------+-----------+-------+------------+-----------------+------------------+-------------------+------------+-------+-----+-----+ */ namespace merkle_check; pol commit sel; @@ -55,13 +62,18 @@ namespace merkle_check; #[TRACE_CONTINUITY] (1 - precomputed.first_row) * (1 - sel) * sel' = 0; - // Inputs - // These are all propagated to the next row so that they are present - // alongside the root (output_hash) on the last row of a merkle check. - // This way an external caller can lookup { leaf, leaf_index, tree_height, root } - pol commit leaf; - pol commit leaf_index; - pol commit tree_height; + // Common inputs - These must be looked up both on read and write + pol commit read_node; + pol commit index; + pol commit path_len; + pol commit read_root; + + // Write specific inputs - These are only looked up when we want to update the root + pol commit write; + write * (1 - write) = 0; // bool + pol commit write_node; + pol commit write_root; + // Hints pol commit sibling; @@ -85,81 +97,90 @@ namespace merkle_check; #[SELECTOR_ON_END] end * (1 - sel) = 0; - // Internals - pol commit current_node; - pol commit current_index_in_layer; - pol commit remaining_path_len; - // On start, initialize internal vals like current_node, current_index_in_layer, remaining_path_len - // from start vals (inputs) like leaf, leaf_index, tree_height - #[INITIALIZE_CURRENT_NODE] - start * (current_node - leaf) = 0; - #[INITIALIZE_CURRENT_INDEX_IN_LAYER] - start * (current_index_in_layer - leaf_index) = 0; - #[INITIALIZE_REMAINING_PATH_LEN] - start * (tree_height - remaining_path_len - 1) = 0; // Remaining path length is initialized to tree_height - 1 - - #[PROPAGATE_LEAF] - NOT_END * (leaf' - leaf) = 0; - #[PROPAGATE_LEAF_INDEX] - NOT_END * (leaf_index' - leaf_index) = 0; - #[PROPAGATE_TREE_HEIGHT] - NOT_END * (tree_height' - tree_height) = 0; - - // If we are not done, the remaining_path_len decrements by 1 + #[PROPAGATE_READ_ROOT] + NOT_END * (read_root' - read_root) = 0; + #[PROPAGATE_WRITE] + NOT_END * (write' - write) = 0; + #[PROPAGATE_WRITE_ROOT] + NOT_END * (write_root' - write_root) = 0; + + // If we are not done, the path_len decrements by 1 #[PATH_LEN_DECREMENTS] - NOT_END * (remaining_path_len' - remaining_path_len + 1) = 0; + NOT_END * (path_len' - path_len + 1) = 0; + + // End when remaining path reaches 1. In other words, (path_len == 1) <==> (end == 1) + pol REMAINING_PATH_LEN = path_len - 1; - // End when remaining path reaches 0. In other words, (remaining_path_len == 0) <==> (end == 1) pol commit remaining_path_len_inv; #[END_WHEN_PATH_EMPTY] - sel * (remaining_path_len * (end * (1 - remaining_path_len_inv) + remaining_path_len_inv) - 1 + end) = 0; + sel * (REMAINING_PATH_LEN * (end * (1 - remaining_path_len_inv) + remaining_path_len_inv) - 1 + end) = 0; // index_is_even is constrained to be correct by the NEXT_INDEX_IS_HALVED and FINAL_INDEX_IS_0_OR_1 constraints pol commit index_is_even; index_is_even * (1 - index_is_even) = 0; pol INDEX_IS_ODD = (1 - index_is_even); // The index into the next layer is half the current index. - // We don't need to worry about underflowing the field since (current_index_in_layer - INDEX_IS_ODD) - // will be even (over the integers) and as the field is not of characteristic 2, current_index_in_layer' == current_index_in_layer / 2 over the integers + // We don't need to worry about underflowing the field since (index - INDEX_IS_ODD) + // will be even (over the integers) and as the field is not of characteristic 2, index' == index / 2 over the integers #[NEXT_INDEX_IS_HALVED] - NOT_END * (current_index_in_layer' * 2 + INDEX_IS_ODD - current_index_in_layer) = 0; + NOT_END * (index' * 2 + INDEX_IS_ODD - index) = 0; // Ensure that the final index is 0 or 1. // This ensures that the previous layer cannot overflow the field in the halving constraint - // when doing `current_index_in_layer' * 2`. This propagates backwards ensuring that no + // when doing `index' * 2`. This propagates backwards ensuring that no // layer can overflow on the halving constraint's multiplication by 2 as long as // tree_height < 254. #[FINAL_INDEX_IS_0_OR_1] - end * (current_index_in_layer * (1 - current_index_in_layer)) = 0; + end * (index * (1 - index)) = 0; // NOTE: index_is_even is essentially a vertical bit-decomposition of leaf_index. // left_node and right_node are sent to poseidon2 - // The constraints below arrange current_node and sibling into proper left/right order - pol commit left_node; - pol commit right_node; + // The constraints below arrange node and sibling for read and write into proper left/right order + pol commit read_left_node; + pol commit read_right_node; + pol commit write_left_node; + pol commit write_right_node; // This is accomplished by using index_is_even to toggle the (left_node - right_node) term. - // If current_index_in_layer is even, left_node (to send to poseidon2) is current_node and right_node is sibling. + // If index is even, left_node (to send to poseidon2) is node and right_node is sibling. // And vice-versa. - #[ASSIGN_CURRENT_NODE_LEFT_OR_RIGHT] - sel * (index_is_even * (left_node - right_node) + right_node - current_node) = 0; - #[ASSIGN_SIBLING_LEFT_OR_RIGHT] - sel * (index_is_even * (right_node - left_node) + left_node - sibling) = 0; + #[ASSIGN_NODE_LEFT_OR_RIGHT_READ] + sel * (index_is_even * (read_left_node - read_right_node) + read_right_node - read_node) = 0; + #[ASSIGN_SIBLING_LEFT_OR_RIGHT_READ] + sel * (index_is_even * (read_right_node - read_left_node) + read_left_node - sibling) = 0; + + #[ASSIGN_NODE_LEFT_OR_RIGHT_WRITE] + write * (index_is_even * (write_left_node - write_right_node) + write_right_node - write_node) = 0; + #[ASSIGN_SIBLING_LEFT_OR_RIGHT_WRITE] + write * (index_is_even * (write_right_node - write_left_node) + write_left_node - sibling) = 0; // NOTE: don't think these can be safely combined // output_hash = hash(left_node, right_node) - // if index_is_even: output_hash = hash(current_node, sibling) - // if !index_is_even: output_hash = hash(sibling, current_node) + // if index_is_even: output_hash = hash(node, sibling) + // if !index_is_even: output_hash = hash(sibling, node) // On end, output_hash is the root - pol commit output_hash; + pol commit read_output_hash; + pol commit write_output_hash; pol commit constant_2; sel * (constant_2 - 2) = 0; // Lookup to the full poseidon2 gadget - #[MERKLE_POSEIDON2] - sel { left_node, right_node, /*input_2=*/ precomputed.zero, /*input_len=*/ constant_2, output_hash } + #[MERKLE_POSEIDON2_READ] + sel { read_left_node, read_right_node, /*input_2=*/ precomputed.zero, /*input_len=*/ constant_2, read_output_hash } + in poseidon2_hash.end { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.input_len, poseidon2_hash.output }; + + #[MERKLE_POSEIDON2_WRITE] + write { write_left_node, write_right_node, /*input_2=*/ precomputed.zero, /*input_len=*/ constant_2, write_output_hash } in poseidon2_hash.end { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.input_len, poseidon2_hash.output }; - // If we are not done, this row's output_hash is the next row's current_node input - #[OUTPUT_HASH_IS_NEXT_ROWS_CURRENT_NODE] - NOT_END * (current_node' - output_hash) = 0; + // If we are not done, this row's output_hash is the next row's node + #[OUTPUT_HASH_IS_NEXT_ROWS_READ_NODE] + NOT_END * (read_node' - read_output_hash) = 0; + #[OUTPUT_HASH_IS_NEXT_ROWS_WRITE_NODE] + NOT_END * (write_node' - write_output_hash) = 0; + + // If we are done, the output hash is the root + #[READ_OUTPUT_HASH_IS_READ_ROOT] + end * (read_output_hash - read_root) = 0; + #[WRITE_OUTPUT_HASH_IS_WRITE_ROOT] + end * (write_output_hash - write_root) = 0; diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/merkle_check.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/merkle_check.test.cpp index 9558637d5fd1..514c243acb9a 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/merkle_check.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/relations/merkle_check.test.cpp @@ -40,8 +40,8 @@ using C = Column; using merkle_check = bb::avm2::merkle_check; using UnconstrainedPoseidon2 = crypto::Poseidon2; -// using permutation_poseidon2_hash = bb::avm2::perm_merkle_check_perm_merkle_poseidon2_relation; -using lookup_poseidon2_hash = bb::avm2::lookup_merkle_check_merkle_poseidon2_relation; +using lookup_poseidon2_read_hash = bb::avm2::lookup_merkle_check_merkle_poseidon2_read_relation; +using lookup_poseidon2_write_hash = bb::avm2::lookup_merkle_check_merkle_poseidon2_write_relation; TEST(MerkleCheckConstrainingTest, EmptyRow) { @@ -131,172 +131,100 @@ TEST(MerkleCheckConstrainingTest, SelectorOnEnd) EXPECT_THROW_WITH_MESSAGE(check_relation(trace, merkle_check::SR_SELECTOR_ON_END), "SELECTOR_ON_END"); } -TEST(MerkleCheckConstrainingTest, InitializeCurrentNode) +TEST(MerkleCheckConstrainingTest, PropagateReadRoot) { - // Test constraint: start * (current_node - leaf) = 0 - // On start rows, current_node should equal leaf + // Test constraint: NOT_END * (root' - root) = 0 + // Root should stay the same in the next row unless it's an end row + // When end=1, the next root can be different TestTraceContainer trace({ - { { C::merkle_check_sel, 1 }, - { C::merkle_check_start, 1 }, - { C::merkle_check_leaf, 123 }, - { C::merkle_check_current_node, 123 } }, // current_node = leaf on start row is correct - }); - - check_relation(trace, merkle_check::SR_INITIALIZE_CURRENT_NODE); - - // Create a trace for the negative test - TestTraceContainer negative_trace({ - { { C::merkle_check_sel, 1 }, - { C::merkle_check_start, 1 }, - { C::merkle_check_leaf, 123 }, - { C::merkle_check_current_node, 123 } }, // Correct values - }); - - // First verify it works with correct values - check_relation(negative_trace, merkle_check::SR_INITIALIZE_CURRENT_NODE); - - // Negative test - now modify to an incorrect value - negative_trace.set( - C::merkle_check_current_node, 0, 456); // This should fail - current_node should equal leaf on start row - - EXPECT_THROW_WITH_MESSAGE(check_relation(negative_trace, merkle_check::SR_INITIALIZE_CURRENT_NODE), - "INITIALIZE_CURRENT_NODE"); -} - -TEST(MerkleCheckConstrainingTest, InitializeCurrentIndexInLayer) -{ - // Test constraint: start * (current_index_in_layer - leaf_index) = 0 - // On start rows, current_index_in_layer should equal leaf_index - TestTraceContainer trace({ - { { C::merkle_check_sel, 1 }, - { C::merkle_check_start, 1 }, - { C::merkle_check_leaf_index, 42 }, - { C::merkle_check_current_index_in_layer, 42 } }, // current_index = leaf_index on start row is correct - }); - - check_relation(trace, merkle_check::SR_INITIALIZE_CURRENT_INDEX_IN_LAYER); - - // Negative test - now modify to an incorrect value - trace.set(C::merkle_check_current_index_in_layer, 0, 24); // This should fail - indices should match on start row - - EXPECT_THROW_WITH_MESSAGE(check_relation(trace, merkle_check::SR_INITIALIZE_CURRENT_INDEX_IN_LAYER), - "INITIALIZE_CURRENT_INDEX_IN_LAYER"); -} - -TEST(MerkleCheckConstrainingTest, InitializeRemainingPathLen) -{ - // Test constraint: start * (tree_height - remaining_path_len - 1) = 0 - // On start rows, remaining_path_len should be tree_height - 1 - TestTraceContainer trace({ - { { C::merkle_check_sel, 1 }, - { C::merkle_check_start, 1 }, - { C::merkle_check_tree_height, 5 }, - { C::merkle_check_remaining_path_len, 4 } }, // remaining_path_len = tree_height - 1 on start row is correct - }); - - check_relation(trace, merkle_check::SR_INITIALIZE_REMAINING_PATH_LEN); - - // Negative test - now modify to an incorrect value - trace.set(C::merkle_check_remaining_path_len, 0, 3); // This should fail - should be tree_height - 1 - - EXPECT_THROW_WITH_MESSAGE(check_relation(trace, merkle_check::SR_INITIALIZE_REMAINING_PATH_LEN), - "INITIALIZE_REMAINING_PATH_LEN"); -} - -TEST(MerkleCheckConstrainingTest, PropagateLeaf) -{ - // Test constraint: NOT_END * (leaf' - leaf) = 0 - // Leaf value should stay the same in the next row unless it's an end row - // When end=1, the next leaf can be different - TestTraceContainer trace({ - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, { C::merkle_check_leaf, 123 } }, + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, { C::merkle_check_read_root, 123 } }, // Same leaf value is correct when NOT_END=1 - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_leaf, 123 } }, + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_read_root, 123 } }, // Different leaf value is allowed after end row - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_leaf, 456 } }, + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_read_root, 456 } }, }); - check_relation(trace, merkle_check::SR_PROPAGATE_LEAF); + check_relation(trace, merkle_check::SR_PROPAGATE_READ_ROOT); // Negative test - now modify to an incorrect value - trace.set(C::merkle_check_leaf, 1, 456); // This should fail - leaf should stay the same when NOT_END=1 + trace.set(C::merkle_check_read_root, 1, 456); // This should fail - root should stay the same when NOT_END=1 - EXPECT_THROW_WITH_MESSAGE(check_relation(trace, merkle_check::SR_PROPAGATE_LEAF), "PROPAGATE_LEAF"); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, merkle_check::SR_PROPAGATE_READ_ROOT), + "PROPAGATE_READ_ROOT"); } -TEST(MerkleCheckConstrainingTest, PropagateLeafIndex) +TEST(MerkleCheckConstrainingTest, PropagateWriteRoot) { - // Test constraint: NOT_END * (leaf_index' - leaf_index) = 0 - // Leaf index should stay the same in the next row unless it's an end row - // When end=1, the next leaf_index can be different + // Test constraint: NOT_END * (write_root' - write_root) = 0 + // write_root should stay the same in the next row unless it's an end row + // When end=1, the next root can be different TestTraceContainer trace({ - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, { C::merkle_check_leaf_index, 42 } }, - // Same leaf index is correct when NOT_END=1 - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_leaf_index, 42 } }, - // Different leaf index is allowed after end row - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_leaf_index, 24 } }, + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, { C::merkle_check_write_root, 123 } }, + // Same leaf value is correct when NOT_END=1 + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_write_root, 123 } }, + // Different leaf value is allowed after end row + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_write_root, 456 } }, }); - check_relation(trace, merkle_check::SR_PROPAGATE_LEAF_INDEX); + check_relation(trace, merkle_check::SR_PROPAGATE_WRITE_ROOT); // Negative test - now modify to an incorrect value - trace.set(C::merkle_check_leaf_index, 1, 24); // This should fail - leaf index should stay the same when NOT_END=1 + trace.set(C::merkle_check_write_root, 1, 456); // This should fail - root should stay the same when NOT_END=1 - EXPECT_THROW_WITH_MESSAGE(check_relation(trace, merkle_check::SR_PROPAGATE_LEAF_INDEX), - "PROPAGATE_LEAF_INDEX"); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, merkle_check::SR_PROPAGATE_WRITE_ROOT), + "PROPAGATE_WRITE_ROOT"); } -TEST(MerkleCheckConstrainingTest, PropagateTreeHeight) +TEST(MerkleCheckConstrainingTest, PropagateWrite) { - // Test constraint: NOT_END * (tree_height' - tree_height) = 0 - // Tree height should stay the same in the next row unless it's an end row - // When end=1, the next tree_height can be different + // Test constraint: NOT_END * (write' - write) = 0 + // write should stay the same in the next row unless it's an end row + // When end=1, the next write flag can be different TestTraceContainer trace({ - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, { C::merkle_check_tree_height, 5 } }, - // Same tree height is correct when NOT_END=1 - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_tree_height, 5 } }, - // Different tree height is allowed after end row - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_tree_height, 3 } }, + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, { C::merkle_check_write, 1 } }, + // Same leaf value is correct when NOT_END=1 + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_write, 1 } }, + // Different leaf value is allowed after end row + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_write, 0 } }, }); - check_relation(trace, merkle_check::SR_PROPAGATE_TREE_HEIGHT); + check_relation(trace, merkle_check::SR_PROPAGATE_WRITE); // Negative test - now modify to an incorrect value - trace.set(C::merkle_check_tree_height, 1, 3); // This should fail - tree height should stay the same when NOT_END=1 + trace.set(C::merkle_check_write, 1, 0); // This should fail - write should stay the same when NOT_END=1 - EXPECT_THROW_WITH_MESSAGE(check_relation(trace, merkle_check::SR_PROPAGATE_TREE_HEIGHT), - "PROPAGATE_TREE_HEIGHT"); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, merkle_check::SR_PROPAGATE_WRITE), "PROPAGATE_WRITE"); } TEST(MerkleCheckConstrainingTest, PathLenDecrements) { TestTraceContainer trace({ // Decrements until path_len=0 - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, { C::merkle_check_remaining_path_len, 2 } }, - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, { C::merkle_check_remaining_path_len, 1 } }, - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_remaining_path_len, 0 } }, + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, { C::merkle_check_path_len, 3 } }, + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, { C::merkle_check_path_len, 2 } }, + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_path_len, 1 } }, // Path len can be different after end=1 - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_remaining_path_len, 5 } }, + { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_path_len, 5 } }, }); check_relation(trace, merkle_check::SR_PATH_LEN_DECREMENTS); // Negative test - now modify to an incorrect value and verify it fails - trace.set(C::merkle_check_remaining_path_len, 1, 0); // Should be 1, change to 0 + trace.set(C::merkle_check_path_len, 1, 1); // Should be 2, change to 1 EXPECT_THROW_WITH_MESSAGE(check_relation(trace, merkle_check::SR_PATH_LEN_DECREMENTS), "PATH_LEN_DECREMENTS"); } -TEST(MerkleCheckConstrainingTest, EndWhenPathEmpty) +TEST(MerkleCheckConstrainingTest, EndWhenPathLenOne) { TestTraceContainer trace({ { { C::merkle_check_sel, 1 }, - { C::merkle_check_remaining_path_len, 1 }, + { C::merkle_check_path_len, 2 }, { C::merkle_check_remaining_path_len_inv, FF(1).invert() }, { C::merkle_check_end, 0 } }, { { C::merkle_check_sel, 1 }, - { C::merkle_check_remaining_path_len, 0 }, + { C::merkle_check_path_len, 1 }, { C::merkle_check_remaining_path_len_inv, 0 }, { C::merkle_check_end, 1 } }, }); @@ -315,15 +243,15 @@ TEST(MerkleCheckConstrainingTest, NextIndexIsHalved) TestTraceContainer trace({ { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, - { C::merkle_check_current_index_in_layer, 6 }, + { C::merkle_check_index, 6 }, { C::merkle_check_index_is_even, 1 } }, { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, - { C::merkle_check_current_index_in_layer, 3 }, // 6/2 = 3 + { C::merkle_check_index, 3 }, // 6/2 = 3 { C::merkle_check_index_is_even, 0 } }, { { C::merkle_check_sel, 1 }, - { C::merkle_check_end, 1 }, // Set end=1 for final row - { C::merkle_check_current_index_in_layer, 1 }, // 3/2 = 1 + { C::merkle_check_end, 1 }, // Set end=1 for final row + { C::merkle_check_index, 1 }, // 3/2 = 1 { C::merkle_check_index_is_even, 0 } }, }); @@ -333,96 +261,164 @@ TEST(MerkleCheckConstrainingTest, NextIndexIsHalved) TestTraceContainer trace2({ { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, - { C::merkle_check_current_index_in_layer, 7 }, + { C::merkle_check_index, 7 }, { C::merkle_check_index_is_even, 0 } }, { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, - { C::merkle_check_current_index_in_layer, 3 }, // (7-1)/2 = 3 + { C::merkle_check_index, 3 }, // (7-1)/2 = 3 { C::merkle_check_index_is_even, 0 } }, { { C::merkle_check_sel, 1 }, - { C::merkle_check_end, 1 }, // Set end=1 for final row - { C::merkle_check_current_index_in_layer, 1 }, // 6/2 = 3 + { C::merkle_check_end, 1 }, // Set end=1 for final row + { C::merkle_check_index, 1 }, // 6/2 = 3 { C::merkle_check_index_is_even, 0 } }, }); check_relation(trace2, merkle_check::SR_NEXT_INDEX_IS_HALVED); // Negative test - now modify to an incorrect value and verify it fails - trace2.set(C::merkle_check_current_index_in_layer, 1, 4); // Should be 3, change to 4 + trace2.set(C::merkle_check_index, 1, 4); // Should be 3, change to 4 EXPECT_THROW_WITH_MESSAGE(check_relation(trace2, merkle_check::SR_NEXT_INDEX_IS_HALVED), "NEXT_INDEX_IS_HALVED"); } -TEST(MerkleCheckConstrainingTest, AssignCurrentNodeLeftOrRight) +TEST(MerkleCheckConstrainingTest, AssignCurrentReadNodeLeftOrRight) { // Test even index (current_node goes to left_node) TestTraceContainer trace({ { { C::merkle_check_sel, 1 }, { C::merkle_check_index_is_even, 1 }, - { C::merkle_check_current_node, 123 }, + { C::merkle_check_read_node, 123 }, { C::merkle_check_sibling, 456 }, - { C::merkle_check_left_node, 123 }, - { C::merkle_check_right_node, 456 } }, + { C::merkle_check_read_left_node, 123 }, + { C::merkle_check_read_right_node, 456 } }, }); - check_relation(trace, merkle_check::SR_ASSIGN_CURRENT_NODE_LEFT_OR_RIGHT); + check_relation(trace, merkle_check::SR_ASSIGN_NODE_LEFT_OR_RIGHT_READ); // Test odd index (current_node goes to right_node) TestTraceContainer trace2({ { { C::merkle_check_sel, 1 }, { C::merkle_check_index_is_even, 0 }, - { C::merkle_check_current_node, 123 }, + { C::merkle_check_read_node, 123 }, + { C::merkle_check_sibling, 456 }, + { C::merkle_check_read_left_node, 456 }, + { C::merkle_check_read_right_node, 123 } }, + }); + + check_relation(trace2, merkle_check::SR_ASSIGN_NODE_LEFT_OR_RIGHT_READ); + + // Negative test - now modify to an incorrect value and verify it fails + trace2.set(C::merkle_check_read_left_node, 0, 123); // Should be 456 + trace2.set(C::merkle_check_read_right_node, 0, 456); // Should be 123 + + EXPECT_THROW_WITH_MESSAGE(check_relation(trace2, merkle_check::SR_ASSIGN_NODE_LEFT_OR_RIGHT_READ), + "ASSIGN_NODE_LEFT_OR_RIGHT_READ"); +} + +TEST(MerkleCheckConstrainingTest, AssignCurrentWriteNodeLeftOrRight) +{ + // Test even index (current_node goes to left_node) + TestTraceContainer trace({ + { { C::merkle_check_write, 1 }, + { C::merkle_check_index_is_even, 1 }, + { C::merkle_check_write_node, 123 }, + { C::merkle_check_sibling, 456 }, + { C::merkle_check_write_left_node, 123 }, + { C::merkle_check_write_right_node, 456 } }, + }); + + check_relation(trace, merkle_check::SR_ASSIGN_NODE_LEFT_OR_RIGHT_WRITE); + + // Test odd index (current_node goes to right_node) + TestTraceContainer trace2({ + { { C::merkle_check_write, 1 }, + { C::merkle_check_index_is_even, 0 }, + { C::merkle_check_write_node, 123 }, { C::merkle_check_sibling, 456 }, - { C::merkle_check_left_node, 456 }, - { C::merkle_check_right_node, 123 } }, + { C::merkle_check_write_left_node, 456 }, + { C::merkle_check_write_right_node, 123 } }, }); - check_relation(trace2, merkle_check::SR_ASSIGN_CURRENT_NODE_LEFT_OR_RIGHT); + check_relation(trace2, merkle_check::SR_ASSIGN_NODE_LEFT_OR_RIGHT_WRITE); // Negative test - now modify to an incorrect value and verify it fails - trace2.set(C::merkle_check_left_node, 0, 123); // Should be 456 - trace2.set(C::merkle_check_right_node, 0, 456); // Should be 123 + trace2.set(C::merkle_check_write_left_node, 0, 123); // Should be 456 + trace2.set(C::merkle_check_write_right_node, 0, 456); // Should be 123 - EXPECT_THROW_WITH_MESSAGE(check_relation(trace2, merkle_check::SR_ASSIGN_CURRENT_NODE_LEFT_OR_RIGHT), - "ASSIGN_CURRENT_NODE_LEFT_OR_RIGHT"); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace2, merkle_check::SR_ASSIGN_NODE_LEFT_OR_RIGHT_WRITE), + "ASSIGN_NODE_LEFT_OR_RIGHT_WRITE"); } -TEST(MerkleCheckConstrainingTest, AssignSiblingLeftOrRight) +TEST(MerkleCheckConstrainingTest, AssignSiblingLeftOrRightRead) { // Test even index (sibling goes to right_node) TestTraceContainer trace({ { { C::merkle_check_sel, 1 }, { C::merkle_check_index_is_even, 1 }, - { C::merkle_check_current_node, 123 }, + { C::merkle_check_read_node, 123 }, { C::merkle_check_sibling, 456 }, - { C::merkle_check_left_node, 123 }, - { C::merkle_check_right_node, 456 } }, + { C::merkle_check_read_left_node, 123 }, + { C::merkle_check_read_right_node, 456 } }, }); - check_relation(trace, merkle_check::SR_ASSIGN_SIBLING_LEFT_OR_RIGHT); + check_relation(trace, merkle_check::SR_ASSIGN_SIBLING_LEFT_OR_RIGHT_READ); // Test odd index (sibling goes to left_node) TestTraceContainer trace2({ { { C::merkle_check_sel, 1 }, { C::merkle_check_index_is_even, 0 }, - { C::merkle_check_current_node, 123 }, + { C::merkle_check_read_node, 123 }, { C::merkle_check_sibling, 456 }, - { C::merkle_check_left_node, 456 }, - { C::merkle_check_right_node, 123 } }, + { C::merkle_check_read_left_node, 456 }, + { C::merkle_check_read_right_node, 123 } }, }); - check_relation(trace2, merkle_check::SR_ASSIGN_SIBLING_LEFT_OR_RIGHT); + check_relation(trace2, merkle_check::SR_ASSIGN_SIBLING_LEFT_OR_RIGHT_READ); // Negative test - now modify to an incorrect value and verify it fails - trace2.set(C::merkle_check_left_node, 0, 123); // Should be 456 - trace2.set(C::merkle_check_right_node, 0, 456); // Should be 123 + trace2.set(C::merkle_check_read_left_node, 0, 123); // Should be 456 + trace2.set(C::merkle_check_read_right_node, 0, 456); // Should be 123 - EXPECT_THROW_WITH_MESSAGE(check_relation(trace2, merkle_check::SR_ASSIGN_SIBLING_LEFT_OR_RIGHT), - "ASSIGN_SIBLING_LEFT_OR_RIGHT"); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace2, merkle_check::SR_ASSIGN_SIBLING_LEFT_OR_RIGHT_READ), + "ASSIGN_SIBLING_LEFT_OR_RIGHT_READ"); } -TEST(MerkleCheckConstrainingTest, OutputHashIsNextRowsCurrentNode) +TEST(MerkleCheckConstrainingTest, AssignSiblingLeftOrRightWrite) +{ + // Test even index (sibling goes to right_node) + TestTraceContainer trace({ + { { C::merkle_check_write, 1 }, + { C::merkle_check_index_is_even, 1 }, + { C::merkle_check_write_node, 123 }, + { C::merkle_check_sibling, 456 }, + { C::merkle_check_write_left_node, 123 }, + { C::merkle_check_write_right_node, 456 } }, + }); + + check_relation(trace, merkle_check::SR_ASSIGN_SIBLING_LEFT_OR_RIGHT_WRITE); + + // Test odd index (sibling goes to left_node) + TestTraceContainer trace2({ + { { C::merkle_check_write, 1 }, + { C::merkle_check_index_is_even, 0 }, + { C::merkle_check_write_node, 123 }, + { C::merkle_check_sibling, 456 }, + { C::merkle_check_write_left_node, 456 }, + { C::merkle_check_write_right_node, 123 } }, + }); + + check_relation(trace2, merkle_check::SR_ASSIGN_SIBLING_LEFT_OR_RIGHT_WRITE); + + // Negative test - now modify to an incorrect value and verify it fails + trace2.set(C::merkle_check_write_left_node, 0, 123); // Should be 456 + trace2.set(C::merkle_check_write_right_node, 0, 456); // Should be 123 + + EXPECT_THROW_WITH_MESSAGE(check_relation(trace2, merkle_check::SR_ASSIGN_SIBLING_LEFT_OR_RIGHT_WRITE), + "ASSIGN_SIBLING_LEFT_OR_RIGHT_WRITE"); +} + +TEST(MerkleCheckConstrainingTest, ReadOutputHashIsNextRowsNode) { FF left_node = FF(123); FF right_node = FF(456); @@ -431,22 +427,47 @@ TEST(MerkleCheckConstrainingTest, OutputHashIsNextRowsCurrentNode) TestTraceContainer trace({ { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 0 }, - { C::merkle_check_left_node, left_node }, - { C::merkle_check_right_node, right_node }, - { C::merkle_check_output_hash, output_hash } }, + { C::merkle_check_read_node, left_node }, + { C::merkle_check_read_right_node, right_node }, + { C::merkle_check_read_output_hash, output_hash } }, { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, // Set end=1 for final row - { C::merkle_check_current_node, output_hash } }, + { C::merkle_check_read_node, output_hash } }, }); - check_relation(trace, merkle_check::SR_OUTPUT_HASH_IS_NEXT_ROWS_CURRENT_NODE); + check_relation(trace, merkle_check::SR_OUTPUT_HASH_IS_NEXT_ROWS_READ_NODE); // Negative test - now modify to an incorrect value and verify it fails - trace.set(C::merkle_check_current_node, 1, output_hash + 1); // Should be output_hash + trace.set(C::merkle_check_read_node, 1, output_hash + 1); // Should be output_hash - EXPECT_THROW_WITH_MESSAGE( - check_relation(trace, merkle_check::SR_OUTPUT_HASH_IS_NEXT_ROWS_CURRENT_NODE), - "OUTPUT_HASH_IS_NEXT_ROWS_CURRENT_NODE"); + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, merkle_check::SR_OUTPUT_HASH_IS_NEXT_ROWS_READ_NODE), + "OUTPUT_HASH_IS_NEXT_ROWS_READ_NODE"); +} + +TEST(MerkleCheckConstrainingTest, WriteOutputHashIsNextRowsNode) +{ + FF left_node = FF(123); + FF right_node = FF(456); + FF output_hash = UnconstrainedPoseidon2::hash({ left_node, right_node }); + + TestTraceContainer trace({ + { { C::merkle_check_sel, 1 }, + { C::merkle_check_end, 0 }, + { C::merkle_check_write_node, left_node }, + { C::merkle_check_write_right_node, right_node }, + { C::merkle_check_write_output_hash, output_hash } }, + { { C::merkle_check_sel, 1 }, + { C::merkle_check_end, 1 }, // Set end=1 for final row + { C::merkle_check_write_node, output_hash } }, + }); + + check_relation(trace, merkle_check::SR_OUTPUT_HASH_IS_NEXT_ROWS_WRITE_NODE); + + // Negative test - now modify to an incorrect value and verify it fails + trace.set(C::merkle_check_write_node, 1, output_hash + 1); // Should be output_hash + + EXPECT_THROW_WITH_MESSAGE(check_relation(trace, merkle_check::SR_OUTPUT_HASH_IS_NEXT_ROWS_WRITE_NODE), + "OUTPUT_HASH_IS_NEXT_ROWS_WRITE_NODE"); } TEST(MerkleCheckConstrainingTest, OutputHashIsNotNextRowsCurrentNodeValueForLastRow) @@ -455,14 +476,20 @@ TEST(MerkleCheckConstrainingTest, OutputHashIsNotNextRowsCurrentNodeValueForLast FF next_current_node = FF(789); TestTraceContainer trace({ - { { C::merkle_check_sel, 1 }, { C::merkle_check_end, 1 }, { C::merkle_check_output_hash, output_hash } }, - { { C::merkle_check_sel, 1 }, { C::merkle_check_current_node, next_current_node } }, + { { C::merkle_check_sel, 1 }, + { C::merkle_check_end, 1 }, + { C::merkle_check_read_output_hash, output_hash }, + { C::merkle_check_write_output_hash, output_hash } }, + { { C::merkle_check_sel, 1 }, + { C::merkle_check_read_node, next_current_node }, + { C::merkle_check_write_node, next_current_node } }, }); - check_relation(trace, merkle_check::SR_OUTPUT_HASH_IS_NEXT_ROWS_CURRENT_NODE); + check_relation(trace, merkle_check::SR_OUTPUT_HASH_IS_NEXT_ROWS_READ_NODE); + check_relation(trace, merkle_check::SR_OUTPUT_HASH_IS_NEXT_ROWS_WRITE_NODE); } -TEST(MerkleCheckConstrainingTest, WithTracegen) +TEST(MerkleCheckConstrainingTest, ReadWithTracegen) { TestTraceContainer trace = TestTraceContainer::from_rows({ { .precomputed_first_row = 1 }, @@ -491,12 +518,45 @@ TEST(MerkleCheckConstrainingTest, WithTracegen) // Negative test - now corrupt the trace and verify it fails auto rows = trace.as_rows(); // Corrupt the last row - trace.set(C::merkle_check_remaining_path_len, static_cast(rows.size() - 1), 66); + trace.set(C::merkle_check_path_len, static_cast(rows.size() - 1), 66); EXPECT_THROW_WITH_MESSAGE(check_relation(trace), "Relation merkle_check"); } -TEST(MerkleCheckConstrainingTest, WithInteractions) +TEST(MerkleCheckConstrainingTest, WriteWithTracegen) +{ + TestTraceContainer trace = TestTraceContainer::from_rows({ + { .precomputed_first_row = 1 }, + }); + MerkleCheckTraceBuilder builder; + + // Create a Merkle tree path with 3 levels + FF leaf_value = FF(123); + FF new_leaf_value = FF(456); + uint64_t leaf_index = 5; + + // Create a sibling path of length 3 + std::vector sibling_path = { FF(456), FF(789), FF(3333) }; + + // Compute read root + FF root = root_from_path(leaf_value, leaf_index, sibling_path); + // Compute new root + FF new_root = root_from_path(new_leaf_value, leaf_index, sibling_path); + + MerkleCheckEvent event = { .leaf_value = leaf_value, + .new_leaf_value = new_leaf_value, + .leaf_index = leaf_index, + .sibling_path = sibling_path, + .root = root, + .new_root = new_root }; + + builder.process({ event }, trace); + + // Check the relation for all rows + check_relation(trace); +} + +TEST(MerkleCheckConstrainingTest, ReadWithInteractions) { EventEmitter hash_event_emitter; EventEmitter perm_event_emitter; @@ -518,17 +578,73 @@ TEST(MerkleCheckConstrainingTest, WithInteractions) poseidon2_builder.process_hash(hash_event_emitter.dump_events(), trace); merkle_check_builder.process(merkle_event_emitter.dump_events(), trace); - LookupIntoDynamicTableSequential().process(trace); - check_interaction(trace); + LookupIntoDynamicTableSequential().process(trace); + LookupIntoDynamicTableSequential().process(trace); + + check_interaction(trace); + check_interaction(trace); check_relation(trace); // Negative test - now corrupt the trace and verify it fails - trace.set(Column::merkle_check_output_hash, static_cast(sibling_path.size()), 66); + trace.set(Column::merkle_check_read_output_hash, static_cast(sibling_path.size()), 66); - EXPECT_THROW_WITH_MESSAGE(LookupIntoDynamicTableSequential().process(trace), + EXPECT_THROW_WITH_MESSAGE(LookupIntoDynamicTableSequential().process(trace), "Failed.*LOOKUP_MERKLE_CHECK_MERKLE_POSEIDON2.* Could not find tuple in destination"); - EXPECT_THROW_WITH_MESSAGE(check_interaction(trace), + EXPECT_THROW_WITH_MESSAGE(check_interaction(trace), "Relation.*LOOKUP_MERKLE_CHECK_MERKLE_POSEIDON2.* ACCUMULATION.* is non-zero"); + LookupIntoDynamicTableSequential().process(trace); + check_interaction(trace); +} + +TEST(MerkleCheckConstrainingTest, WriteWithInteractions) +{ + EventEmitter hash_event_emitter; + EventEmitter perm_event_emitter; + Poseidon2 poseidon2(hash_event_emitter, perm_event_emitter); + + EventEmitter merkle_event_emitter; + MerkleCheck merkle_check_sim(poseidon2, merkle_event_emitter); + + TestTraceContainer trace({ { { C::precomputed_first_row, 1 } } }); + Poseidon2TraceBuilder poseidon2_builder; + MerkleCheckTraceBuilder merkle_check_builder; + + FF leaf_value = 333; + FF new_leaf_value = 444; + uint64_t leaf_index = 30; + std::vector sibling_path = { 10, 2, 30, 4, 50, 6 }; + FF root = root_from_path(leaf_value, leaf_index, sibling_path); + FF expected_new_root = root_from_path(new_leaf_value, leaf_index, sibling_path); + + FF new_root = merkle_check_sim.write(leaf_value, new_leaf_value, leaf_index, sibling_path, root); + + EXPECT_EQ(new_root, expected_new_root); + + poseidon2_builder.process_hash(hash_event_emitter.dump_events(), trace); + merkle_check_builder.process(merkle_event_emitter.dump_events(), trace); + + LookupIntoDynamicTableSequential().process(trace); + LookupIntoDynamicTableSequential().process(trace); + + check_interaction(trace); + check_interaction(trace); + check_relation(trace); + + // Negative test - now corrupt the trace and verify it fails + trace.set(Column::merkle_check_read_output_hash, static_cast(sibling_path.size()), 66); + trace.set(Column::merkle_check_write_output_hash, static_cast(sibling_path.size()), 77); + + EXPECT_THROW_WITH_MESSAGE( + LookupIntoDynamicTableSequential().process(trace), + "Failed.*LOOKUP_MERKLE_CHECK_MERKLE_POSEIDON2_READ.* Could not find tuple in destination"); + EXPECT_THROW_WITH_MESSAGE(check_interaction(trace), + "Relation.*LOOKUP_MERKLE_CHECK_MERKLE_POSEIDON2_READ.* ACCUMULATION.* is non-zero"); + + EXPECT_THROW_WITH_MESSAGE( + LookupIntoDynamicTableSequential().process(trace), + "Failed.*LOOKUP_MERKLE_CHECK_MERKLE_POSEIDON2_WRITE.* Could not find tuple in destination"); + EXPECT_THROW_WITH_MESSAGE(check_interaction(trace), + "Relation.*LOOKUP_MERKLE_CHECK_MERKLE_POSEIDON2_WRITE.* ACCUMULATION.* is non-zero"); } TEST(MerkleCheckConstrainingTest, MultipleWithTracegen) @@ -547,33 +663,42 @@ TEST(MerkleCheckConstrainingTest, MultipleWithTracegen) }; FF leaf_value2 = 444; + FF new_leaf_value2 = 555; uint64_t leaf_index2 = 40; std::vector sibling_path2 = { 11, 22, 33, 44, 55, 66 }; FF root2 = root_from_path(leaf_value2, leaf_index2, sibling_path2); - MerkleCheckEvent event2 = { - .leaf_value = leaf_value2, .leaf_index = leaf_index2, .sibling_path = sibling_path2, .root = root2 - }; + FF new_root2 = root_from_path(new_leaf_value2, leaf_index2, sibling_path2); + MerkleCheckEvent event2 = { .leaf_value = leaf_value2, + .new_leaf_value = new_leaf_value2, + .leaf_index = leaf_index2, + .sibling_path = sibling_path2, + .root = root2, + .new_root = new_root2 }; builder.process({ event, event2 }, trace); // Empty row after last real merkle row uint32_t after_last_row_index = 1 + static_cast(sibling_path.size() + sibling_path2.size()); trace.set(Column::merkle_check_sel, after_last_row_index, 0); - trace.set(Column::merkle_check_leaf, after_last_row_index, 0); - trace.set(Column::merkle_check_leaf_index, after_last_row_index, 0); - trace.set(Column::merkle_check_tree_height, after_last_row_index, 0); - trace.set(Column::merkle_check_current_node, after_last_row_index, 0); - trace.set(Column::merkle_check_current_index_in_layer, after_last_row_index, 0); - trace.set(Column::merkle_check_remaining_path_len, after_last_row_index, 0); + trace.set(Column::merkle_check_write, after_last_row_index, 0); + trace.set(Column::merkle_check_read_node, after_last_row_index, 0); + trace.set(Column::merkle_check_write_node, after_last_row_index, 0); + trace.set(Column::merkle_check_index, after_last_row_index, 0); + trace.set(Column::merkle_check_path_len, after_last_row_index, 0); trace.set(Column::merkle_check_remaining_path_len_inv, after_last_row_index, 0); + trace.set(Column::merkle_check_read_root, after_last_row_index, 0); + trace.set(Column::merkle_check_write_root, after_last_row_index, 0); trace.set(Column::merkle_check_sibling, after_last_row_index, 0); trace.set(Column::merkle_check_start, after_last_row_index, 0); trace.set(Column::merkle_check_end, after_last_row_index, 0); trace.set(Column::merkle_check_index_is_even, after_last_row_index, 0); - trace.set(Column::merkle_check_left_node, after_last_row_index, 0); - trace.set(Column::merkle_check_right_node, after_last_row_index, 0); + trace.set(Column::merkle_check_read_left_node, after_last_row_index, 0); + trace.set(Column::merkle_check_read_right_node, after_last_row_index, 0); + trace.set(Column::merkle_check_write_left_node, after_last_row_index, 0); + trace.set(Column::merkle_check_write_right_node, after_last_row_index, 0); trace.set(Column::merkle_check_constant_2, after_last_row_index, 0); - trace.set(Column::merkle_check_output_hash, after_last_row_index, 0); + trace.set(Column::merkle_check_read_output_hash, after_last_row_index, 0); + trace.set(Column::merkle_check_write_output_hash, after_last_row_index, 0); check_relation(trace); } @@ -585,7 +710,6 @@ TEST(MerkleCheckConstrainingTest, MultipleWithInteractions) Poseidon2 poseidon2(hash_event_emitter, perm_event_emitter); EventEmitter merkle_event_emitter; - MerkleCheck merkle_check_sim(poseidon2, merkle_event_emitter); TestTraceContainer trace({ { { C::precomputed_first_row, 1 } } }); @@ -596,19 +720,26 @@ TEST(MerkleCheckConstrainingTest, MultipleWithInteractions) uint64_t leaf_index = 30; std::vector sibling_path = { 10, 2, 30, 4, 50, 6 }; FF root = root_from_path(leaf_value, leaf_index, sibling_path); + merkle_check_sim.assert_membership(leaf_value, leaf_index, sibling_path, root); FF leaf_value2 = 444; + FF new_leaf_value2 = 555; uint64_t leaf_index2 = 40; std::vector sibling_path2 = { 11, 22, 33, 44, 55, 66 }; FF root2 = root_from_path(leaf_value2, leaf_index2, sibling_path2); - merkle_check_sim.assert_membership(leaf_value2, leaf_index2, sibling_path2, root2); + FF expected_new_root2 = root_from_path(new_leaf_value2, leaf_index2, sibling_path2); + + FF new_root2 = merkle_check_sim.write(leaf_value2, new_leaf_value2, leaf_index2, sibling_path2, root2); + EXPECT_EQ(new_root2, expected_new_root2); poseidon2_builder.process_hash(hash_event_emitter.dump_events(), trace); merkle_check_builder.process(merkle_event_emitter.dump_events(), trace); - LookupIntoDynamicTableSequential().process(trace); - check_interaction(trace); + LookupIntoDynamicTableSequential().process(trace); + LookupIntoDynamicTableSequential().process(trace); + check_interaction(trace); + check_interaction(trace); check_relation(trace); } diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp index 342f5d5a3335..efff5600a3c3 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp @@ -10,16 +10,16 @@ namespace bb::avm2 { // The entities that will be used in the flavor. // clang-format off #define AVM2_PRECOMPUTED_ENTITIES precomputed_as_unary, precomputed_bitwise_input_a, precomputed_bitwise_input_b, precomputed_bitwise_op_id, precomputed_bitwise_output, precomputed_clk, precomputed_exec_opcode, precomputed_first_row, precomputed_instr_size, precomputed_integral_tag_length, precomputed_opcode_out_of_range, precomputed_p_decomposition_limb, precomputed_p_decomposition_limb_index, precomputed_p_decomposition_radix, precomputed_power_of_2, precomputed_sel_bitwise, precomputed_sel_has_tag, precomputed_sel_integral_tag, precomputed_sel_mem_tag_out_of_range, precomputed_sel_op_dc_0, precomputed_sel_op_dc_1, precomputed_sel_op_dc_10, precomputed_sel_op_dc_11, precomputed_sel_op_dc_12, precomputed_sel_op_dc_13, precomputed_sel_op_dc_14, precomputed_sel_op_dc_15, precomputed_sel_op_dc_16, precomputed_sel_op_dc_17, precomputed_sel_op_dc_2, precomputed_sel_op_dc_3, precomputed_sel_op_dc_4, precomputed_sel_op_dc_5, precomputed_sel_op_dc_6, precomputed_sel_op_dc_7, precomputed_sel_op_dc_8, precomputed_sel_op_dc_9, precomputed_sel_p_decomposition, precomputed_sel_range_16, precomputed_sel_range_8, precomputed_sel_sha256_compression, precomputed_sel_tag_is_op2, precomputed_sel_to_radix_safe_limbs, precomputed_sel_unary, precomputed_sha256_compression_round_constant, precomputed_to_radix_safe_limbs, precomputed_zero -#define AVM2_WIRE_ENTITIES execution_input, address_derivation_address, address_derivation_address_y, address_derivation_class_id, address_derivation_deployer_addr, address_derivation_g1_x, address_derivation_g1_y, address_derivation_incoming_viewing_key_x, address_derivation_incoming_viewing_key_y, address_derivation_init_hash, address_derivation_nullifier_key_x, address_derivation_nullifier_key_y, address_derivation_outgoing_viewing_key_x, address_derivation_outgoing_viewing_key_y, address_derivation_partial_address, address_derivation_partial_address_domain_separator, address_derivation_preaddress, address_derivation_preaddress_domain_separator, address_derivation_preaddress_public_key_x, address_derivation_preaddress_public_key_y, address_derivation_public_keys_hash, address_derivation_public_keys_hash_domain_separator, address_derivation_salt, address_derivation_salted_init_hash, address_derivation_sel, address_derivation_tagging_key_x, address_derivation_tagging_key_y, alu_dst_addr, alu_ia, alu_ia_addr, alu_ib, alu_ib_addr, alu_ic, alu_op, alu_sel_op_add, bc_decomposition_abs_diff, bc_decomposition_bytes, bc_decomposition_bytes_pc_plus_1, bc_decomposition_bytes_pc_plus_10, bc_decomposition_bytes_pc_plus_11, bc_decomposition_bytes_pc_plus_12, bc_decomposition_bytes_pc_plus_13, bc_decomposition_bytes_pc_plus_14, bc_decomposition_bytes_pc_plus_15, bc_decomposition_bytes_pc_plus_16, bc_decomposition_bytes_pc_plus_17, bc_decomposition_bytes_pc_plus_18, bc_decomposition_bytes_pc_plus_19, bc_decomposition_bytes_pc_plus_2, bc_decomposition_bytes_pc_plus_20, bc_decomposition_bytes_pc_plus_21, bc_decomposition_bytes_pc_plus_22, bc_decomposition_bytes_pc_plus_23, bc_decomposition_bytes_pc_plus_24, bc_decomposition_bytes_pc_plus_25, bc_decomposition_bytes_pc_plus_26, bc_decomposition_bytes_pc_plus_27, bc_decomposition_bytes_pc_plus_28, bc_decomposition_bytes_pc_plus_29, bc_decomposition_bytes_pc_plus_3, bc_decomposition_bytes_pc_plus_30, bc_decomposition_bytes_pc_plus_31, bc_decomposition_bytes_pc_plus_32, bc_decomposition_bytes_pc_plus_33, bc_decomposition_bytes_pc_plus_34, bc_decomposition_bytes_pc_plus_35, bc_decomposition_bytes_pc_plus_36, bc_decomposition_bytes_pc_plus_4, bc_decomposition_bytes_pc_plus_5, bc_decomposition_bytes_pc_plus_6, bc_decomposition_bytes_pc_plus_7, bc_decomposition_bytes_pc_plus_8, bc_decomposition_bytes_pc_plus_9, bc_decomposition_bytes_rem_inv, bc_decomposition_bytes_rem_min_one_inv, bc_decomposition_bytes_remaining, bc_decomposition_bytes_to_read, bc_decomposition_bytes_to_read_unary, bc_decomposition_id, bc_decomposition_last_of_contract, bc_decomposition_packed_field, bc_decomposition_pc, bc_decomposition_sel, bc_decomposition_sel_overflow_correction_needed, bc_decomposition_sel_packed, bc_decomposition_sel_pc_plus_1, bc_decomposition_sel_pc_plus_10, bc_decomposition_sel_pc_plus_11, bc_decomposition_sel_pc_plus_12, bc_decomposition_sel_pc_plus_13, bc_decomposition_sel_pc_plus_14, bc_decomposition_sel_pc_plus_15, bc_decomposition_sel_pc_plus_16, bc_decomposition_sel_pc_plus_17, bc_decomposition_sel_pc_plus_18, bc_decomposition_sel_pc_plus_19, bc_decomposition_sel_pc_plus_2, bc_decomposition_sel_pc_plus_20, bc_decomposition_sel_pc_plus_21, bc_decomposition_sel_pc_plus_22, bc_decomposition_sel_pc_plus_23, bc_decomposition_sel_pc_plus_24, bc_decomposition_sel_pc_plus_25, bc_decomposition_sel_pc_plus_26, bc_decomposition_sel_pc_plus_27, bc_decomposition_sel_pc_plus_28, bc_decomposition_sel_pc_plus_29, bc_decomposition_sel_pc_plus_3, bc_decomposition_sel_pc_plus_30, bc_decomposition_sel_pc_plus_31, bc_decomposition_sel_pc_plus_32, bc_decomposition_sel_pc_plus_33, bc_decomposition_sel_pc_plus_34, bc_decomposition_sel_pc_plus_35, bc_decomposition_sel_pc_plus_36, bc_decomposition_sel_pc_plus_4, bc_decomposition_sel_pc_plus_5, bc_decomposition_sel_pc_plus_6, bc_decomposition_sel_pc_plus_7, bc_decomposition_sel_pc_plus_8, bc_decomposition_sel_pc_plus_9, bc_hashing_bytecode_id, bc_hashing_incremental_hash, bc_hashing_latch, bc_hashing_output_hash, bc_hashing_packed_field, bc_hashing_pc_index, bc_hashing_sel, bc_hashing_start, bc_retrieval_address, bc_retrieval_artifact_hash, bc_retrieval_bytecode_id, bc_retrieval_class_id, bc_retrieval_deployer_addr, bc_retrieval_err, bc_retrieval_incoming_viewing_key_x, bc_retrieval_incoming_viewing_key_y, bc_retrieval_init_hash, bc_retrieval_nullifier_key_x, bc_retrieval_nullifier_key_y, bc_retrieval_outgoing_viewing_key_x, bc_retrieval_outgoing_viewing_key_y, bc_retrieval_private_function_root, bc_retrieval_public_bytecode_commitment, bc_retrieval_salt, bc_retrieval_sel, bc_retrieval_siloed_address, bc_retrieval_tagging_key_x, bc_retrieval_tagging_key_y, bitwise_acc_ia, bitwise_acc_ib, bitwise_acc_ic, bitwise_ctr, bitwise_ctr_inv, bitwise_ctr_min_one_inv, bitwise_ia_byte, bitwise_ib_byte, bitwise_ic_byte, bitwise_last, bitwise_op_id, bitwise_sel, bitwise_start, bitwise_tag, class_id_derivation_artifact_hash, class_id_derivation_class_id, class_id_derivation_private_function_root, class_id_derivation_public_bytecode_commitment, class_id_derivation_sel, class_id_derivation_temp_constant_for_lookup, context_stack_context_id, context_stack_contract_address, context_stack_is_static, context_stack_msg_sender, context_stack_parent_calldata_offset_addr, context_stack_parent_calldata_size_addr, context_stack_pc, ecc_add_op, ecc_double_op, ecc_inv_2_p_y, ecc_inv_x_diff, ecc_inv_y_diff, ecc_lambda, ecc_p_is_inf, ecc_p_x, ecc_p_y, ecc_q_is_inf, ecc_q_x, ecc_q_y, ecc_r_is_inf, ecc_r_x, ecc_r_y, ecc_result_infinity, ecc_sel, ecc_x_match, ecc_y_match, execution_addressing_error_idx, execution_addressing_error_kind, execution_base_address_tag, execution_base_address_val, execution_bytecode_id, execution_clk, execution_context_id, execution_contract_address, execution_ex_opcode, execution_indirect, execution_is_static, execution_last, execution_last_child_returndata_offset_addr, execution_last_child_returndata_size_addr, execution_last_child_success, execution_msg_sender, execution_op1, execution_op1_after_relative, execution_op2, execution_op2_after_relative, execution_op3, execution_op3_after_relative, execution_op4, execution_op4_after_relative, execution_parent_calldata_offset_addr, execution_parent_calldata_size_addr, execution_pc, execution_rop1, execution_rop2, execution_rop3, execution_rop4, execution_sel, execution_sel_addressing_error, execution_sel_op1_is_address, execution_sel_op2_is_address, execution_sel_op3_is_address, execution_sel_op4_is_address, ff_gt_a, ff_gt_a_hi, ff_gt_a_lo, ff_gt_b, ff_gt_b_hi, ff_gt_b_lo, ff_gt_borrow, ff_gt_cmp_rng_ctr, ff_gt_cmp_rng_ctr_inv, ff_gt_constant_128, ff_gt_p_a_borrow, ff_gt_p_b_borrow, ff_gt_p_sub_a_hi, ff_gt_p_sub_a_lo, ff_gt_p_sub_b_hi, ff_gt_p_sub_b_lo, ff_gt_res_hi, ff_gt_res_lo, ff_gt_result, ff_gt_sel, ff_gt_sel_gt, ff_gt_sel_shift_rng, instr_fetching_bd0, instr_fetching_bd1, instr_fetching_bd10, instr_fetching_bd11, instr_fetching_bd12, instr_fetching_bd13, instr_fetching_bd14, instr_fetching_bd15, instr_fetching_bd16, instr_fetching_bd17, instr_fetching_bd18, instr_fetching_bd19, instr_fetching_bd2, instr_fetching_bd20, instr_fetching_bd21, instr_fetching_bd22, instr_fetching_bd23, instr_fetching_bd24, instr_fetching_bd25, instr_fetching_bd26, instr_fetching_bd27, instr_fetching_bd28, instr_fetching_bd29, instr_fetching_bd3, instr_fetching_bd30, instr_fetching_bd31, instr_fetching_bd32, instr_fetching_bd33, instr_fetching_bd34, instr_fetching_bd35, instr_fetching_bd36, instr_fetching_bd4, instr_fetching_bd5, instr_fetching_bd6, instr_fetching_bd7, instr_fetching_bd8, instr_fetching_bd9, instr_fetching_bytecode_id, instr_fetching_bytecode_size, instr_fetching_bytes_to_read, instr_fetching_exec_opcode, instr_fetching_indirect, instr_fetching_instr_abs_diff, instr_fetching_instr_out_of_range, instr_fetching_instr_size, instr_fetching_op1, instr_fetching_op2, instr_fetching_op3, instr_fetching_op4, instr_fetching_op5, instr_fetching_op6, instr_fetching_op7, instr_fetching_opcode_out_of_range, instr_fetching_parsing_err, instr_fetching_pc, instr_fetching_pc_abs_diff, instr_fetching_pc_out_of_range, instr_fetching_pc_size_in_bits, instr_fetching_sel, instr_fetching_sel_has_tag, instr_fetching_sel_op_dc_0, instr_fetching_sel_op_dc_1, instr_fetching_sel_op_dc_10, instr_fetching_sel_op_dc_11, instr_fetching_sel_op_dc_12, instr_fetching_sel_op_dc_13, instr_fetching_sel_op_dc_14, instr_fetching_sel_op_dc_15, instr_fetching_sel_op_dc_16, instr_fetching_sel_op_dc_17, instr_fetching_sel_op_dc_2, instr_fetching_sel_op_dc_3, instr_fetching_sel_op_dc_4, instr_fetching_sel_op_dc_5, instr_fetching_sel_op_dc_6, instr_fetching_sel_op_dc_7, instr_fetching_sel_op_dc_8, instr_fetching_sel_op_dc_9, instr_fetching_sel_pc_in_range, instr_fetching_sel_tag_is_op2, instr_fetching_tag_out_of_range, instr_fetching_tag_value, merkle_check_constant_2, merkle_check_current_index_in_layer, merkle_check_current_node, merkle_check_end, merkle_check_index_is_even, merkle_check_leaf, merkle_check_leaf_index, merkle_check_left_node, merkle_check_output_hash, merkle_check_remaining_path_len, merkle_check_remaining_path_len_inv, merkle_check_right_node, merkle_check_sel, merkle_check_sibling, merkle_check_start, merkle_check_tree_height, poseidon2_hash_a_0, poseidon2_hash_a_1, poseidon2_hash_a_2, poseidon2_hash_a_3, poseidon2_hash_b_0, poseidon2_hash_b_1, poseidon2_hash_b_2, poseidon2_hash_b_3, poseidon2_hash_end, poseidon2_hash_input_0, poseidon2_hash_input_1, poseidon2_hash_input_2, poseidon2_hash_input_len, poseidon2_hash_num_perm_rounds_rem, poseidon2_hash_num_perm_rounds_rem_inv, poseidon2_hash_output, poseidon2_hash_padding, poseidon2_hash_sel, poseidon2_hash_start, poseidon2_perm_B_10_0, poseidon2_perm_B_10_1, poseidon2_perm_B_10_2, poseidon2_perm_B_10_3, poseidon2_perm_B_11_0, poseidon2_perm_B_11_1, poseidon2_perm_B_11_2, poseidon2_perm_B_11_3, poseidon2_perm_B_12_0, poseidon2_perm_B_12_1, poseidon2_perm_B_12_2, poseidon2_perm_B_12_3, poseidon2_perm_B_13_0, poseidon2_perm_B_13_1, poseidon2_perm_B_13_2, poseidon2_perm_B_13_3, poseidon2_perm_B_14_0, poseidon2_perm_B_14_1, poseidon2_perm_B_14_2, poseidon2_perm_B_14_3, poseidon2_perm_B_15_0, poseidon2_perm_B_15_1, poseidon2_perm_B_15_2, poseidon2_perm_B_15_3, poseidon2_perm_B_16_0, poseidon2_perm_B_16_1, poseidon2_perm_B_16_2, poseidon2_perm_B_16_3, poseidon2_perm_B_17_0, poseidon2_perm_B_17_1, poseidon2_perm_B_17_2, poseidon2_perm_B_17_3, poseidon2_perm_B_18_0, poseidon2_perm_B_18_1, poseidon2_perm_B_18_2, poseidon2_perm_B_18_3, poseidon2_perm_B_19_0, poseidon2_perm_B_19_1, poseidon2_perm_B_19_2, poseidon2_perm_B_19_3, poseidon2_perm_B_20_0, poseidon2_perm_B_20_1, poseidon2_perm_B_20_2, poseidon2_perm_B_20_3, poseidon2_perm_B_21_0, poseidon2_perm_B_21_1, poseidon2_perm_B_21_2, poseidon2_perm_B_21_3, poseidon2_perm_B_22_0, poseidon2_perm_B_22_1, poseidon2_perm_B_22_2, poseidon2_perm_B_22_3, poseidon2_perm_B_23_0, poseidon2_perm_B_23_1, poseidon2_perm_B_23_2, poseidon2_perm_B_23_3, poseidon2_perm_B_24_0, poseidon2_perm_B_24_1, poseidon2_perm_B_24_2, poseidon2_perm_B_24_3, poseidon2_perm_B_25_0, poseidon2_perm_B_25_1, poseidon2_perm_B_25_2, poseidon2_perm_B_25_3, poseidon2_perm_B_26_0, poseidon2_perm_B_26_1, poseidon2_perm_B_26_2, poseidon2_perm_B_26_3, poseidon2_perm_B_27_0, poseidon2_perm_B_27_1, poseidon2_perm_B_27_2, poseidon2_perm_B_27_3, poseidon2_perm_B_28_0, poseidon2_perm_B_28_1, poseidon2_perm_B_28_2, poseidon2_perm_B_28_3, poseidon2_perm_B_29_0, poseidon2_perm_B_29_1, poseidon2_perm_B_29_2, poseidon2_perm_B_29_3, poseidon2_perm_B_30_0, poseidon2_perm_B_30_1, poseidon2_perm_B_30_2, poseidon2_perm_B_30_3, poseidon2_perm_B_31_0, poseidon2_perm_B_31_1, poseidon2_perm_B_31_2, poseidon2_perm_B_31_3, poseidon2_perm_B_32_0, poseidon2_perm_B_32_1, poseidon2_perm_B_32_2, poseidon2_perm_B_32_3, poseidon2_perm_B_33_0, poseidon2_perm_B_33_1, poseidon2_perm_B_33_2, poseidon2_perm_B_33_3, poseidon2_perm_B_34_0, poseidon2_perm_B_34_1, poseidon2_perm_B_34_2, poseidon2_perm_B_34_3, poseidon2_perm_B_35_0, poseidon2_perm_B_35_1, poseidon2_perm_B_35_2, poseidon2_perm_B_35_3, poseidon2_perm_B_36_0, poseidon2_perm_B_36_1, poseidon2_perm_B_36_2, poseidon2_perm_B_36_3, poseidon2_perm_B_37_0, poseidon2_perm_B_37_1, poseidon2_perm_B_37_2, poseidon2_perm_B_37_3, poseidon2_perm_B_38_0, poseidon2_perm_B_38_1, poseidon2_perm_B_38_2, poseidon2_perm_B_38_3, poseidon2_perm_B_39_0, poseidon2_perm_B_39_1, poseidon2_perm_B_39_2, poseidon2_perm_B_39_3, poseidon2_perm_B_40_0, poseidon2_perm_B_40_1, poseidon2_perm_B_40_2, poseidon2_perm_B_40_3, poseidon2_perm_B_41_0, poseidon2_perm_B_41_1, poseidon2_perm_B_41_2, poseidon2_perm_B_41_3, poseidon2_perm_B_42_0, poseidon2_perm_B_42_1, poseidon2_perm_B_42_2, poseidon2_perm_B_42_3, poseidon2_perm_B_43_0, poseidon2_perm_B_43_1, poseidon2_perm_B_43_2, poseidon2_perm_B_43_3, poseidon2_perm_B_44_0, poseidon2_perm_B_44_1, poseidon2_perm_B_44_2, poseidon2_perm_B_44_3, poseidon2_perm_B_45_0, poseidon2_perm_B_45_1, poseidon2_perm_B_45_2, poseidon2_perm_B_45_3, poseidon2_perm_B_46_0, poseidon2_perm_B_46_1, poseidon2_perm_B_46_2, poseidon2_perm_B_46_3, poseidon2_perm_B_47_0, poseidon2_perm_B_47_1, poseidon2_perm_B_47_2, poseidon2_perm_B_47_3, poseidon2_perm_B_48_0, poseidon2_perm_B_48_1, poseidon2_perm_B_48_2, poseidon2_perm_B_48_3, poseidon2_perm_B_49_0, poseidon2_perm_B_49_1, poseidon2_perm_B_49_2, poseidon2_perm_B_49_3, poseidon2_perm_B_4_0, poseidon2_perm_B_4_1, poseidon2_perm_B_4_2, poseidon2_perm_B_4_3, poseidon2_perm_B_50_0, poseidon2_perm_B_50_1, poseidon2_perm_B_50_2, poseidon2_perm_B_50_3, poseidon2_perm_B_51_0, poseidon2_perm_B_51_1, poseidon2_perm_B_51_2, poseidon2_perm_B_51_3, poseidon2_perm_B_52_0, poseidon2_perm_B_52_1, poseidon2_perm_B_52_2, poseidon2_perm_B_52_3, poseidon2_perm_B_53_0, poseidon2_perm_B_53_1, poseidon2_perm_B_53_2, poseidon2_perm_B_53_3, poseidon2_perm_B_54_0, poseidon2_perm_B_54_1, poseidon2_perm_B_54_2, poseidon2_perm_B_54_3, poseidon2_perm_B_55_0, poseidon2_perm_B_55_1, poseidon2_perm_B_55_2, poseidon2_perm_B_55_3, poseidon2_perm_B_56_0, poseidon2_perm_B_56_1, poseidon2_perm_B_56_2, poseidon2_perm_B_56_3, poseidon2_perm_B_57_0, poseidon2_perm_B_57_1, poseidon2_perm_B_57_2, poseidon2_perm_B_57_3, poseidon2_perm_B_58_0, poseidon2_perm_B_58_1, poseidon2_perm_B_58_2, poseidon2_perm_B_58_3, poseidon2_perm_B_59_0, poseidon2_perm_B_59_1, poseidon2_perm_B_59_2, poseidon2_perm_B_59_3, poseidon2_perm_B_5_0, poseidon2_perm_B_5_1, poseidon2_perm_B_5_2, poseidon2_perm_B_5_3, poseidon2_perm_B_6_0, poseidon2_perm_B_6_1, poseidon2_perm_B_6_2, poseidon2_perm_B_6_3, poseidon2_perm_B_7_0, poseidon2_perm_B_7_1, poseidon2_perm_B_7_2, poseidon2_perm_B_7_3, poseidon2_perm_B_8_0, poseidon2_perm_B_8_1, poseidon2_perm_B_8_2, poseidon2_perm_B_8_3, poseidon2_perm_B_9_0, poseidon2_perm_B_9_1, poseidon2_perm_B_9_2, poseidon2_perm_B_9_3, poseidon2_perm_EXT_LAYER_4, poseidon2_perm_EXT_LAYER_5, poseidon2_perm_EXT_LAYER_6, poseidon2_perm_EXT_LAYER_7, poseidon2_perm_T_0_4, poseidon2_perm_T_0_5, poseidon2_perm_T_0_6, poseidon2_perm_T_0_7, poseidon2_perm_T_1_4, poseidon2_perm_T_1_5, poseidon2_perm_T_1_6, poseidon2_perm_T_1_7, poseidon2_perm_T_2_4, poseidon2_perm_T_2_5, poseidon2_perm_T_2_6, poseidon2_perm_T_2_7, poseidon2_perm_T_3_4, poseidon2_perm_T_3_5, poseidon2_perm_T_3_6, poseidon2_perm_T_3_7, poseidon2_perm_T_60_4, poseidon2_perm_T_60_5, poseidon2_perm_T_60_6, poseidon2_perm_T_60_7, poseidon2_perm_T_61_4, poseidon2_perm_T_61_5, poseidon2_perm_T_61_6, poseidon2_perm_T_61_7, poseidon2_perm_T_62_4, poseidon2_perm_T_62_5, poseidon2_perm_T_62_6, poseidon2_perm_T_62_7, poseidon2_perm_T_63_4, poseidon2_perm_T_63_5, poseidon2_perm_T_63_6, poseidon2_perm_T_63_7, poseidon2_perm_a_0, poseidon2_perm_a_1, poseidon2_perm_a_2, poseidon2_perm_a_3, poseidon2_perm_b_0, poseidon2_perm_b_1, poseidon2_perm_b_2, poseidon2_perm_b_3, poseidon2_perm_sel, range_check_dyn_diff, range_check_dyn_rng_chk_bits, range_check_dyn_rng_chk_pow_2, range_check_is_lte_u112, range_check_is_lte_u128, range_check_is_lte_u16, range_check_is_lte_u32, range_check_is_lte_u48, range_check_is_lte_u64, range_check_is_lte_u80, range_check_is_lte_u96, range_check_rng_chk_bits, range_check_sel, range_check_sel_r0_16_bit_rng_lookup, range_check_sel_r1_16_bit_rng_lookup, range_check_sel_r2_16_bit_rng_lookup, range_check_sel_r3_16_bit_rng_lookup, range_check_sel_r4_16_bit_rng_lookup, range_check_sel_r5_16_bit_rng_lookup, range_check_sel_r6_16_bit_rng_lookup, range_check_u16_r0, range_check_u16_r1, range_check_u16_r2, range_check_u16_r3, range_check_u16_r4, range_check_u16_r5, range_check_u16_r6, range_check_u16_r7, range_check_value, scalar_mul_bit, scalar_mul_bit_idx, scalar_mul_bit_radix, scalar_mul_end, scalar_mul_not_end, scalar_mul_point_inf, scalar_mul_point_x, scalar_mul_point_y, scalar_mul_res_inf, scalar_mul_res_x, scalar_mul_res_y, scalar_mul_scalar, scalar_mul_sel, scalar_mul_should_add, scalar_mul_start, scalar_mul_temp_inf, scalar_mul_temp_x, scalar_mul_temp_y, sha256_a, sha256_a_and_b, sha256_a_and_b_xor_a_and_c, sha256_a_and_c, sha256_a_rotr_13, sha256_a_rotr_2, sha256_a_rotr_22, sha256_a_rotr_2_xor_a_rotr_13, sha256_and_sel, sha256_b, sha256_b_and_c, sha256_c, sha256_ch, sha256_clk, sha256_computed_w_lhs, sha256_computed_w_rhs, sha256_d, sha256_e, sha256_e_and_f, sha256_e_rotr_11, sha256_e_rotr_25, sha256_e_rotr_6, sha256_e_rotr_6_xor_e_rotr_11, sha256_f, sha256_g, sha256_h, sha256_helper_w0, sha256_helper_w1, sha256_helper_w10, sha256_helper_w11, sha256_helper_w12, sha256_helper_w13, sha256_helper_w14, sha256_helper_w15, sha256_helper_w2, sha256_helper_w3, sha256_helper_w4, sha256_helper_w5, sha256_helper_w6, sha256_helper_w7, sha256_helper_w8, sha256_helper_w9, sha256_init_a, sha256_init_b, sha256_init_c, sha256_init_d, sha256_init_e, sha256_init_f, sha256_init_g, sha256_init_h, sha256_input_offset, sha256_is_input_round, sha256_latch, sha256_lhs_a_13, sha256_lhs_a_2, sha256_lhs_a_22, sha256_lhs_e_11, sha256_lhs_e_25, sha256_lhs_e_6, sha256_lhs_w_10, sha256_lhs_w_17, sha256_lhs_w_18, sha256_lhs_w_19, sha256_lhs_w_3, sha256_lhs_w_7, sha256_maj, sha256_next_a_lhs, sha256_next_a_rhs, sha256_next_e_lhs, sha256_next_e_rhs, sha256_not_e, sha256_not_e_and_g, sha256_output_a_lhs, sha256_output_a_rhs, sha256_output_b_lhs, sha256_output_b_rhs, sha256_output_c_lhs, sha256_output_c_rhs, sha256_output_d_lhs, sha256_output_d_rhs, sha256_output_e_lhs, sha256_output_e_rhs, sha256_output_f_lhs, sha256_output_f_rhs, sha256_output_g_lhs, sha256_output_g_rhs, sha256_output_h_lhs, sha256_output_h_rhs, sha256_output_offset, sha256_perform_round, sha256_rhs_a_13, sha256_rhs_a_2, sha256_rhs_a_22, sha256_rhs_e_11, sha256_rhs_e_25, sha256_rhs_e_6, sha256_rhs_w_10, sha256_rhs_w_17, sha256_rhs_w_18, sha256_rhs_w_19, sha256_rhs_w_3, sha256_rhs_w_7, sha256_round_constant, sha256_round_count, sha256_rounds_remaining, sha256_rounds_remaining_inv, sha256_s_0, sha256_s_1, sha256_sel, sha256_start, sha256_state_offset, sha256_w, sha256_w_15_rotr_18, sha256_w_15_rotr_7, sha256_w_15_rotr_7_xor_w_15_rotr_18, sha256_w_15_rshift_3, sha256_w_2_rotr_17, sha256_w_2_rotr_17_xor_w_2_rotr_19, sha256_w_2_rotr_19, sha256_w_2_rshift_10, sha256_w_s_0, sha256_w_s_1, sha256_xor_sel, to_radix_acc, to_radix_acc_under_p, to_radix_end, to_radix_exponent, to_radix_found, to_radix_is_unsafe_limb, to_radix_limb, to_radix_limb_eq_p, to_radix_limb_index, to_radix_limb_lt_p, to_radix_limb_p_diff, to_radix_limb_radix_diff, to_radix_not_end, to_radix_not_padding_limb, to_radix_p_limb, to_radix_radix, to_radix_rem_inverse, to_radix_safe_limbs, to_radix_safety_diff_inverse, to_radix_sel, to_radix_start, to_radix_value, lookup_poseidon2_hash_poseidon2_perm_counts, lookup_range_check_dyn_rng_chk_pow_2_counts, lookup_range_check_dyn_diff_is_u16_counts, lookup_range_check_r0_is_u16_counts, lookup_range_check_r1_is_u16_counts, lookup_range_check_r2_is_u16_counts, lookup_range_check_r3_is_u16_counts, lookup_range_check_r4_is_u16_counts, lookup_range_check_r5_is_u16_counts, lookup_range_check_r6_is_u16_counts, lookup_range_check_r7_is_u16_counts, lookup_to_radix_limb_range_counts, lookup_to_radix_limb_less_than_radix_range_counts, lookup_to_radix_fetch_safe_limbs_counts, lookup_to_radix_fetch_p_limb_counts, lookup_to_radix_limb_p_diff_range_counts, lookup_scalar_mul_to_radix_counts, lookup_scalar_mul_double_counts, lookup_scalar_mul_add_counts, lookup_address_derivation_salted_initialization_hash_poseidon2_0_counts, lookup_address_derivation_salted_initialization_hash_poseidon2_1_counts, lookup_address_derivation_partial_address_poseidon2_counts, lookup_address_derivation_public_keys_hash_poseidon2_0_counts, lookup_address_derivation_public_keys_hash_poseidon2_1_counts, lookup_address_derivation_public_keys_hash_poseidon2_2_counts, lookup_address_derivation_public_keys_hash_poseidon2_3_counts, lookup_address_derivation_public_keys_hash_poseidon2_4_counts, lookup_address_derivation_preaddress_poseidon2_counts, lookup_address_derivation_preaddress_scalar_mul_counts, lookup_address_derivation_address_ecadd_counts, lookup_bc_decomposition_bytes_are_bytes_counts, lookup_bc_decomposition_abs_diff_is_u16_counts, lookup_bc_decomposition_bytes_to_read_as_unary_counts, lookup_bc_hashing_get_packed_field_counts, lookup_bc_hashing_iv_is_len_counts, lookup_bc_hashing_poseidon2_hash_counts, lookup_bc_retrieval_class_id_derivation_counts, lookup_bc_retrieval_bytecode_hash_is_correct_counts, lookup_instr_fetching_pc_abs_diff_positive_counts, lookup_instr_fetching_instr_abs_diff_positive_counts, lookup_instr_fetching_tag_value_validation_counts, lookup_instr_fetching_bytecode_size_from_bc_dec_counts, lookup_instr_fetching_bytes_from_bc_dec_counts, lookup_instr_fetching_wire_instruction_info_counts, lookup_class_id_derivation_class_id_poseidon2_0_counts, lookup_class_id_derivation_class_id_poseidon2_1_counts, lookup_bitwise_integral_tag_length_counts, lookup_bitwise_byte_operations_counts, lookup_merkle_check_merkle_poseidon2_counts, lookup_sha256_round_constant_counts, lookup_ff_gt_a_lo_range_counts, lookup_ff_gt_a_hi_range_counts -#define AVM2_DERIVED_WITNESS_ENTITIES lookup_poseidon2_hash_poseidon2_perm_inv, lookup_range_check_dyn_rng_chk_pow_2_inv, lookup_range_check_dyn_diff_is_u16_inv, lookup_range_check_r0_is_u16_inv, lookup_range_check_r1_is_u16_inv, lookup_range_check_r2_is_u16_inv, lookup_range_check_r3_is_u16_inv, lookup_range_check_r4_is_u16_inv, lookup_range_check_r5_is_u16_inv, lookup_range_check_r6_is_u16_inv, lookup_range_check_r7_is_u16_inv, lookup_to_radix_limb_range_inv, lookup_to_radix_limb_less_than_radix_range_inv, lookup_to_radix_fetch_safe_limbs_inv, lookup_to_radix_fetch_p_limb_inv, lookup_to_radix_limb_p_diff_range_inv, lookup_scalar_mul_to_radix_inv, lookup_scalar_mul_double_inv, lookup_scalar_mul_add_inv, lookup_address_derivation_salted_initialization_hash_poseidon2_0_inv, lookup_address_derivation_salted_initialization_hash_poseidon2_1_inv, lookup_address_derivation_partial_address_poseidon2_inv, lookup_address_derivation_public_keys_hash_poseidon2_0_inv, lookup_address_derivation_public_keys_hash_poseidon2_1_inv, lookup_address_derivation_public_keys_hash_poseidon2_2_inv, lookup_address_derivation_public_keys_hash_poseidon2_3_inv, lookup_address_derivation_public_keys_hash_poseidon2_4_inv, lookup_address_derivation_preaddress_poseidon2_inv, lookup_address_derivation_preaddress_scalar_mul_inv, lookup_address_derivation_address_ecadd_inv, lookup_bc_decomposition_bytes_are_bytes_inv, lookup_bc_decomposition_abs_diff_is_u16_inv, lookup_bc_decomposition_bytes_to_read_as_unary_inv, lookup_bc_hashing_get_packed_field_inv, lookup_bc_hashing_iv_is_len_inv, lookup_bc_hashing_poseidon2_hash_inv, lookup_bc_retrieval_class_id_derivation_inv, lookup_bc_retrieval_bytecode_hash_is_correct_inv, lookup_instr_fetching_pc_abs_diff_positive_inv, lookup_instr_fetching_instr_abs_diff_positive_inv, lookup_instr_fetching_tag_value_validation_inv, lookup_instr_fetching_bytecode_size_from_bc_dec_inv, lookup_instr_fetching_bytes_from_bc_dec_inv, lookup_instr_fetching_wire_instruction_info_inv, lookup_class_id_derivation_class_id_poseidon2_0_inv, lookup_class_id_derivation_class_id_poseidon2_1_inv, lookup_bitwise_integral_tag_length_inv, lookup_bitwise_byte_operations_inv, lookup_merkle_check_merkle_poseidon2_inv, lookup_sha256_round_constant_inv, lookup_ff_gt_a_lo_range_inv, lookup_ff_gt_a_hi_range_inv -#define AVM2_SHIFTED_ENTITIES bc_decomposition_bytes_shift, bc_decomposition_bytes_pc_plus_1_shift, bc_decomposition_bytes_pc_plus_10_shift, bc_decomposition_bytes_pc_plus_11_shift, bc_decomposition_bytes_pc_plus_12_shift, bc_decomposition_bytes_pc_plus_13_shift, bc_decomposition_bytes_pc_plus_14_shift, bc_decomposition_bytes_pc_plus_15_shift, bc_decomposition_bytes_pc_plus_16_shift, bc_decomposition_bytes_pc_plus_17_shift, bc_decomposition_bytes_pc_plus_18_shift, bc_decomposition_bytes_pc_plus_19_shift, bc_decomposition_bytes_pc_plus_2_shift, bc_decomposition_bytes_pc_plus_20_shift, bc_decomposition_bytes_pc_plus_21_shift, bc_decomposition_bytes_pc_plus_22_shift, bc_decomposition_bytes_pc_plus_23_shift, bc_decomposition_bytes_pc_plus_24_shift, bc_decomposition_bytes_pc_plus_25_shift, bc_decomposition_bytes_pc_plus_26_shift, bc_decomposition_bytes_pc_plus_27_shift, bc_decomposition_bytes_pc_plus_28_shift, bc_decomposition_bytes_pc_plus_29_shift, bc_decomposition_bytes_pc_plus_3_shift, bc_decomposition_bytes_pc_plus_30_shift, bc_decomposition_bytes_pc_plus_31_shift, bc_decomposition_bytes_pc_plus_32_shift, bc_decomposition_bytes_pc_plus_33_shift, bc_decomposition_bytes_pc_plus_34_shift, bc_decomposition_bytes_pc_plus_35_shift, bc_decomposition_bytes_pc_plus_4_shift, bc_decomposition_bytes_pc_plus_5_shift, bc_decomposition_bytes_pc_plus_6_shift, bc_decomposition_bytes_pc_plus_7_shift, bc_decomposition_bytes_pc_plus_8_shift, bc_decomposition_bytes_pc_plus_9_shift, bc_decomposition_bytes_remaining_shift, bc_decomposition_id_shift, bc_decomposition_pc_shift, bc_decomposition_sel_shift, bc_hashing_bytecode_id_shift, bc_hashing_incremental_hash_shift, bc_hashing_pc_index_shift, bc_hashing_sel_shift, bc_hashing_start_shift, bitwise_acc_ia_shift, bitwise_acc_ib_shift, bitwise_acc_ic_shift, bitwise_ctr_shift, bitwise_op_id_shift, execution_sel_shift, ff_gt_a_hi_shift, ff_gt_a_lo_shift, ff_gt_b_hi_shift, ff_gt_b_lo_shift, ff_gt_cmp_rng_ctr_shift, ff_gt_p_sub_a_hi_shift, ff_gt_p_sub_a_lo_shift, ff_gt_p_sub_b_hi_shift, ff_gt_p_sub_b_lo_shift, ff_gt_sel_shift, ff_gt_sel_gt_shift, merkle_check_current_index_in_layer_shift, merkle_check_current_node_shift, merkle_check_leaf_shift, merkle_check_leaf_index_shift, merkle_check_remaining_path_len_shift, merkle_check_sel_shift, merkle_check_start_shift, merkle_check_tree_height_shift, poseidon2_hash_a_0_shift, poseidon2_hash_a_1_shift, poseidon2_hash_a_2_shift, poseidon2_hash_a_3_shift, poseidon2_hash_input_0_shift, poseidon2_hash_input_1_shift, poseidon2_hash_input_2_shift, poseidon2_hash_num_perm_rounds_rem_shift, poseidon2_hash_output_shift, poseidon2_hash_sel_shift, poseidon2_hash_start_shift, scalar_mul_bit_idx_shift, scalar_mul_point_inf_shift, scalar_mul_point_x_shift, scalar_mul_point_y_shift, scalar_mul_res_inf_shift, scalar_mul_res_x_shift, scalar_mul_res_y_shift, scalar_mul_scalar_shift, scalar_mul_sel_shift, scalar_mul_start_shift, scalar_mul_temp_inf_shift, scalar_mul_temp_x_shift, scalar_mul_temp_y_shift, sha256_a_shift, sha256_b_shift, sha256_c_shift, sha256_d_shift, sha256_e_shift, sha256_f_shift, sha256_g_shift, sha256_h_shift, sha256_helper_w0_shift, sha256_helper_w1_shift, sha256_helper_w10_shift, sha256_helper_w11_shift, sha256_helper_w12_shift, sha256_helper_w13_shift, sha256_helper_w14_shift, sha256_helper_w15_shift, sha256_helper_w2_shift, sha256_helper_w3_shift, sha256_helper_w4_shift, sha256_helper_w5_shift, sha256_helper_w6_shift, sha256_helper_w7_shift, sha256_helper_w8_shift, sha256_helper_w9_shift, sha256_rounds_remaining_shift, sha256_sel_shift, sha256_start_shift, to_radix_acc_shift, to_radix_acc_under_p_shift, to_radix_exponent_shift, to_radix_limb_shift, to_radix_limb_eq_p_shift, to_radix_limb_index_shift, to_radix_limb_lt_p_shift, to_radix_not_padding_limb_shift, to_radix_radix_shift, to_radix_safe_limbs_shift, to_radix_sel_shift, to_radix_start_shift, to_radix_value_shift -#define AVM2_TO_BE_SHIFTED(e) e.bc_decomposition_bytes, e.bc_decomposition_bytes_pc_plus_1, e.bc_decomposition_bytes_pc_plus_10, e.bc_decomposition_bytes_pc_plus_11, e.bc_decomposition_bytes_pc_plus_12, e.bc_decomposition_bytes_pc_plus_13, e.bc_decomposition_bytes_pc_plus_14, e.bc_decomposition_bytes_pc_plus_15, e.bc_decomposition_bytes_pc_plus_16, e.bc_decomposition_bytes_pc_plus_17, e.bc_decomposition_bytes_pc_plus_18, e.bc_decomposition_bytes_pc_plus_19, e.bc_decomposition_bytes_pc_plus_2, e.bc_decomposition_bytes_pc_plus_20, e.bc_decomposition_bytes_pc_plus_21, e.bc_decomposition_bytes_pc_plus_22, e.bc_decomposition_bytes_pc_plus_23, e.bc_decomposition_bytes_pc_plus_24, e.bc_decomposition_bytes_pc_plus_25, e.bc_decomposition_bytes_pc_plus_26, e.bc_decomposition_bytes_pc_plus_27, e.bc_decomposition_bytes_pc_plus_28, e.bc_decomposition_bytes_pc_plus_29, e.bc_decomposition_bytes_pc_plus_3, e.bc_decomposition_bytes_pc_plus_30, e.bc_decomposition_bytes_pc_plus_31, e.bc_decomposition_bytes_pc_plus_32, e.bc_decomposition_bytes_pc_plus_33, e.bc_decomposition_bytes_pc_plus_34, e.bc_decomposition_bytes_pc_plus_35, e.bc_decomposition_bytes_pc_plus_4, e.bc_decomposition_bytes_pc_plus_5, e.bc_decomposition_bytes_pc_plus_6, e.bc_decomposition_bytes_pc_plus_7, e.bc_decomposition_bytes_pc_plus_8, e.bc_decomposition_bytes_pc_plus_9, e.bc_decomposition_bytes_remaining, e.bc_decomposition_id, e.bc_decomposition_pc, e.bc_decomposition_sel, e.bc_hashing_bytecode_id, e.bc_hashing_incremental_hash, e.bc_hashing_pc_index, e.bc_hashing_sel, e.bc_hashing_start, e.bitwise_acc_ia, e.bitwise_acc_ib, e.bitwise_acc_ic, e.bitwise_ctr, e.bitwise_op_id, e.execution_sel, e.ff_gt_a_hi, e.ff_gt_a_lo, e.ff_gt_b_hi, e.ff_gt_b_lo, e.ff_gt_cmp_rng_ctr, e.ff_gt_p_sub_a_hi, e.ff_gt_p_sub_a_lo, e.ff_gt_p_sub_b_hi, e.ff_gt_p_sub_b_lo, e.ff_gt_sel, e.ff_gt_sel_gt, e.merkle_check_current_index_in_layer, e.merkle_check_current_node, e.merkle_check_leaf, e.merkle_check_leaf_index, e.merkle_check_remaining_path_len, e.merkle_check_sel, e.merkle_check_start, e.merkle_check_tree_height, e.poseidon2_hash_a_0, e.poseidon2_hash_a_1, e.poseidon2_hash_a_2, e.poseidon2_hash_a_3, e.poseidon2_hash_input_0, e.poseidon2_hash_input_1, e.poseidon2_hash_input_2, e.poseidon2_hash_num_perm_rounds_rem, e.poseidon2_hash_output, e.poseidon2_hash_sel, e.poseidon2_hash_start, e.scalar_mul_bit_idx, e.scalar_mul_point_inf, e.scalar_mul_point_x, e.scalar_mul_point_y, e.scalar_mul_res_inf, e.scalar_mul_res_x, e.scalar_mul_res_y, e.scalar_mul_scalar, e.scalar_mul_sel, e.scalar_mul_start, e.scalar_mul_temp_inf, e.scalar_mul_temp_x, e.scalar_mul_temp_y, e.sha256_a, e.sha256_b, e.sha256_c, e.sha256_d, e.sha256_e, e.sha256_f, e.sha256_g, e.sha256_h, e.sha256_helper_w0, e.sha256_helper_w1, e.sha256_helper_w10, e.sha256_helper_w11, e.sha256_helper_w12, e.sha256_helper_w13, e.sha256_helper_w14, e.sha256_helper_w15, e.sha256_helper_w2, e.sha256_helper_w3, e.sha256_helper_w4, e.sha256_helper_w5, e.sha256_helper_w6, e.sha256_helper_w7, e.sha256_helper_w8, e.sha256_helper_w9, e.sha256_rounds_remaining, e.sha256_sel, e.sha256_start, e.to_radix_acc, e.to_radix_acc_under_p, e.to_radix_exponent, e.to_radix_limb, e.to_radix_limb_eq_p, e.to_radix_limb_index, e.to_radix_limb_lt_p, e.to_radix_not_padding_limb, e.to_radix_radix, e.to_radix_safe_limbs, e.to_radix_sel, e.to_radix_start, e.to_radix_value +#define AVM2_WIRE_ENTITIES execution_input, address_derivation_address, address_derivation_address_y, address_derivation_class_id, address_derivation_deployer_addr, address_derivation_g1_x, address_derivation_g1_y, address_derivation_incoming_viewing_key_x, address_derivation_incoming_viewing_key_y, address_derivation_init_hash, address_derivation_nullifier_key_x, address_derivation_nullifier_key_y, address_derivation_outgoing_viewing_key_x, address_derivation_outgoing_viewing_key_y, address_derivation_partial_address, address_derivation_partial_address_domain_separator, address_derivation_preaddress, address_derivation_preaddress_domain_separator, address_derivation_preaddress_public_key_x, address_derivation_preaddress_public_key_y, address_derivation_public_keys_hash, address_derivation_public_keys_hash_domain_separator, address_derivation_salt, address_derivation_salted_init_hash, address_derivation_sel, address_derivation_tagging_key_x, address_derivation_tagging_key_y, alu_dst_addr, alu_ia, alu_ia_addr, alu_ib, alu_ib_addr, alu_ic, alu_op, alu_sel_op_add, bc_decomposition_abs_diff, bc_decomposition_bytes, bc_decomposition_bytes_pc_plus_1, bc_decomposition_bytes_pc_plus_10, bc_decomposition_bytes_pc_plus_11, bc_decomposition_bytes_pc_plus_12, bc_decomposition_bytes_pc_plus_13, bc_decomposition_bytes_pc_plus_14, bc_decomposition_bytes_pc_plus_15, bc_decomposition_bytes_pc_plus_16, bc_decomposition_bytes_pc_plus_17, bc_decomposition_bytes_pc_plus_18, bc_decomposition_bytes_pc_plus_19, bc_decomposition_bytes_pc_plus_2, bc_decomposition_bytes_pc_plus_20, bc_decomposition_bytes_pc_plus_21, bc_decomposition_bytes_pc_plus_22, bc_decomposition_bytes_pc_plus_23, bc_decomposition_bytes_pc_plus_24, bc_decomposition_bytes_pc_plus_25, bc_decomposition_bytes_pc_plus_26, bc_decomposition_bytes_pc_plus_27, bc_decomposition_bytes_pc_plus_28, bc_decomposition_bytes_pc_plus_29, bc_decomposition_bytes_pc_plus_3, bc_decomposition_bytes_pc_plus_30, bc_decomposition_bytes_pc_plus_31, bc_decomposition_bytes_pc_plus_32, bc_decomposition_bytes_pc_plus_33, bc_decomposition_bytes_pc_plus_34, bc_decomposition_bytes_pc_plus_35, bc_decomposition_bytes_pc_plus_36, bc_decomposition_bytes_pc_plus_4, bc_decomposition_bytes_pc_plus_5, bc_decomposition_bytes_pc_plus_6, bc_decomposition_bytes_pc_plus_7, bc_decomposition_bytes_pc_plus_8, bc_decomposition_bytes_pc_plus_9, bc_decomposition_bytes_rem_inv, bc_decomposition_bytes_rem_min_one_inv, bc_decomposition_bytes_remaining, bc_decomposition_bytes_to_read, bc_decomposition_bytes_to_read_unary, bc_decomposition_id, bc_decomposition_last_of_contract, bc_decomposition_packed_field, bc_decomposition_pc, bc_decomposition_sel, bc_decomposition_sel_overflow_correction_needed, bc_decomposition_sel_packed, bc_decomposition_sel_pc_plus_1, bc_decomposition_sel_pc_plus_10, bc_decomposition_sel_pc_plus_11, bc_decomposition_sel_pc_plus_12, bc_decomposition_sel_pc_plus_13, bc_decomposition_sel_pc_plus_14, bc_decomposition_sel_pc_plus_15, bc_decomposition_sel_pc_plus_16, bc_decomposition_sel_pc_plus_17, bc_decomposition_sel_pc_plus_18, bc_decomposition_sel_pc_plus_19, bc_decomposition_sel_pc_plus_2, bc_decomposition_sel_pc_plus_20, bc_decomposition_sel_pc_plus_21, bc_decomposition_sel_pc_plus_22, bc_decomposition_sel_pc_plus_23, bc_decomposition_sel_pc_plus_24, bc_decomposition_sel_pc_plus_25, bc_decomposition_sel_pc_plus_26, bc_decomposition_sel_pc_plus_27, bc_decomposition_sel_pc_plus_28, bc_decomposition_sel_pc_plus_29, bc_decomposition_sel_pc_plus_3, bc_decomposition_sel_pc_plus_30, bc_decomposition_sel_pc_plus_31, bc_decomposition_sel_pc_plus_32, bc_decomposition_sel_pc_plus_33, bc_decomposition_sel_pc_plus_34, bc_decomposition_sel_pc_plus_35, bc_decomposition_sel_pc_plus_36, bc_decomposition_sel_pc_plus_4, bc_decomposition_sel_pc_plus_5, bc_decomposition_sel_pc_plus_6, bc_decomposition_sel_pc_plus_7, bc_decomposition_sel_pc_plus_8, bc_decomposition_sel_pc_plus_9, bc_hashing_bytecode_id, bc_hashing_incremental_hash, bc_hashing_latch, bc_hashing_output_hash, bc_hashing_packed_field, bc_hashing_pc_index, bc_hashing_sel, bc_hashing_start, bc_retrieval_address, bc_retrieval_artifact_hash, bc_retrieval_bytecode_id, bc_retrieval_class_id, bc_retrieval_deployer_addr, bc_retrieval_err, bc_retrieval_incoming_viewing_key_x, bc_retrieval_incoming_viewing_key_y, bc_retrieval_init_hash, bc_retrieval_nullifier_key_x, bc_retrieval_nullifier_key_y, bc_retrieval_outgoing_viewing_key_x, bc_retrieval_outgoing_viewing_key_y, bc_retrieval_private_function_root, bc_retrieval_public_bytecode_commitment, bc_retrieval_salt, bc_retrieval_sel, bc_retrieval_siloed_address, bc_retrieval_tagging_key_x, bc_retrieval_tagging_key_y, bitwise_acc_ia, bitwise_acc_ib, bitwise_acc_ic, bitwise_ctr, bitwise_ctr_inv, bitwise_ctr_min_one_inv, bitwise_ia_byte, bitwise_ib_byte, bitwise_ic_byte, bitwise_last, bitwise_op_id, bitwise_sel, bitwise_start, bitwise_tag, class_id_derivation_artifact_hash, class_id_derivation_class_id, class_id_derivation_private_function_root, class_id_derivation_public_bytecode_commitment, class_id_derivation_sel, class_id_derivation_temp_constant_for_lookup, context_stack_context_id, context_stack_contract_address, context_stack_is_static, context_stack_msg_sender, context_stack_parent_calldata_offset_addr, context_stack_parent_calldata_size_addr, context_stack_pc, ecc_add_op, ecc_double_op, ecc_inv_2_p_y, ecc_inv_x_diff, ecc_inv_y_diff, ecc_lambda, ecc_p_is_inf, ecc_p_x, ecc_p_y, ecc_q_is_inf, ecc_q_x, ecc_q_y, ecc_r_is_inf, ecc_r_x, ecc_r_y, ecc_result_infinity, ecc_sel, ecc_x_match, ecc_y_match, execution_addressing_error_idx, execution_addressing_error_kind, execution_base_address_tag, execution_base_address_val, execution_bytecode_id, execution_clk, execution_context_id, execution_contract_address, execution_ex_opcode, execution_indirect, execution_is_static, execution_last, execution_last_child_returndata_offset_addr, execution_last_child_returndata_size_addr, execution_last_child_success, execution_msg_sender, execution_op1, execution_op1_after_relative, execution_op2, execution_op2_after_relative, execution_op3, execution_op3_after_relative, execution_op4, execution_op4_after_relative, execution_parent_calldata_offset_addr, execution_parent_calldata_size_addr, execution_pc, execution_rop1, execution_rop2, execution_rop3, execution_rop4, execution_sel, execution_sel_addressing_error, execution_sel_op1_is_address, execution_sel_op2_is_address, execution_sel_op3_is_address, execution_sel_op4_is_address, ff_gt_a, ff_gt_a_hi, ff_gt_a_lo, ff_gt_b, ff_gt_b_hi, ff_gt_b_lo, ff_gt_borrow, ff_gt_cmp_rng_ctr, ff_gt_cmp_rng_ctr_inv, ff_gt_constant_128, ff_gt_p_a_borrow, ff_gt_p_b_borrow, ff_gt_p_sub_a_hi, ff_gt_p_sub_a_lo, ff_gt_p_sub_b_hi, ff_gt_p_sub_b_lo, ff_gt_res_hi, ff_gt_res_lo, ff_gt_result, ff_gt_sel, ff_gt_sel_gt, ff_gt_sel_shift_rng, instr_fetching_bd0, instr_fetching_bd1, instr_fetching_bd10, instr_fetching_bd11, instr_fetching_bd12, instr_fetching_bd13, instr_fetching_bd14, instr_fetching_bd15, instr_fetching_bd16, instr_fetching_bd17, instr_fetching_bd18, instr_fetching_bd19, instr_fetching_bd2, instr_fetching_bd20, instr_fetching_bd21, instr_fetching_bd22, instr_fetching_bd23, instr_fetching_bd24, instr_fetching_bd25, instr_fetching_bd26, instr_fetching_bd27, instr_fetching_bd28, instr_fetching_bd29, instr_fetching_bd3, instr_fetching_bd30, instr_fetching_bd31, instr_fetching_bd32, instr_fetching_bd33, instr_fetching_bd34, instr_fetching_bd35, instr_fetching_bd36, instr_fetching_bd4, instr_fetching_bd5, instr_fetching_bd6, instr_fetching_bd7, instr_fetching_bd8, instr_fetching_bd9, instr_fetching_bytecode_id, instr_fetching_bytecode_size, instr_fetching_bytes_to_read, instr_fetching_exec_opcode, instr_fetching_indirect, instr_fetching_instr_abs_diff, instr_fetching_instr_out_of_range, instr_fetching_instr_size, instr_fetching_op1, instr_fetching_op2, instr_fetching_op3, instr_fetching_op4, instr_fetching_op5, instr_fetching_op6, instr_fetching_op7, instr_fetching_opcode_out_of_range, instr_fetching_parsing_err, instr_fetching_pc, instr_fetching_pc_abs_diff, instr_fetching_pc_out_of_range, instr_fetching_pc_size_in_bits, instr_fetching_sel, instr_fetching_sel_has_tag, instr_fetching_sel_op_dc_0, instr_fetching_sel_op_dc_1, instr_fetching_sel_op_dc_10, instr_fetching_sel_op_dc_11, instr_fetching_sel_op_dc_12, instr_fetching_sel_op_dc_13, instr_fetching_sel_op_dc_14, instr_fetching_sel_op_dc_15, instr_fetching_sel_op_dc_16, instr_fetching_sel_op_dc_17, instr_fetching_sel_op_dc_2, instr_fetching_sel_op_dc_3, instr_fetching_sel_op_dc_4, instr_fetching_sel_op_dc_5, instr_fetching_sel_op_dc_6, instr_fetching_sel_op_dc_7, instr_fetching_sel_op_dc_8, instr_fetching_sel_op_dc_9, instr_fetching_sel_pc_in_range, instr_fetching_sel_tag_is_op2, instr_fetching_tag_out_of_range, instr_fetching_tag_value, merkle_check_constant_2, merkle_check_end, merkle_check_index, merkle_check_index_is_even, merkle_check_path_len, merkle_check_read_left_node, merkle_check_read_node, merkle_check_read_output_hash, merkle_check_read_right_node, merkle_check_read_root, merkle_check_remaining_path_len_inv, merkle_check_sel, merkle_check_sibling, merkle_check_start, merkle_check_write, merkle_check_write_left_node, merkle_check_write_node, merkle_check_write_output_hash, merkle_check_write_right_node, merkle_check_write_root, poseidon2_hash_a_0, poseidon2_hash_a_1, poseidon2_hash_a_2, poseidon2_hash_a_3, poseidon2_hash_b_0, poseidon2_hash_b_1, poseidon2_hash_b_2, poseidon2_hash_b_3, poseidon2_hash_end, poseidon2_hash_input_0, poseidon2_hash_input_1, poseidon2_hash_input_2, poseidon2_hash_input_len, poseidon2_hash_num_perm_rounds_rem, poseidon2_hash_num_perm_rounds_rem_inv, poseidon2_hash_output, poseidon2_hash_padding, poseidon2_hash_sel, poseidon2_hash_start, poseidon2_perm_B_10_0, poseidon2_perm_B_10_1, poseidon2_perm_B_10_2, poseidon2_perm_B_10_3, poseidon2_perm_B_11_0, poseidon2_perm_B_11_1, poseidon2_perm_B_11_2, poseidon2_perm_B_11_3, poseidon2_perm_B_12_0, poseidon2_perm_B_12_1, poseidon2_perm_B_12_2, poseidon2_perm_B_12_3, poseidon2_perm_B_13_0, poseidon2_perm_B_13_1, poseidon2_perm_B_13_2, poseidon2_perm_B_13_3, poseidon2_perm_B_14_0, poseidon2_perm_B_14_1, poseidon2_perm_B_14_2, poseidon2_perm_B_14_3, poseidon2_perm_B_15_0, poseidon2_perm_B_15_1, poseidon2_perm_B_15_2, poseidon2_perm_B_15_3, poseidon2_perm_B_16_0, poseidon2_perm_B_16_1, poseidon2_perm_B_16_2, poseidon2_perm_B_16_3, poseidon2_perm_B_17_0, poseidon2_perm_B_17_1, poseidon2_perm_B_17_2, poseidon2_perm_B_17_3, poseidon2_perm_B_18_0, poseidon2_perm_B_18_1, poseidon2_perm_B_18_2, poseidon2_perm_B_18_3, poseidon2_perm_B_19_0, poseidon2_perm_B_19_1, poseidon2_perm_B_19_2, poseidon2_perm_B_19_3, poseidon2_perm_B_20_0, poseidon2_perm_B_20_1, poseidon2_perm_B_20_2, poseidon2_perm_B_20_3, poseidon2_perm_B_21_0, poseidon2_perm_B_21_1, poseidon2_perm_B_21_2, poseidon2_perm_B_21_3, poseidon2_perm_B_22_0, poseidon2_perm_B_22_1, poseidon2_perm_B_22_2, poseidon2_perm_B_22_3, poseidon2_perm_B_23_0, poseidon2_perm_B_23_1, poseidon2_perm_B_23_2, poseidon2_perm_B_23_3, poseidon2_perm_B_24_0, poseidon2_perm_B_24_1, poseidon2_perm_B_24_2, poseidon2_perm_B_24_3, poseidon2_perm_B_25_0, poseidon2_perm_B_25_1, poseidon2_perm_B_25_2, poseidon2_perm_B_25_3, poseidon2_perm_B_26_0, poseidon2_perm_B_26_1, poseidon2_perm_B_26_2, poseidon2_perm_B_26_3, poseidon2_perm_B_27_0, poseidon2_perm_B_27_1, poseidon2_perm_B_27_2, poseidon2_perm_B_27_3, poseidon2_perm_B_28_0, poseidon2_perm_B_28_1, poseidon2_perm_B_28_2, poseidon2_perm_B_28_3, poseidon2_perm_B_29_0, poseidon2_perm_B_29_1, poseidon2_perm_B_29_2, poseidon2_perm_B_29_3, poseidon2_perm_B_30_0, poseidon2_perm_B_30_1, poseidon2_perm_B_30_2, poseidon2_perm_B_30_3, poseidon2_perm_B_31_0, poseidon2_perm_B_31_1, poseidon2_perm_B_31_2, poseidon2_perm_B_31_3, poseidon2_perm_B_32_0, poseidon2_perm_B_32_1, poseidon2_perm_B_32_2, poseidon2_perm_B_32_3, poseidon2_perm_B_33_0, poseidon2_perm_B_33_1, poseidon2_perm_B_33_2, poseidon2_perm_B_33_3, poseidon2_perm_B_34_0, poseidon2_perm_B_34_1, poseidon2_perm_B_34_2, poseidon2_perm_B_34_3, poseidon2_perm_B_35_0, poseidon2_perm_B_35_1, poseidon2_perm_B_35_2, poseidon2_perm_B_35_3, poseidon2_perm_B_36_0, poseidon2_perm_B_36_1, poseidon2_perm_B_36_2, poseidon2_perm_B_36_3, poseidon2_perm_B_37_0, poseidon2_perm_B_37_1, poseidon2_perm_B_37_2, poseidon2_perm_B_37_3, poseidon2_perm_B_38_0, poseidon2_perm_B_38_1, poseidon2_perm_B_38_2, poseidon2_perm_B_38_3, poseidon2_perm_B_39_0, poseidon2_perm_B_39_1, poseidon2_perm_B_39_2, poseidon2_perm_B_39_3, poseidon2_perm_B_40_0, poseidon2_perm_B_40_1, poseidon2_perm_B_40_2, poseidon2_perm_B_40_3, poseidon2_perm_B_41_0, poseidon2_perm_B_41_1, poseidon2_perm_B_41_2, poseidon2_perm_B_41_3, poseidon2_perm_B_42_0, poseidon2_perm_B_42_1, poseidon2_perm_B_42_2, poseidon2_perm_B_42_3, poseidon2_perm_B_43_0, poseidon2_perm_B_43_1, poseidon2_perm_B_43_2, poseidon2_perm_B_43_3, poseidon2_perm_B_44_0, poseidon2_perm_B_44_1, poseidon2_perm_B_44_2, poseidon2_perm_B_44_3, poseidon2_perm_B_45_0, poseidon2_perm_B_45_1, poseidon2_perm_B_45_2, poseidon2_perm_B_45_3, poseidon2_perm_B_46_0, poseidon2_perm_B_46_1, poseidon2_perm_B_46_2, poseidon2_perm_B_46_3, poseidon2_perm_B_47_0, poseidon2_perm_B_47_1, poseidon2_perm_B_47_2, poseidon2_perm_B_47_3, poseidon2_perm_B_48_0, poseidon2_perm_B_48_1, poseidon2_perm_B_48_2, poseidon2_perm_B_48_3, poseidon2_perm_B_49_0, poseidon2_perm_B_49_1, poseidon2_perm_B_49_2, poseidon2_perm_B_49_3, poseidon2_perm_B_4_0, poseidon2_perm_B_4_1, poseidon2_perm_B_4_2, poseidon2_perm_B_4_3, poseidon2_perm_B_50_0, poseidon2_perm_B_50_1, poseidon2_perm_B_50_2, poseidon2_perm_B_50_3, poseidon2_perm_B_51_0, poseidon2_perm_B_51_1, poseidon2_perm_B_51_2, poseidon2_perm_B_51_3, poseidon2_perm_B_52_0, poseidon2_perm_B_52_1, poseidon2_perm_B_52_2, poseidon2_perm_B_52_3, poseidon2_perm_B_53_0, poseidon2_perm_B_53_1, poseidon2_perm_B_53_2, poseidon2_perm_B_53_3, poseidon2_perm_B_54_0, poseidon2_perm_B_54_1, poseidon2_perm_B_54_2, poseidon2_perm_B_54_3, poseidon2_perm_B_55_0, poseidon2_perm_B_55_1, poseidon2_perm_B_55_2, poseidon2_perm_B_55_3, poseidon2_perm_B_56_0, poseidon2_perm_B_56_1, poseidon2_perm_B_56_2, poseidon2_perm_B_56_3, poseidon2_perm_B_57_0, poseidon2_perm_B_57_1, poseidon2_perm_B_57_2, poseidon2_perm_B_57_3, poseidon2_perm_B_58_0, poseidon2_perm_B_58_1, poseidon2_perm_B_58_2, poseidon2_perm_B_58_3, poseidon2_perm_B_59_0, poseidon2_perm_B_59_1, poseidon2_perm_B_59_2, poseidon2_perm_B_59_3, poseidon2_perm_B_5_0, poseidon2_perm_B_5_1, poseidon2_perm_B_5_2, poseidon2_perm_B_5_3, poseidon2_perm_B_6_0, poseidon2_perm_B_6_1, poseidon2_perm_B_6_2, poseidon2_perm_B_6_3, poseidon2_perm_B_7_0, poseidon2_perm_B_7_1, poseidon2_perm_B_7_2, poseidon2_perm_B_7_3, poseidon2_perm_B_8_0, poseidon2_perm_B_8_1, poseidon2_perm_B_8_2, poseidon2_perm_B_8_3, poseidon2_perm_B_9_0, poseidon2_perm_B_9_1, poseidon2_perm_B_9_2, poseidon2_perm_B_9_3, poseidon2_perm_EXT_LAYER_4, poseidon2_perm_EXT_LAYER_5, poseidon2_perm_EXT_LAYER_6, poseidon2_perm_EXT_LAYER_7, poseidon2_perm_T_0_4, poseidon2_perm_T_0_5, poseidon2_perm_T_0_6, poseidon2_perm_T_0_7, poseidon2_perm_T_1_4, poseidon2_perm_T_1_5, poseidon2_perm_T_1_6, poseidon2_perm_T_1_7, poseidon2_perm_T_2_4, poseidon2_perm_T_2_5, poseidon2_perm_T_2_6, poseidon2_perm_T_2_7, poseidon2_perm_T_3_4, poseidon2_perm_T_3_5, poseidon2_perm_T_3_6, poseidon2_perm_T_3_7, poseidon2_perm_T_60_4, poseidon2_perm_T_60_5, poseidon2_perm_T_60_6, poseidon2_perm_T_60_7, poseidon2_perm_T_61_4, poseidon2_perm_T_61_5, poseidon2_perm_T_61_6, poseidon2_perm_T_61_7, poseidon2_perm_T_62_4, poseidon2_perm_T_62_5, poseidon2_perm_T_62_6, poseidon2_perm_T_62_7, poseidon2_perm_T_63_4, poseidon2_perm_T_63_5, poseidon2_perm_T_63_6, poseidon2_perm_T_63_7, poseidon2_perm_a_0, poseidon2_perm_a_1, poseidon2_perm_a_2, poseidon2_perm_a_3, poseidon2_perm_b_0, poseidon2_perm_b_1, poseidon2_perm_b_2, poseidon2_perm_b_3, poseidon2_perm_sel, range_check_dyn_diff, range_check_dyn_rng_chk_bits, range_check_dyn_rng_chk_pow_2, range_check_is_lte_u112, range_check_is_lte_u128, range_check_is_lte_u16, range_check_is_lte_u32, range_check_is_lte_u48, range_check_is_lte_u64, range_check_is_lte_u80, range_check_is_lte_u96, range_check_rng_chk_bits, range_check_sel, range_check_sel_r0_16_bit_rng_lookup, range_check_sel_r1_16_bit_rng_lookup, range_check_sel_r2_16_bit_rng_lookup, range_check_sel_r3_16_bit_rng_lookup, range_check_sel_r4_16_bit_rng_lookup, range_check_sel_r5_16_bit_rng_lookup, range_check_sel_r6_16_bit_rng_lookup, range_check_u16_r0, range_check_u16_r1, range_check_u16_r2, range_check_u16_r3, range_check_u16_r4, range_check_u16_r5, range_check_u16_r6, range_check_u16_r7, range_check_value, scalar_mul_bit, scalar_mul_bit_idx, scalar_mul_bit_radix, scalar_mul_end, scalar_mul_not_end, scalar_mul_point_inf, scalar_mul_point_x, scalar_mul_point_y, scalar_mul_res_inf, scalar_mul_res_x, scalar_mul_res_y, scalar_mul_scalar, scalar_mul_sel, scalar_mul_should_add, scalar_mul_start, scalar_mul_temp_inf, scalar_mul_temp_x, scalar_mul_temp_y, sha256_a, sha256_a_and_b, sha256_a_and_b_xor_a_and_c, sha256_a_and_c, sha256_a_rotr_13, sha256_a_rotr_2, sha256_a_rotr_22, sha256_a_rotr_2_xor_a_rotr_13, sha256_and_sel, sha256_b, sha256_b_and_c, sha256_c, sha256_ch, sha256_clk, sha256_computed_w_lhs, sha256_computed_w_rhs, sha256_d, sha256_e, sha256_e_and_f, sha256_e_rotr_11, sha256_e_rotr_25, sha256_e_rotr_6, sha256_e_rotr_6_xor_e_rotr_11, sha256_f, sha256_g, sha256_h, sha256_helper_w0, sha256_helper_w1, sha256_helper_w10, sha256_helper_w11, sha256_helper_w12, sha256_helper_w13, sha256_helper_w14, sha256_helper_w15, sha256_helper_w2, sha256_helper_w3, sha256_helper_w4, sha256_helper_w5, sha256_helper_w6, sha256_helper_w7, sha256_helper_w8, sha256_helper_w9, sha256_init_a, sha256_init_b, sha256_init_c, sha256_init_d, sha256_init_e, sha256_init_f, sha256_init_g, sha256_init_h, sha256_input_offset, sha256_is_input_round, sha256_latch, sha256_lhs_a_13, sha256_lhs_a_2, sha256_lhs_a_22, sha256_lhs_e_11, sha256_lhs_e_25, sha256_lhs_e_6, sha256_lhs_w_10, sha256_lhs_w_17, sha256_lhs_w_18, sha256_lhs_w_19, sha256_lhs_w_3, sha256_lhs_w_7, sha256_maj, sha256_next_a_lhs, sha256_next_a_rhs, sha256_next_e_lhs, sha256_next_e_rhs, sha256_not_e, sha256_not_e_and_g, sha256_output_a_lhs, sha256_output_a_rhs, sha256_output_b_lhs, sha256_output_b_rhs, sha256_output_c_lhs, sha256_output_c_rhs, sha256_output_d_lhs, sha256_output_d_rhs, sha256_output_e_lhs, sha256_output_e_rhs, sha256_output_f_lhs, sha256_output_f_rhs, sha256_output_g_lhs, sha256_output_g_rhs, sha256_output_h_lhs, sha256_output_h_rhs, sha256_output_offset, sha256_perform_round, sha256_rhs_a_13, sha256_rhs_a_2, sha256_rhs_a_22, sha256_rhs_e_11, sha256_rhs_e_25, sha256_rhs_e_6, sha256_rhs_w_10, sha256_rhs_w_17, sha256_rhs_w_18, sha256_rhs_w_19, sha256_rhs_w_3, sha256_rhs_w_7, sha256_round_constant, sha256_round_count, sha256_rounds_remaining, sha256_rounds_remaining_inv, sha256_s_0, sha256_s_1, sha256_sel, sha256_start, sha256_state_offset, sha256_w, sha256_w_15_rotr_18, sha256_w_15_rotr_7, sha256_w_15_rotr_7_xor_w_15_rotr_18, sha256_w_15_rshift_3, sha256_w_2_rotr_17, sha256_w_2_rotr_17_xor_w_2_rotr_19, sha256_w_2_rotr_19, sha256_w_2_rshift_10, sha256_w_s_0, sha256_w_s_1, sha256_xor_sel, to_radix_acc, to_radix_acc_under_p, to_radix_end, to_radix_exponent, to_radix_found, to_radix_is_unsafe_limb, to_radix_limb, to_radix_limb_eq_p, to_radix_limb_index, to_radix_limb_lt_p, to_radix_limb_p_diff, to_radix_limb_radix_diff, to_radix_not_end, to_radix_not_padding_limb, to_radix_p_limb, to_radix_radix, to_radix_rem_inverse, to_radix_safe_limbs, to_radix_safety_diff_inverse, to_radix_sel, to_radix_start, to_radix_value, lookup_poseidon2_hash_poseidon2_perm_counts, lookup_range_check_dyn_rng_chk_pow_2_counts, lookup_range_check_dyn_diff_is_u16_counts, lookup_range_check_r0_is_u16_counts, lookup_range_check_r1_is_u16_counts, lookup_range_check_r2_is_u16_counts, lookup_range_check_r3_is_u16_counts, lookup_range_check_r4_is_u16_counts, lookup_range_check_r5_is_u16_counts, lookup_range_check_r6_is_u16_counts, lookup_range_check_r7_is_u16_counts, lookup_to_radix_limb_range_counts, lookup_to_radix_limb_less_than_radix_range_counts, lookup_to_radix_fetch_safe_limbs_counts, lookup_to_radix_fetch_p_limb_counts, lookup_to_radix_limb_p_diff_range_counts, lookup_scalar_mul_to_radix_counts, lookup_scalar_mul_double_counts, lookup_scalar_mul_add_counts, lookup_address_derivation_salted_initialization_hash_poseidon2_0_counts, lookup_address_derivation_salted_initialization_hash_poseidon2_1_counts, lookup_address_derivation_partial_address_poseidon2_counts, lookup_address_derivation_public_keys_hash_poseidon2_0_counts, lookup_address_derivation_public_keys_hash_poseidon2_1_counts, lookup_address_derivation_public_keys_hash_poseidon2_2_counts, lookup_address_derivation_public_keys_hash_poseidon2_3_counts, lookup_address_derivation_public_keys_hash_poseidon2_4_counts, lookup_address_derivation_preaddress_poseidon2_counts, lookup_address_derivation_preaddress_scalar_mul_counts, lookup_address_derivation_address_ecadd_counts, lookup_bc_decomposition_bytes_are_bytes_counts, lookup_bc_decomposition_abs_diff_is_u16_counts, lookup_bc_decomposition_bytes_to_read_as_unary_counts, lookup_bc_hashing_get_packed_field_counts, lookup_bc_hashing_iv_is_len_counts, lookup_bc_hashing_poseidon2_hash_counts, lookup_bc_retrieval_class_id_derivation_counts, lookup_bc_retrieval_bytecode_hash_is_correct_counts, lookup_instr_fetching_pc_abs_diff_positive_counts, lookup_instr_fetching_instr_abs_diff_positive_counts, lookup_instr_fetching_tag_value_validation_counts, lookup_instr_fetching_bytecode_size_from_bc_dec_counts, lookup_instr_fetching_bytes_from_bc_dec_counts, lookup_instr_fetching_wire_instruction_info_counts, lookup_class_id_derivation_class_id_poseidon2_0_counts, lookup_class_id_derivation_class_id_poseidon2_1_counts, lookup_bitwise_integral_tag_length_counts, lookup_bitwise_byte_operations_counts, lookup_merkle_check_merkle_poseidon2_read_counts, lookup_merkle_check_merkle_poseidon2_write_counts, lookup_sha256_round_constant_counts, lookup_ff_gt_a_lo_range_counts, lookup_ff_gt_a_hi_range_counts +#define AVM2_DERIVED_WITNESS_ENTITIES lookup_poseidon2_hash_poseidon2_perm_inv, lookup_range_check_dyn_rng_chk_pow_2_inv, lookup_range_check_dyn_diff_is_u16_inv, lookup_range_check_r0_is_u16_inv, lookup_range_check_r1_is_u16_inv, lookup_range_check_r2_is_u16_inv, lookup_range_check_r3_is_u16_inv, lookup_range_check_r4_is_u16_inv, lookup_range_check_r5_is_u16_inv, lookup_range_check_r6_is_u16_inv, lookup_range_check_r7_is_u16_inv, lookup_to_radix_limb_range_inv, lookup_to_radix_limb_less_than_radix_range_inv, lookup_to_radix_fetch_safe_limbs_inv, lookup_to_radix_fetch_p_limb_inv, lookup_to_radix_limb_p_diff_range_inv, lookup_scalar_mul_to_radix_inv, lookup_scalar_mul_double_inv, lookup_scalar_mul_add_inv, lookup_address_derivation_salted_initialization_hash_poseidon2_0_inv, lookup_address_derivation_salted_initialization_hash_poseidon2_1_inv, lookup_address_derivation_partial_address_poseidon2_inv, lookup_address_derivation_public_keys_hash_poseidon2_0_inv, lookup_address_derivation_public_keys_hash_poseidon2_1_inv, lookup_address_derivation_public_keys_hash_poseidon2_2_inv, lookup_address_derivation_public_keys_hash_poseidon2_3_inv, lookup_address_derivation_public_keys_hash_poseidon2_4_inv, lookup_address_derivation_preaddress_poseidon2_inv, lookup_address_derivation_preaddress_scalar_mul_inv, lookup_address_derivation_address_ecadd_inv, lookup_bc_decomposition_bytes_are_bytes_inv, lookup_bc_decomposition_abs_diff_is_u16_inv, lookup_bc_decomposition_bytes_to_read_as_unary_inv, lookup_bc_hashing_get_packed_field_inv, lookup_bc_hashing_iv_is_len_inv, lookup_bc_hashing_poseidon2_hash_inv, lookup_bc_retrieval_class_id_derivation_inv, lookup_bc_retrieval_bytecode_hash_is_correct_inv, lookup_instr_fetching_pc_abs_diff_positive_inv, lookup_instr_fetching_instr_abs_diff_positive_inv, lookup_instr_fetching_tag_value_validation_inv, lookup_instr_fetching_bytecode_size_from_bc_dec_inv, lookup_instr_fetching_bytes_from_bc_dec_inv, lookup_instr_fetching_wire_instruction_info_inv, lookup_class_id_derivation_class_id_poseidon2_0_inv, lookup_class_id_derivation_class_id_poseidon2_1_inv, lookup_bitwise_integral_tag_length_inv, lookup_bitwise_byte_operations_inv, lookup_merkle_check_merkle_poseidon2_read_inv, lookup_merkle_check_merkle_poseidon2_write_inv, lookup_sha256_round_constant_inv, lookup_ff_gt_a_lo_range_inv, lookup_ff_gt_a_hi_range_inv +#define AVM2_SHIFTED_ENTITIES bc_decomposition_bytes_shift, bc_decomposition_bytes_pc_plus_1_shift, bc_decomposition_bytes_pc_plus_10_shift, bc_decomposition_bytes_pc_plus_11_shift, bc_decomposition_bytes_pc_plus_12_shift, bc_decomposition_bytes_pc_plus_13_shift, bc_decomposition_bytes_pc_plus_14_shift, bc_decomposition_bytes_pc_plus_15_shift, bc_decomposition_bytes_pc_plus_16_shift, bc_decomposition_bytes_pc_plus_17_shift, bc_decomposition_bytes_pc_plus_18_shift, bc_decomposition_bytes_pc_plus_19_shift, bc_decomposition_bytes_pc_plus_2_shift, bc_decomposition_bytes_pc_plus_20_shift, bc_decomposition_bytes_pc_plus_21_shift, bc_decomposition_bytes_pc_plus_22_shift, bc_decomposition_bytes_pc_plus_23_shift, bc_decomposition_bytes_pc_plus_24_shift, bc_decomposition_bytes_pc_plus_25_shift, bc_decomposition_bytes_pc_plus_26_shift, bc_decomposition_bytes_pc_plus_27_shift, bc_decomposition_bytes_pc_plus_28_shift, bc_decomposition_bytes_pc_plus_29_shift, bc_decomposition_bytes_pc_plus_3_shift, bc_decomposition_bytes_pc_plus_30_shift, bc_decomposition_bytes_pc_plus_31_shift, bc_decomposition_bytes_pc_plus_32_shift, bc_decomposition_bytes_pc_plus_33_shift, bc_decomposition_bytes_pc_plus_34_shift, bc_decomposition_bytes_pc_plus_35_shift, bc_decomposition_bytes_pc_plus_4_shift, bc_decomposition_bytes_pc_plus_5_shift, bc_decomposition_bytes_pc_plus_6_shift, bc_decomposition_bytes_pc_plus_7_shift, bc_decomposition_bytes_pc_plus_8_shift, bc_decomposition_bytes_pc_plus_9_shift, bc_decomposition_bytes_remaining_shift, bc_decomposition_id_shift, bc_decomposition_pc_shift, bc_decomposition_sel_shift, bc_hashing_bytecode_id_shift, bc_hashing_incremental_hash_shift, bc_hashing_pc_index_shift, bc_hashing_sel_shift, bc_hashing_start_shift, bitwise_acc_ia_shift, bitwise_acc_ib_shift, bitwise_acc_ic_shift, bitwise_ctr_shift, bitwise_op_id_shift, execution_sel_shift, ff_gt_a_hi_shift, ff_gt_a_lo_shift, ff_gt_b_hi_shift, ff_gt_b_lo_shift, ff_gt_cmp_rng_ctr_shift, ff_gt_p_sub_a_hi_shift, ff_gt_p_sub_a_lo_shift, ff_gt_p_sub_b_hi_shift, ff_gt_p_sub_b_lo_shift, ff_gt_sel_shift, ff_gt_sel_gt_shift, merkle_check_index_shift, merkle_check_path_len_shift, merkle_check_read_node_shift, merkle_check_read_root_shift, merkle_check_sel_shift, merkle_check_start_shift, merkle_check_write_shift, merkle_check_write_node_shift, merkle_check_write_root_shift, poseidon2_hash_a_0_shift, poseidon2_hash_a_1_shift, poseidon2_hash_a_2_shift, poseidon2_hash_a_3_shift, poseidon2_hash_input_0_shift, poseidon2_hash_input_1_shift, poseidon2_hash_input_2_shift, poseidon2_hash_num_perm_rounds_rem_shift, poseidon2_hash_output_shift, poseidon2_hash_sel_shift, poseidon2_hash_start_shift, scalar_mul_bit_idx_shift, scalar_mul_point_inf_shift, scalar_mul_point_x_shift, scalar_mul_point_y_shift, scalar_mul_res_inf_shift, scalar_mul_res_x_shift, scalar_mul_res_y_shift, scalar_mul_scalar_shift, scalar_mul_sel_shift, scalar_mul_start_shift, scalar_mul_temp_inf_shift, scalar_mul_temp_x_shift, scalar_mul_temp_y_shift, sha256_a_shift, sha256_b_shift, sha256_c_shift, sha256_d_shift, sha256_e_shift, sha256_f_shift, sha256_g_shift, sha256_h_shift, sha256_helper_w0_shift, sha256_helper_w1_shift, sha256_helper_w10_shift, sha256_helper_w11_shift, sha256_helper_w12_shift, sha256_helper_w13_shift, sha256_helper_w14_shift, sha256_helper_w15_shift, sha256_helper_w2_shift, sha256_helper_w3_shift, sha256_helper_w4_shift, sha256_helper_w5_shift, sha256_helper_w6_shift, sha256_helper_w7_shift, sha256_helper_w8_shift, sha256_helper_w9_shift, sha256_rounds_remaining_shift, sha256_sel_shift, sha256_start_shift, to_radix_acc_shift, to_radix_acc_under_p_shift, to_radix_exponent_shift, to_radix_limb_shift, to_radix_limb_eq_p_shift, to_radix_limb_index_shift, to_radix_limb_lt_p_shift, to_radix_not_padding_limb_shift, to_radix_radix_shift, to_radix_safe_limbs_shift, to_radix_sel_shift, to_radix_start_shift, to_radix_value_shift +#define AVM2_TO_BE_SHIFTED(e) e.bc_decomposition_bytes, e.bc_decomposition_bytes_pc_plus_1, e.bc_decomposition_bytes_pc_plus_10, e.bc_decomposition_bytes_pc_plus_11, e.bc_decomposition_bytes_pc_plus_12, e.bc_decomposition_bytes_pc_plus_13, e.bc_decomposition_bytes_pc_plus_14, e.bc_decomposition_bytes_pc_plus_15, e.bc_decomposition_bytes_pc_plus_16, e.bc_decomposition_bytes_pc_plus_17, e.bc_decomposition_bytes_pc_plus_18, e.bc_decomposition_bytes_pc_plus_19, e.bc_decomposition_bytes_pc_plus_2, e.bc_decomposition_bytes_pc_plus_20, e.bc_decomposition_bytes_pc_plus_21, e.bc_decomposition_bytes_pc_plus_22, e.bc_decomposition_bytes_pc_plus_23, e.bc_decomposition_bytes_pc_plus_24, e.bc_decomposition_bytes_pc_plus_25, e.bc_decomposition_bytes_pc_plus_26, e.bc_decomposition_bytes_pc_plus_27, e.bc_decomposition_bytes_pc_plus_28, e.bc_decomposition_bytes_pc_plus_29, e.bc_decomposition_bytes_pc_plus_3, e.bc_decomposition_bytes_pc_plus_30, e.bc_decomposition_bytes_pc_plus_31, e.bc_decomposition_bytes_pc_plus_32, e.bc_decomposition_bytes_pc_plus_33, e.bc_decomposition_bytes_pc_plus_34, e.bc_decomposition_bytes_pc_plus_35, e.bc_decomposition_bytes_pc_plus_4, e.bc_decomposition_bytes_pc_plus_5, e.bc_decomposition_bytes_pc_plus_6, e.bc_decomposition_bytes_pc_plus_7, e.bc_decomposition_bytes_pc_plus_8, e.bc_decomposition_bytes_pc_plus_9, e.bc_decomposition_bytes_remaining, e.bc_decomposition_id, e.bc_decomposition_pc, e.bc_decomposition_sel, e.bc_hashing_bytecode_id, e.bc_hashing_incremental_hash, e.bc_hashing_pc_index, e.bc_hashing_sel, e.bc_hashing_start, e.bitwise_acc_ia, e.bitwise_acc_ib, e.bitwise_acc_ic, e.bitwise_ctr, e.bitwise_op_id, e.execution_sel, e.ff_gt_a_hi, e.ff_gt_a_lo, e.ff_gt_b_hi, e.ff_gt_b_lo, e.ff_gt_cmp_rng_ctr, e.ff_gt_p_sub_a_hi, e.ff_gt_p_sub_a_lo, e.ff_gt_p_sub_b_hi, e.ff_gt_p_sub_b_lo, e.ff_gt_sel, e.ff_gt_sel_gt, e.merkle_check_index, e.merkle_check_path_len, e.merkle_check_read_node, e.merkle_check_read_root, e.merkle_check_sel, e.merkle_check_start, e.merkle_check_write, e.merkle_check_write_node, e.merkle_check_write_root, e.poseidon2_hash_a_0, e.poseidon2_hash_a_1, e.poseidon2_hash_a_2, e.poseidon2_hash_a_3, e.poseidon2_hash_input_0, e.poseidon2_hash_input_1, e.poseidon2_hash_input_2, e.poseidon2_hash_num_perm_rounds_rem, e.poseidon2_hash_output, e.poseidon2_hash_sel, e.poseidon2_hash_start, e.scalar_mul_bit_idx, e.scalar_mul_point_inf, e.scalar_mul_point_x, e.scalar_mul_point_y, e.scalar_mul_res_inf, e.scalar_mul_res_x, e.scalar_mul_res_y, e.scalar_mul_scalar, e.scalar_mul_sel, e.scalar_mul_start, e.scalar_mul_temp_inf, e.scalar_mul_temp_x, e.scalar_mul_temp_y, e.sha256_a, e.sha256_b, e.sha256_c, e.sha256_d, e.sha256_e, e.sha256_f, e.sha256_g, e.sha256_h, e.sha256_helper_w0, e.sha256_helper_w1, e.sha256_helper_w10, e.sha256_helper_w11, e.sha256_helper_w12, e.sha256_helper_w13, e.sha256_helper_w14, e.sha256_helper_w15, e.sha256_helper_w2, e.sha256_helper_w3, e.sha256_helper_w4, e.sha256_helper_w5, e.sha256_helper_w6, e.sha256_helper_w7, e.sha256_helper_w8, e.sha256_helper_w9, e.sha256_rounds_remaining, e.sha256_sel, e.sha256_start, e.to_radix_acc, e.to_radix_acc_under_p, e.to_radix_exponent, e.to_radix_limb, e.to_radix_limb_eq_p, e.to_radix_limb_index, e.to_radix_limb_lt_p, e.to_radix_not_padding_limb, e.to_radix_radix, e.to_radix_safe_limbs, e.to_radix_sel, e.to_radix_start, e.to_radix_value #define AVM2_ALL_ENTITIES AVM2_PRECOMPUTED_ENTITIES, AVM2_WIRE_ENTITIES, AVM2_DERIVED_WITNESS_ENTITIES, AVM2_SHIFTED_ENTITIES #define AVM2_UNSHIFTED_ENTITIES AVM2_PRECOMPUTED_ENTITIES, AVM2_WIRE_ENTITIES, AVM2_DERIVED_WITNESS_ENTITIES #define AVM2_WITNESS_ENTITIES AVM2_WIRE_ENTITIES, AVM2_DERIVED_WITNESS_ENTITIES -#define AVM2_TO_BE_SHIFTED_COLUMNS Column::bc_decomposition_bytes, Column::bc_decomposition_bytes_pc_plus_1, Column::bc_decomposition_bytes_pc_plus_10, Column::bc_decomposition_bytes_pc_plus_11, Column::bc_decomposition_bytes_pc_plus_12, Column::bc_decomposition_bytes_pc_plus_13, Column::bc_decomposition_bytes_pc_plus_14, Column::bc_decomposition_bytes_pc_plus_15, Column::bc_decomposition_bytes_pc_plus_16, Column::bc_decomposition_bytes_pc_plus_17, Column::bc_decomposition_bytes_pc_plus_18, Column::bc_decomposition_bytes_pc_plus_19, Column::bc_decomposition_bytes_pc_plus_2, Column::bc_decomposition_bytes_pc_plus_20, Column::bc_decomposition_bytes_pc_plus_21, Column::bc_decomposition_bytes_pc_plus_22, Column::bc_decomposition_bytes_pc_plus_23, Column::bc_decomposition_bytes_pc_plus_24, Column::bc_decomposition_bytes_pc_plus_25, Column::bc_decomposition_bytes_pc_plus_26, Column::bc_decomposition_bytes_pc_plus_27, Column::bc_decomposition_bytes_pc_plus_28, Column::bc_decomposition_bytes_pc_plus_29, Column::bc_decomposition_bytes_pc_plus_3, Column::bc_decomposition_bytes_pc_plus_30, Column::bc_decomposition_bytes_pc_plus_31, Column::bc_decomposition_bytes_pc_plus_32, Column::bc_decomposition_bytes_pc_plus_33, Column::bc_decomposition_bytes_pc_plus_34, Column::bc_decomposition_bytes_pc_plus_35, Column::bc_decomposition_bytes_pc_plus_4, Column::bc_decomposition_bytes_pc_plus_5, Column::bc_decomposition_bytes_pc_plus_6, Column::bc_decomposition_bytes_pc_plus_7, Column::bc_decomposition_bytes_pc_plus_8, Column::bc_decomposition_bytes_pc_plus_9, Column::bc_decomposition_bytes_remaining, Column::bc_decomposition_id, Column::bc_decomposition_pc, Column::bc_decomposition_sel, Column::bc_hashing_bytecode_id, Column::bc_hashing_incremental_hash, Column::bc_hashing_pc_index, Column::bc_hashing_sel, Column::bc_hashing_start, Column::bitwise_acc_ia, Column::bitwise_acc_ib, Column::bitwise_acc_ic, Column::bitwise_ctr, Column::bitwise_op_id, Column::execution_sel, Column::ff_gt_a_hi, Column::ff_gt_a_lo, Column::ff_gt_b_hi, Column::ff_gt_b_lo, Column::ff_gt_cmp_rng_ctr, Column::ff_gt_p_sub_a_hi, Column::ff_gt_p_sub_a_lo, Column::ff_gt_p_sub_b_hi, Column::ff_gt_p_sub_b_lo, Column::ff_gt_sel, Column::ff_gt_sel_gt, Column::merkle_check_current_index_in_layer, Column::merkle_check_current_node, Column::merkle_check_leaf, Column::merkle_check_leaf_index, Column::merkle_check_remaining_path_len, Column::merkle_check_sel, Column::merkle_check_start, Column::merkle_check_tree_height, Column::poseidon2_hash_a_0, Column::poseidon2_hash_a_1, Column::poseidon2_hash_a_2, Column::poseidon2_hash_a_3, Column::poseidon2_hash_input_0, Column::poseidon2_hash_input_1, Column::poseidon2_hash_input_2, Column::poseidon2_hash_num_perm_rounds_rem, Column::poseidon2_hash_output, Column::poseidon2_hash_sel, Column::poseidon2_hash_start, Column::scalar_mul_bit_idx, Column::scalar_mul_point_inf, Column::scalar_mul_point_x, Column::scalar_mul_point_y, Column::scalar_mul_res_inf, Column::scalar_mul_res_x, Column::scalar_mul_res_y, Column::scalar_mul_scalar, Column::scalar_mul_sel, Column::scalar_mul_start, Column::scalar_mul_temp_inf, Column::scalar_mul_temp_x, Column::scalar_mul_temp_y, Column::sha256_a, Column::sha256_b, Column::sha256_c, Column::sha256_d, Column::sha256_e, Column::sha256_f, Column::sha256_g, Column::sha256_h, Column::sha256_helper_w0, Column::sha256_helper_w1, Column::sha256_helper_w10, Column::sha256_helper_w11, Column::sha256_helper_w12, Column::sha256_helper_w13, Column::sha256_helper_w14, Column::sha256_helper_w15, Column::sha256_helper_w2, Column::sha256_helper_w3, Column::sha256_helper_w4, Column::sha256_helper_w5, Column::sha256_helper_w6, Column::sha256_helper_w7, Column::sha256_helper_w8, Column::sha256_helper_w9, Column::sha256_rounds_remaining, Column::sha256_sel, Column::sha256_start, Column::to_radix_acc, Column::to_radix_acc_under_p, Column::to_radix_exponent, Column::to_radix_limb, Column::to_radix_limb_eq_p, Column::to_radix_limb_index, Column::to_radix_limb_lt_p, Column::to_radix_not_padding_limb, Column::to_radix_radix, Column::to_radix_safe_limbs, Column::to_radix_sel, Column::to_radix_start, Column::to_radix_value -#define AVM2_SHIFTED_COLUMNS ColumnAndShifts::bc_decomposition_bytes_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_1_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_10_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_11_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_12_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_13_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_14_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_15_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_16_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_17_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_18_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_19_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_2_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_20_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_21_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_22_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_23_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_24_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_25_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_26_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_27_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_28_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_29_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_3_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_30_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_31_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_32_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_33_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_34_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_35_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_4_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_5_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_6_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_7_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_8_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_9_shift, ColumnAndShifts::bc_decomposition_bytes_remaining_shift, ColumnAndShifts::bc_decomposition_id_shift, ColumnAndShifts::bc_decomposition_pc_shift, ColumnAndShifts::bc_decomposition_sel_shift, ColumnAndShifts::bc_hashing_bytecode_id_shift, ColumnAndShifts::bc_hashing_incremental_hash_shift, ColumnAndShifts::bc_hashing_pc_index_shift, ColumnAndShifts::bc_hashing_sel_shift, ColumnAndShifts::bc_hashing_start_shift, ColumnAndShifts::bitwise_acc_ia_shift, ColumnAndShifts::bitwise_acc_ib_shift, ColumnAndShifts::bitwise_acc_ic_shift, ColumnAndShifts::bitwise_ctr_shift, ColumnAndShifts::bitwise_op_id_shift, ColumnAndShifts::execution_sel_shift, ColumnAndShifts::ff_gt_a_hi_shift, ColumnAndShifts::ff_gt_a_lo_shift, ColumnAndShifts::ff_gt_b_hi_shift, ColumnAndShifts::ff_gt_b_lo_shift, ColumnAndShifts::ff_gt_cmp_rng_ctr_shift, ColumnAndShifts::ff_gt_p_sub_a_hi_shift, ColumnAndShifts::ff_gt_p_sub_a_lo_shift, ColumnAndShifts::ff_gt_p_sub_b_hi_shift, ColumnAndShifts::ff_gt_p_sub_b_lo_shift, ColumnAndShifts::ff_gt_sel_shift, ColumnAndShifts::ff_gt_sel_gt_shift, ColumnAndShifts::merkle_check_current_index_in_layer_shift, ColumnAndShifts::merkle_check_current_node_shift, ColumnAndShifts::merkle_check_leaf_shift, ColumnAndShifts::merkle_check_leaf_index_shift, ColumnAndShifts::merkle_check_remaining_path_len_shift, ColumnAndShifts::merkle_check_sel_shift, ColumnAndShifts::merkle_check_start_shift, ColumnAndShifts::merkle_check_tree_height_shift, ColumnAndShifts::poseidon2_hash_a_0_shift, ColumnAndShifts::poseidon2_hash_a_1_shift, ColumnAndShifts::poseidon2_hash_a_2_shift, ColumnAndShifts::poseidon2_hash_a_3_shift, ColumnAndShifts::poseidon2_hash_input_0_shift, ColumnAndShifts::poseidon2_hash_input_1_shift, ColumnAndShifts::poseidon2_hash_input_2_shift, ColumnAndShifts::poseidon2_hash_num_perm_rounds_rem_shift, ColumnAndShifts::poseidon2_hash_output_shift, ColumnAndShifts::poseidon2_hash_sel_shift, ColumnAndShifts::poseidon2_hash_start_shift, ColumnAndShifts::scalar_mul_bit_idx_shift, ColumnAndShifts::scalar_mul_point_inf_shift, ColumnAndShifts::scalar_mul_point_x_shift, ColumnAndShifts::scalar_mul_point_y_shift, ColumnAndShifts::scalar_mul_res_inf_shift, ColumnAndShifts::scalar_mul_res_x_shift, ColumnAndShifts::scalar_mul_res_y_shift, ColumnAndShifts::scalar_mul_scalar_shift, ColumnAndShifts::scalar_mul_sel_shift, ColumnAndShifts::scalar_mul_start_shift, ColumnAndShifts::scalar_mul_temp_inf_shift, ColumnAndShifts::scalar_mul_temp_x_shift, ColumnAndShifts::scalar_mul_temp_y_shift, ColumnAndShifts::sha256_a_shift, ColumnAndShifts::sha256_b_shift, ColumnAndShifts::sha256_c_shift, ColumnAndShifts::sha256_d_shift, ColumnAndShifts::sha256_e_shift, ColumnAndShifts::sha256_f_shift, ColumnAndShifts::sha256_g_shift, ColumnAndShifts::sha256_h_shift, ColumnAndShifts::sha256_helper_w0_shift, ColumnAndShifts::sha256_helper_w1_shift, ColumnAndShifts::sha256_helper_w10_shift, ColumnAndShifts::sha256_helper_w11_shift, ColumnAndShifts::sha256_helper_w12_shift, ColumnAndShifts::sha256_helper_w13_shift, ColumnAndShifts::sha256_helper_w14_shift, ColumnAndShifts::sha256_helper_w15_shift, ColumnAndShifts::sha256_helper_w2_shift, ColumnAndShifts::sha256_helper_w3_shift, ColumnAndShifts::sha256_helper_w4_shift, ColumnAndShifts::sha256_helper_w5_shift, ColumnAndShifts::sha256_helper_w6_shift, ColumnAndShifts::sha256_helper_w7_shift, ColumnAndShifts::sha256_helper_w8_shift, ColumnAndShifts::sha256_helper_w9_shift, ColumnAndShifts::sha256_rounds_remaining_shift, ColumnAndShifts::sha256_sel_shift, ColumnAndShifts::sha256_start_shift, ColumnAndShifts::to_radix_acc_shift, ColumnAndShifts::to_radix_acc_under_p_shift, ColumnAndShifts::to_radix_exponent_shift, ColumnAndShifts::to_radix_limb_shift, ColumnAndShifts::to_radix_limb_eq_p_shift, ColumnAndShifts::to_radix_limb_index_shift, ColumnAndShifts::to_radix_limb_lt_p_shift, ColumnAndShifts::to_radix_not_padding_limb_shift, ColumnAndShifts::to_radix_radix_shift, ColumnAndShifts::to_radix_safe_limbs_shift, ColumnAndShifts::to_radix_sel_shift, ColumnAndShifts::to_radix_start_shift, ColumnAndShifts::to_radix_value_shift +#define AVM2_TO_BE_SHIFTED_COLUMNS Column::bc_decomposition_bytes, Column::bc_decomposition_bytes_pc_plus_1, Column::bc_decomposition_bytes_pc_plus_10, Column::bc_decomposition_bytes_pc_plus_11, Column::bc_decomposition_bytes_pc_plus_12, Column::bc_decomposition_bytes_pc_plus_13, Column::bc_decomposition_bytes_pc_plus_14, Column::bc_decomposition_bytes_pc_plus_15, Column::bc_decomposition_bytes_pc_plus_16, Column::bc_decomposition_bytes_pc_plus_17, Column::bc_decomposition_bytes_pc_plus_18, Column::bc_decomposition_bytes_pc_plus_19, Column::bc_decomposition_bytes_pc_plus_2, Column::bc_decomposition_bytes_pc_plus_20, Column::bc_decomposition_bytes_pc_plus_21, Column::bc_decomposition_bytes_pc_plus_22, Column::bc_decomposition_bytes_pc_plus_23, Column::bc_decomposition_bytes_pc_plus_24, Column::bc_decomposition_bytes_pc_plus_25, Column::bc_decomposition_bytes_pc_plus_26, Column::bc_decomposition_bytes_pc_plus_27, Column::bc_decomposition_bytes_pc_plus_28, Column::bc_decomposition_bytes_pc_plus_29, Column::bc_decomposition_bytes_pc_plus_3, Column::bc_decomposition_bytes_pc_plus_30, Column::bc_decomposition_bytes_pc_plus_31, Column::bc_decomposition_bytes_pc_plus_32, Column::bc_decomposition_bytes_pc_plus_33, Column::bc_decomposition_bytes_pc_plus_34, Column::bc_decomposition_bytes_pc_plus_35, Column::bc_decomposition_bytes_pc_plus_4, Column::bc_decomposition_bytes_pc_plus_5, Column::bc_decomposition_bytes_pc_plus_6, Column::bc_decomposition_bytes_pc_plus_7, Column::bc_decomposition_bytes_pc_plus_8, Column::bc_decomposition_bytes_pc_plus_9, Column::bc_decomposition_bytes_remaining, Column::bc_decomposition_id, Column::bc_decomposition_pc, Column::bc_decomposition_sel, Column::bc_hashing_bytecode_id, Column::bc_hashing_incremental_hash, Column::bc_hashing_pc_index, Column::bc_hashing_sel, Column::bc_hashing_start, Column::bitwise_acc_ia, Column::bitwise_acc_ib, Column::bitwise_acc_ic, Column::bitwise_ctr, Column::bitwise_op_id, Column::execution_sel, Column::ff_gt_a_hi, Column::ff_gt_a_lo, Column::ff_gt_b_hi, Column::ff_gt_b_lo, Column::ff_gt_cmp_rng_ctr, Column::ff_gt_p_sub_a_hi, Column::ff_gt_p_sub_a_lo, Column::ff_gt_p_sub_b_hi, Column::ff_gt_p_sub_b_lo, Column::ff_gt_sel, Column::ff_gt_sel_gt, Column::merkle_check_index, Column::merkle_check_path_len, Column::merkle_check_read_node, Column::merkle_check_read_root, Column::merkle_check_sel, Column::merkle_check_start, Column::merkle_check_write, Column::merkle_check_write_node, Column::merkle_check_write_root, Column::poseidon2_hash_a_0, Column::poseidon2_hash_a_1, Column::poseidon2_hash_a_2, Column::poseidon2_hash_a_3, Column::poseidon2_hash_input_0, Column::poseidon2_hash_input_1, Column::poseidon2_hash_input_2, Column::poseidon2_hash_num_perm_rounds_rem, Column::poseidon2_hash_output, Column::poseidon2_hash_sel, Column::poseidon2_hash_start, Column::scalar_mul_bit_idx, Column::scalar_mul_point_inf, Column::scalar_mul_point_x, Column::scalar_mul_point_y, Column::scalar_mul_res_inf, Column::scalar_mul_res_x, Column::scalar_mul_res_y, Column::scalar_mul_scalar, Column::scalar_mul_sel, Column::scalar_mul_start, Column::scalar_mul_temp_inf, Column::scalar_mul_temp_x, Column::scalar_mul_temp_y, Column::sha256_a, Column::sha256_b, Column::sha256_c, Column::sha256_d, Column::sha256_e, Column::sha256_f, Column::sha256_g, Column::sha256_h, Column::sha256_helper_w0, Column::sha256_helper_w1, Column::sha256_helper_w10, Column::sha256_helper_w11, Column::sha256_helper_w12, Column::sha256_helper_w13, Column::sha256_helper_w14, Column::sha256_helper_w15, Column::sha256_helper_w2, Column::sha256_helper_w3, Column::sha256_helper_w4, Column::sha256_helper_w5, Column::sha256_helper_w6, Column::sha256_helper_w7, Column::sha256_helper_w8, Column::sha256_helper_w9, Column::sha256_rounds_remaining, Column::sha256_sel, Column::sha256_start, Column::to_radix_acc, Column::to_radix_acc_under_p, Column::to_radix_exponent, Column::to_radix_limb, Column::to_radix_limb_eq_p, Column::to_radix_limb_index, Column::to_radix_limb_lt_p, Column::to_radix_not_padding_limb, Column::to_radix_radix, Column::to_radix_safe_limbs, Column::to_radix_sel, Column::to_radix_start, Column::to_radix_value +#define AVM2_SHIFTED_COLUMNS ColumnAndShifts::bc_decomposition_bytes_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_1_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_10_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_11_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_12_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_13_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_14_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_15_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_16_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_17_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_18_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_19_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_2_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_20_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_21_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_22_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_23_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_24_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_25_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_26_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_27_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_28_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_29_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_3_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_30_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_31_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_32_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_33_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_34_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_35_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_4_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_5_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_6_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_7_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_8_shift, ColumnAndShifts::bc_decomposition_bytes_pc_plus_9_shift, ColumnAndShifts::bc_decomposition_bytes_remaining_shift, ColumnAndShifts::bc_decomposition_id_shift, ColumnAndShifts::bc_decomposition_pc_shift, ColumnAndShifts::bc_decomposition_sel_shift, ColumnAndShifts::bc_hashing_bytecode_id_shift, ColumnAndShifts::bc_hashing_incremental_hash_shift, ColumnAndShifts::bc_hashing_pc_index_shift, ColumnAndShifts::bc_hashing_sel_shift, ColumnAndShifts::bc_hashing_start_shift, ColumnAndShifts::bitwise_acc_ia_shift, ColumnAndShifts::bitwise_acc_ib_shift, ColumnAndShifts::bitwise_acc_ic_shift, ColumnAndShifts::bitwise_ctr_shift, ColumnAndShifts::bitwise_op_id_shift, ColumnAndShifts::execution_sel_shift, ColumnAndShifts::ff_gt_a_hi_shift, ColumnAndShifts::ff_gt_a_lo_shift, ColumnAndShifts::ff_gt_b_hi_shift, ColumnAndShifts::ff_gt_b_lo_shift, ColumnAndShifts::ff_gt_cmp_rng_ctr_shift, ColumnAndShifts::ff_gt_p_sub_a_hi_shift, ColumnAndShifts::ff_gt_p_sub_a_lo_shift, ColumnAndShifts::ff_gt_p_sub_b_hi_shift, ColumnAndShifts::ff_gt_p_sub_b_lo_shift, ColumnAndShifts::ff_gt_sel_shift, ColumnAndShifts::ff_gt_sel_gt_shift, ColumnAndShifts::merkle_check_index_shift, ColumnAndShifts::merkle_check_path_len_shift, ColumnAndShifts::merkle_check_read_node_shift, ColumnAndShifts::merkle_check_read_root_shift, ColumnAndShifts::merkle_check_sel_shift, ColumnAndShifts::merkle_check_start_shift, ColumnAndShifts::merkle_check_write_shift, ColumnAndShifts::merkle_check_write_node_shift, ColumnAndShifts::merkle_check_write_root_shift, ColumnAndShifts::poseidon2_hash_a_0_shift, ColumnAndShifts::poseidon2_hash_a_1_shift, ColumnAndShifts::poseidon2_hash_a_2_shift, ColumnAndShifts::poseidon2_hash_a_3_shift, ColumnAndShifts::poseidon2_hash_input_0_shift, ColumnAndShifts::poseidon2_hash_input_1_shift, ColumnAndShifts::poseidon2_hash_input_2_shift, ColumnAndShifts::poseidon2_hash_num_perm_rounds_rem_shift, ColumnAndShifts::poseidon2_hash_output_shift, ColumnAndShifts::poseidon2_hash_sel_shift, ColumnAndShifts::poseidon2_hash_start_shift, ColumnAndShifts::scalar_mul_bit_idx_shift, ColumnAndShifts::scalar_mul_point_inf_shift, ColumnAndShifts::scalar_mul_point_x_shift, ColumnAndShifts::scalar_mul_point_y_shift, ColumnAndShifts::scalar_mul_res_inf_shift, ColumnAndShifts::scalar_mul_res_x_shift, ColumnAndShifts::scalar_mul_res_y_shift, ColumnAndShifts::scalar_mul_scalar_shift, ColumnAndShifts::scalar_mul_sel_shift, ColumnAndShifts::scalar_mul_start_shift, ColumnAndShifts::scalar_mul_temp_inf_shift, ColumnAndShifts::scalar_mul_temp_x_shift, ColumnAndShifts::scalar_mul_temp_y_shift, ColumnAndShifts::sha256_a_shift, ColumnAndShifts::sha256_b_shift, ColumnAndShifts::sha256_c_shift, ColumnAndShifts::sha256_d_shift, ColumnAndShifts::sha256_e_shift, ColumnAndShifts::sha256_f_shift, ColumnAndShifts::sha256_g_shift, ColumnAndShifts::sha256_h_shift, ColumnAndShifts::sha256_helper_w0_shift, ColumnAndShifts::sha256_helper_w1_shift, ColumnAndShifts::sha256_helper_w10_shift, ColumnAndShifts::sha256_helper_w11_shift, ColumnAndShifts::sha256_helper_w12_shift, ColumnAndShifts::sha256_helper_w13_shift, ColumnAndShifts::sha256_helper_w14_shift, ColumnAndShifts::sha256_helper_w15_shift, ColumnAndShifts::sha256_helper_w2_shift, ColumnAndShifts::sha256_helper_w3_shift, ColumnAndShifts::sha256_helper_w4_shift, ColumnAndShifts::sha256_helper_w5_shift, ColumnAndShifts::sha256_helper_w6_shift, ColumnAndShifts::sha256_helper_w7_shift, ColumnAndShifts::sha256_helper_w8_shift, ColumnAndShifts::sha256_helper_w9_shift, ColumnAndShifts::sha256_rounds_remaining_shift, ColumnAndShifts::sha256_sel_shift, ColumnAndShifts::sha256_start_shift, ColumnAndShifts::to_radix_acc_shift, ColumnAndShifts::to_radix_acc_under_p_shift, ColumnAndShifts::to_radix_exponent_shift, ColumnAndShifts::to_radix_limb_shift, ColumnAndShifts::to_radix_limb_eq_p_shift, ColumnAndShifts::to_radix_limb_index_shift, ColumnAndShifts::to_radix_limb_lt_p_shift, ColumnAndShifts::to_radix_not_padding_limb_shift, ColumnAndShifts::to_radix_radix_shift, ColumnAndShifts::to_radix_safe_limbs_shift, ColumnAndShifts::to_radix_sel_shift, ColumnAndShifts::to_radix_start_shift, ColumnAndShifts::to_radix_value_shift // clang-format on // All columns minus shifts. @@ -31,8 +31,8 @@ enum class ColumnAndShifts { SENTINEL_DO_NOT_USE, }; -constexpr auto NUM_COLUMNS_WITH_SHIFTS = 1117; -constexpr auto NUM_COLUMNS_WITHOUT_SHIFTS = 983; +constexpr auto NUM_COLUMNS_WITH_SHIFTS = 1124; +constexpr auto NUM_COLUMNS_WITHOUT_SHIFTS = 989; constexpr auto TO_BE_SHIFTED_COLUMNS_ARRAY = []() { return std::array{ AVM2_TO_BE_SHIFTED_COLUMNS }; }(); constexpr auto SHIFTED_COLUMNS_ARRAY = []() { return std::array{ AVM2_SHIFTED_COLUMNS }; }(); static_assert(TO_BE_SHIFTED_COLUMNS_ARRAY.size() == SHIFTED_COLUMNS_ARRAY.size()); diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp index 1f6a84fae3c4..a9000e6b59f4 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/flavor.hpp @@ -96,12 +96,12 @@ class AvmFlavor { static constexpr bool HasZK = false; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 47; - static constexpr size_t NUM_WITNESS_ENTITIES = 936; - static constexpr size_t NUM_SHIFTED_ENTITIES = 134; + static constexpr size_t NUM_WITNESS_ENTITIES = 942; + static constexpr size_t NUM_SHIFTED_ENTITIES = 135; static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES; // We have two copies of the witness entities, so we subtract the number of fixed ones (they have no shift), one for // the unshifted and one for the shifted - static constexpr size_t NUM_ALL_ENTITIES = 1117; + static constexpr size_t NUM_ALL_ENTITIES = 1124; // In the sumcheck univariate computation, we divide the trace in chunks and each chunk is // evenly processed by all the threads. This constant defines the maximum number of rows @@ -175,7 +175,8 @@ class AvmFlavor { lookup_instr_fetching_pc_abs_diff_positive_relation, lookup_instr_fetching_tag_value_validation_relation, lookup_instr_fetching_wire_instruction_info_relation, - lookup_merkle_check_merkle_poseidon2_relation, + lookup_merkle_check_merkle_poseidon2_read_relation, + lookup_merkle_check_merkle_poseidon2_write_relation, lookup_poseidon2_hash_poseidon2_perm_relation, lookup_range_check_dyn_diff_is_u16_relation, lookup_range_check_dyn_rng_chk_pow_2_relation, diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_merkle_check.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_merkle_check.hpp index 9488ae0a509a..26122bacb9bb 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_merkle_check.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/lookups_merkle_check.hpp @@ -10,11 +10,11 @@ namespace bb::avm2 { -/////////////////// lookup_merkle_check_merkle_poseidon2 /////////////////// +/////////////////// lookup_merkle_check_merkle_poseidon2_read /////////////////// -class lookup_merkle_check_merkle_poseidon2_settings { +class lookup_merkle_check_merkle_poseidon2_read_settings { public: - static constexpr std::string_view NAME = "LOOKUP_MERKLE_CHECK_MERKLE_POSEIDON2"; + static constexpr std::string_view NAME = "LOOKUP_MERKLE_CHECK_MERKLE_POSEIDON2_READ"; static constexpr std::string_view RELATION_NAME = "merkle_check"; static constexpr size_t READ_TERMS = 1; @@ -29,14 +29,14 @@ class lookup_merkle_check_merkle_poseidon2_settings { // Columns using the Column enum. static constexpr Column SRC_SELECTOR = Column::merkle_check_sel; static constexpr Column DST_SELECTOR = Column::poseidon2_hash_end; - static constexpr Column COUNTS = Column::lookup_merkle_check_merkle_poseidon2_counts; - static constexpr Column INVERSES = Column::lookup_merkle_check_merkle_poseidon2_inv; + static constexpr Column COUNTS = Column::lookup_merkle_check_merkle_poseidon2_read_counts; + static constexpr Column INVERSES = Column::lookup_merkle_check_merkle_poseidon2_read_inv; static constexpr std::array SRC_COLUMNS = { - ColumnAndShifts::merkle_check_left_node, - ColumnAndShifts::merkle_check_right_node, + ColumnAndShifts::merkle_check_read_left_node, + ColumnAndShifts::merkle_check_read_right_node, ColumnAndShifts::precomputed_zero, ColumnAndShifts::merkle_check_constant_2, - ColumnAndShifts::merkle_check_output_hash + ColumnAndShifts::merkle_check_read_output_hash }; static constexpr std::array DST_COLUMNS = { ColumnAndShifts::poseidon2_hash_input_0, @@ -72,15 +72,15 @@ class lookup_merkle_check_merkle_poseidon2_settings { template static inline auto get_entities(AllEntities&& in) { - return std::forward_as_tuple(in._lookup_merkle_check_merkle_poseidon2_inv(), - in._lookup_merkle_check_merkle_poseidon2_counts(), + return std::forward_as_tuple(in._lookup_merkle_check_merkle_poseidon2_read_inv(), + in._lookup_merkle_check_merkle_poseidon2_read_counts(), in._merkle_check_sel(), in._poseidon2_hash_end(), - in._merkle_check_left_node(), - in._merkle_check_right_node(), + in._merkle_check_read_left_node(), + in._merkle_check_read_right_node(), in._precomputed_zero(), in._merkle_check_constant_2(), - in._merkle_check_output_hash(), + in._merkle_check_read_output_hash(), in._poseidon2_hash_input_0(), in._poseidon2_hash_input_1(), in._poseidon2_hash_input_2(), @@ -90,16 +90,120 @@ class lookup_merkle_check_merkle_poseidon2_settings { }; template -class lookup_merkle_check_merkle_poseidon2_relation - : public GenericLookupRelation { +class lookup_merkle_check_merkle_poseidon2_read_relation + : public GenericLookupRelation { public: - using Settings = lookup_merkle_check_merkle_poseidon2_settings; - static constexpr std::string_view NAME = lookup_merkle_check_merkle_poseidon2_settings::NAME; - static constexpr std::string_view RELATION_NAME = lookup_merkle_check_merkle_poseidon2_settings::RELATION_NAME; + using Settings = lookup_merkle_check_merkle_poseidon2_read_settings; + static constexpr std::string_view NAME = lookup_merkle_check_merkle_poseidon2_read_settings::NAME; + static constexpr std::string_view RELATION_NAME = lookup_merkle_check_merkle_poseidon2_read_settings::RELATION_NAME; template inline static bool skip(const AllEntities& in) { - return in.lookup_merkle_check_merkle_poseidon2_inv.is_zero(); + return in.lookup_merkle_check_merkle_poseidon2_read_inv.is_zero(); + } + + static std::string get_subrelation_label(size_t index) + { + if (index == 0) { + return "INVERSES_ARE_CORRECT"; + } else if (index == 1) { + return "ACCUMULATION_IS_CORRECT"; + } + return std::to_string(index); + } +}; + +/////////////////// lookup_merkle_check_merkle_poseidon2_write /////////////////// + +class lookup_merkle_check_merkle_poseidon2_write_settings { + public: + static constexpr std::string_view NAME = "LOOKUP_MERKLE_CHECK_MERKLE_POSEIDON2_WRITE"; + static constexpr std::string_view RELATION_NAME = "merkle_check"; + + static constexpr size_t READ_TERMS = 1; + static constexpr size_t WRITE_TERMS = 1; + static constexpr size_t READ_TERM_TYPES[READ_TERMS] = { 0 }; + static constexpr size_t WRITE_TERM_TYPES[WRITE_TERMS] = { 0 }; + static constexpr size_t LOOKUP_TUPLE_SIZE = 5; + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 4; + static constexpr size_t READ_TERM_DEGREE = 0; + static constexpr size_t WRITE_TERM_DEGREE = 0; + + // Columns using the Column enum. + static constexpr Column SRC_SELECTOR = Column::merkle_check_write; + static constexpr Column DST_SELECTOR = Column::poseidon2_hash_end; + static constexpr Column COUNTS = Column::lookup_merkle_check_merkle_poseidon2_write_counts; + static constexpr Column INVERSES = Column::lookup_merkle_check_merkle_poseidon2_write_inv; + static constexpr std::array SRC_COLUMNS = { + ColumnAndShifts::merkle_check_write_left_node, + ColumnAndShifts::merkle_check_write_right_node, + ColumnAndShifts::precomputed_zero, + ColumnAndShifts::merkle_check_constant_2, + ColumnAndShifts::merkle_check_write_output_hash + }; + static constexpr std::array DST_COLUMNS = { + ColumnAndShifts::poseidon2_hash_input_0, + ColumnAndShifts::poseidon2_hash_input_1, + ColumnAndShifts::poseidon2_hash_input_2, + ColumnAndShifts::poseidon2_hash_input_len, + ColumnAndShifts::poseidon2_hash_output + }; + + template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in._merkle_check_write() == 1 || in._poseidon2_hash_end() == 1); + } + + template + static inline auto compute_inverse_exists(const AllEntities& in) + { + using View = typename Accumulator::View; + const auto is_operation = View(in._merkle_check_write()); + const auto is_table_entry = View(in._poseidon2_hash_end()); + return (is_operation + is_table_entry - is_operation * is_table_entry); + } + + template static inline auto get_const_entities(const AllEntities& in) + { + return get_entities(in); + } + + template static inline auto get_nonconst_entities(AllEntities& in) + { + return get_entities(in); + } + + template static inline auto get_entities(AllEntities&& in) + { + return std::forward_as_tuple(in._lookup_merkle_check_merkle_poseidon2_write_inv(), + in._lookup_merkle_check_merkle_poseidon2_write_counts(), + in._merkle_check_write(), + in._poseidon2_hash_end(), + in._merkle_check_write_left_node(), + in._merkle_check_write_right_node(), + in._precomputed_zero(), + in._merkle_check_constant_2(), + in._merkle_check_write_output_hash(), + in._poseidon2_hash_input_0(), + in._poseidon2_hash_input_1(), + in._poseidon2_hash_input_2(), + in._poseidon2_hash_input_len(), + in._poseidon2_hash_output()); + } +}; + +template +class lookup_merkle_check_merkle_poseidon2_write_relation + : public GenericLookupRelation { + public: + using Settings = lookup_merkle_check_merkle_poseidon2_write_settings; + static constexpr std::string_view NAME = lookup_merkle_check_merkle_poseidon2_write_settings::NAME; + static constexpr std::string_view RELATION_NAME = + lookup_merkle_check_merkle_poseidon2_write_settings::RELATION_NAME; + + template inline static bool skip(const AllEntities& in) + { + return in.lookup_merkle_check_merkle_poseidon2_write_inv.is_zero(); } static std::string get_subrelation_label(size_t index) diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/merkle_check.hpp b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/merkle_check.hpp index db91838ec3c2..3041f665a2d2 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/relations/merkle_check.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/relations/merkle_check.hpp @@ -12,8 +12,8 @@ template class merkle_checkImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, - 4, 4, 4, 5, 3, 4, 4, 4, 4, 3, 4 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, + 3, 4, 4, 4, 4, 4, 4, 3, 4, 4, 3, 3 }; template inline static bool skip(const AllEntities& in) { @@ -29,6 +29,7 @@ template class merkle_checkImpl { { const auto merkle_check_NOT_END = new_term.merkle_check_sel * (FF(1) - new_term.merkle_check_end); const auto merkle_check_LATCH_CONDITION = new_term.merkle_check_end + new_term.precomputed_first_row; + const auto merkle_check_REMAINING_PATH_LEN = (new_term.merkle_check_path_len - FF(1)); const auto merkle_check_INDEX_IS_ODD = (FF(1) - new_term.merkle_check_index_is_even); { @@ -46,132 +47,134 @@ template class merkle_checkImpl { } { using Accumulator = typename std::tuple_element_t<2, ContainerOverSubrelations>; - auto tmp = new_term.merkle_check_start * (FF(1) - new_term.merkle_check_start); + auto tmp = new_term.merkle_check_write * (FF(1) - new_term.merkle_check_write); tmp *= scaling_factor; std::get<2>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<3, ContainerOverSubrelations>; - auto tmp = new_term.merkle_check_end * (FF(1) - new_term.merkle_check_end); + auto tmp = new_term.merkle_check_start * (FF(1) - new_term.merkle_check_start); tmp *= scaling_factor; std::get<3>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<4, ContainerOverSubrelations>; - auto tmp = new_term.merkle_check_end * new_term.precomputed_first_row; + auto tmp = new_term.merkle_check_end * (FF(1) - new_term.merkle_check_end); tmp *= scaling_factor; std::get<4>(evals) += typename Accumulator::View(tmp); } - { // START_AFTER_LATCH + { using Accumulator = typename std::tuple_element_t<5, ContainerOverSubrelations>; - auto tmp = - new_term.merkle_check_sel_shift * (new_term.merkle_check_start_shift - merkle_check_LATCH_CONDITION); + auto tmp = new_term.merkle_check_end * new_term.precomputed_first_row; tmp *= scaling_factor; std::get<5>(evals) += typename Accumulator::View(tmp); } - { // SELECTOR_ON_END + { // START_AFTER_LATCH using Accumulator = typename std::tuple_element_t<6, ContainerOverSubrelations>; - auto tmp = new_term.merkle_check_end * (FF(1) - new_term.merkle_check_sel); + auto tmp = + new_term.merkle_check_sel_shift * (new_term.merkle_check_start_shift - merkle_check_LATCH_CONDITION); tmp *= scaling_factor; std::get<6>(evals) += typename Accumulator::View(tmp); } - { // INITIALIZE_CURRENT_NODE + { // SELECTOR_ON_END using Accumulator = typename std::tuple_element_t<7, ContainerOverSubrelations>; - auto tmp = new_term.merkle_check_start * (new_term.merkle_check_current_node - new_term.merkle_check_leaf); + auto tmp = new_term.merkle_check_end * (FF(1) - new_term.merkle_check_sel); tmp *= scaling_factor; std::get<7>(evals) += typename Accumulator::View(tmp); } - { // INITIALIZE_CURRENT_INDEX_IN_LAYER + { // PROPAGATE_READ_ROOT using Accumulator = typename std::tuple_element_t<8, ContainerOverSubrelations>; - auto tmp = new_term.merkle_check_start * - (new_term.merkle_check_current_index_in_layer - new_term.merkle_check_leaf_index); + auto tmp = merkle_check_NOT_END * (new_term.merkle_check_read_root_shift - new_term.merkle_check_read_root); tmp *= scaling_factor; std::get<8>(evals) += typename Accumulator::View(tmp); } - { // INITIALIZE_REMAINING_PATH_LEN + { // PROPAGATE_WRITE using Accumulator = typename std::tuple_element_t<9, ContainerOverSubrelations>; - auto tmp = new_term.merkle_check_start * - ((new_term.merkle_check_tree_height - new_term.merkle_check_remaining_path_len) - FF(1)); + auto tmp = merkle_check_NOT_END * (new_term.merkle_check_write_shift - new_term.merkle_check_write); tmp *= scaling_factor; std::get<9>(evals) += typename Accumulator::View(tmp); } - { // PROPAGATE_LEAF + { // PROPAGATE_WRITE_ROOT using Accumulator = typename std::tuple_element_t<10, ContainerOverSubrelations>; - auto tmp = merkle_check_NOT_END * (new_term.merkle_check_leaf_shift - new_term.merkle_check_leaf); + auto tmp = + merkle_check_NOT_END * (new_term.merkle_check_write_root_shift - new_term.merkle_check_write_root); tmp *= scaling_factor; std::get<10>(evals) += typename Accumulator::View(tmp); } - { // PROPAGATE_LEAF_INDEX + { // PATH_LEN_DECREMENTS using Accumulator = typename std::tuple_element_t<11, ContainerOverSubrelations>; - auto tmp = - merkle_check_NOT_END * (new_term.merkle_check_leaf_index_shift - new_term.merkle_check_leaf_index); + auto tmp = merkle_check_NOT_END * + ((new_term.merkle_check_path_len_shift - new_term.merkle_check_path_len) + FF(1)); tmp *= scaling_factor; std::get<11>(evals) += typename Accumulator::View(tmp); } - { // PROPAGATE_TREE_HEIGHT + { // END_WHEN_PATH_EMPTY using Accumulator = typename std::tuple_element_t<12, ContainerOverSubrelations>; - auto tmp = - merkle_check_NOT_END * (new_term.merkle_check_tree_height_shift - new_term.merkle_check_tree_height); + auto tmp = new_term.merkle_check_sel * + ((merkle_check_REMAINING_PATH_LEN * + (new_term.merkle_check_end * (FF(1) - new_term.merkle_check_remaining_path_len_inv) + + new_term.merkle_check_remaining_path_len_inv) - + FF(1)) + + new_term.merkle_check_end); tmp *= scaling_factor; std::get<12>(evals) += typename Accumulator::View(tmp); } - { // PATH_LEN_DECREMENTS + { using Accumulator = typename std::tuple_element_t<13, ContainerOverSubrelations>; - auto tmp = - merkle_check_NOT_END * - ((new_term.merkle_check_remaining_path_len_shift - new_term.merkle_check_remaining_path_len) + FF(1)); + auto tmp = new_term.merkle_check_index_is_even * (FF(1) - new_term.merkle_check_index_is_even); tmp *= scaling_factor; std::get<13>(evals) += typename Accumulator::View(tmp); } - { // END_WHEN_PATH_EMPTY + { // NEXT_INDEX_IS_HALVED using Accumulator = typename std::tuple_element_t<14, ContainerOverSubrelations>; - auto tmp = new_term.merkle_check_sel * - ((new_term.merkle_check_remaining_path_len * - (new_term.merkle_check_end * (FF(1) - new_term.merkle_check_remaining_path_len_inv) + - new_term.merkle_check_remaining_path_len_inv) - - FF(1)) + - new_term.merkle_check_end); + auto tmp = merkle_check_NOT_END * ((new_term.merkle_check_index_shift * FF(2) + merkle_check_INDEX_IS_ODD) - + new_term.merkle_check_index); tmp *= scaling_factor; std::get<14>(evals) += typename Accumulator::View(tmp); } - { + { // FINAL_INDEX_IS_0_OR_1 using Accumulator = typename std::tuple_element_t<15, ContainerOverSubrelations>; - auto tmp = new_term.merkle_check_index_is_even * (FF(1) - new_term.merkle_check_index_is_even); + auto tmp = new_term.merkle_check_end * new_term.merkle_check_index * (FF(1) - new_term.merkle_check_index); tmp *= scaling_factor; std::get<15>(evals) += typename Accumulator::View(tmp); } - { // NEXT_INDEX_IS_HALVED + { // ASSIGN_NODE_LEFT_OR_RIGHT_READ using Accumulator = typename std::tuple_element_t<16, ContainerOverSubrelations>; - auto tmp = merkle_check_NOT_END * - ((new_term.merkle_check_current_index_in_layer_shift * FF(2) + merkle_check_INDEX_IS_ODD) - - new_term.merkle_check_current_index_in_layer); + auto tmp = new_term.merkle_check_sel * + ((new_term.merkle_check_index_is_even * + (new_term.merkle_check_read_left_node - new_term.merkle_check_read_right_node) + + new_term.merkle_check_read_right_node) - + new_term.merkle_check_read_node); tmp *= scaling_factor; std::get<16>(evals) += typename Accumulator::View(tmp); } - { // FINAL_INDEX_IS_0_OR_1 + { // ASSIGN_SIBLING_LEFT_OR_RIGHT_READ using Accumulator = typename std::tuple_element_t<17, ContainerOverSubrelations>; - auto tmp = new_term.merkle_check_end * new_term.merkle_check_current_index_in_layer * - (FF(1) - new_term.merkle_check_current_index_in_layer); + auto tmp = new_term.merkle_check_sel * + ((new_term.merkle_check_index_is_even * + (new_term.merkle_check_read_right_node - new_term.merkle_check_read_left_node) + + new_term.merkle_check_read_left_node) - + new_term.merkle_check_sibling); tmp *= scaling_factor; std::get<17>(evals) += typename Accumulator::View(tmp); } - { // ASSIGN_CURRENT_NODE_LEFT_OR_RIGHT + { // ASSIGN_NODE_LEFT_OR_RIGHT_WRITE using Accumulator = typename std::tuple_element_t<18, ContainerOverSubrelations>; - auto tmp = - new_term.merkle_check_sel * ((new_term.merkle_check_index_is_even * - (new_term.merkle_check_left_node - new_term.merkle_check_right_node) + - new_term.merkle_check_right_node) - - new_term.merkle_check_current_node); + auto tmp = new_term.merkle_check_write * + ((new_term.merkle_check_index_is_even * + (new_term.merkle_check_write_left_node - new_term.merkle_check_write_right_node) + + new_term.merkle_check_write_right_node) - + new_term.merkle_check_write_node); tmp *= scaling_factor; std::get<18>(evals) += typename Accumulator::View(tmp); } - { // ASSIGN_SIBLING_LEFT_OR_RIGHT + { // ASSIGN_SIBLING_LEFT_OR_RIGHT_WRITE using Accumulator = typename std::tuple_element_t<19, ContainerOverSubrelations>; - auto tmp = - new_term.merkle_check_sel * ((new_term.merkle_check_index_is_even * - (new_term.merkle_check_right_node - new_term.merkle_check_left_node) + - new_term.merkle_check_left_node) - - new_term.merkle_check_sibling); + auto tmp = new_term.merkle_check_write * + ((new_term.merkle_check_index_is_even * + (new_term.merkle_check_write_right_node - new_term.merkle_check_write_left_node) + + new_term.merkle_check_write_left_node) - + new_term.merkle_check_sibling); tmp *= scaling_factor; std::get<19>(evals) += typename Accumulator::View(tmp); } @@ -181,13 +184,34 @@ template class merkle_checkImpl { tmp *= scaling_factor; std::get<20>(evals) += typename Accumulator::View(tmp); } - { // OUTPUT_HASH_IS_NEXT_ROWS_CURRENT_NODE + { // OUTPUT_HASH_IS_NEXT_ROWS_READ_NODE using Accumulator = typename std::tuple_element_t<21, ContainerOverSubrelations>; auto tmp = - merkle_check_NOT_END * (new_term.merkle_check_current_node_shift - new_term.merkle_check_output_hash); + merkle_check_NOT_END * (new_term.merkle_check_read_node_shift - new_term.merkle_check_read_output_hash); tmp *= scaling_factor; std::get<21>(evals) += typename Accumulator::View(tmp); } + { // OUTPUT_HASH_IS_NEXT_ROWS_WRITE_NODE + using Accumulator = typename std::tuple_element_t<22, ContainerOverSubrelations>; + auto tmp = merkle_check_NOT_END * + (new_term.merkle_check_write_node_shift - new_term.merkle_check_write_output_hash); + tmp *= scaling_factor; + std::get<22>(evals) += typename Accumulator::View(tmp); + } + { // READ_OUTPUT_HASH_IS_READ_ROOT + using Accumulator = typename std::tuple_element_t<23, ContainerOverSubrelations>; + auto tmp = + new_term.merkle_check_end * (new_term.merkle_check_read_output_hash - new_term.merkle_check_read_root); + tmp *= scaling_factor; + std::get<23>(evals) += typename Accumulator::View(tmp); + } + { // WRITE_OUTPUT_HASH_IS_WRITE_ROOT + using Accumulator = typename std::tuple_element_t<24, ContainerOverSubrelations>; + auto tmp = new_term.merkle_check_end * + (new_term.merkle_check_write_output_hash - new_term.merkle_check_write_root); + tmp *= scaling_factor; + std::get<24>(evals) += typename Accumulator::View(tmp); + } } }; @@ -200,57 +224,63 @@ template class merkle_check : public Relation switch (index) { case 1: return "TRACE_CONTINUITY"; - case 5: - return "START_AFTER_LATCH"; case 6: - return "SELECTOR_ON_END"; + return "START_AFTER_LATCH"; case 7: - return "INITIALIZE_CURRENT_NODE"; + return "SELECTOR_ON_END"; case 8: - return "INITIALIZE_CURRENT_INDEX_IN_LAYER"; + return "PROPAGATE_READ_ROOT"; case 9: - return "INITIALIZE_REMAINING_PATH_LEN"; + return "PROPAGATE_WRITE"; case 10: - return "PROPAGATE_LEAF"; + return "PROPAGATE_WRITE_ROOT"; case 11: - return "PROPAGATE_LEAF_INDEX"; - case 12: - return "PROPAGATE_TREE_HEIGHT"; - case 13: return "PATH_LEN_DECREMENTS"; - case 14: + case 12: return "END_WHEN_PATH_EMPTY"; - case 16: + case 14: return "NEXT_INDEX_IS_HALVED"; - case 17: + case 15: return "FINAL_INDEX_IS_0_OR_1"; + case 16: + return "ASSIGN_NODE_LEFT_OR_RIGHT_READ"; + case 17: + return "ASSIGN_SIBLING_LEFT_OR_RIGHT_READ"; case 18: - return "ASSIGN_CURRENT_NODE_LEFT_OR_RIGHT"; + return "ASSIGN_NODE_LEFT_OR_RIGHT_WRITE"; case 19: - return "ASSIGN_SIBLING_LEFT_OR_RIGHT"; + return "ASSIGN_SIBLING_LEFT_OR_RIGHT_WRITE"; case 21: - return "OUTPUT_HASH_IS_NEXT_ROWS_CURRENT_NODE"; + return "OUTPUT_HASH_IS_NEXT_ROWS_READ_NODE"; + case 22: + return "OUTPUT_HASH_IS_NEXT_ROWS_WRITE_NODE"; + case 23: + return "READ_OUTPUT_HASH_IS_READ_ROOT"; + case 24: + return "WRITE_OUTPUT_HASH_IS_WRITE_ROOT"; } return std::to_string(index); } // Subrelation indices constants, to be used in tests. static constexpr size_t SR_TRACE_CONTINUITY = 1; - static constexpr size_t SR_START_AFTER_LATCH = 5; - static constexpr size_t SR_SELECTOR_ON_END = 6; - static constexpr size_t SR_INITIALIZE_CURRENT_NODE = 7; - static constexpr size_t SR_INITIALIZE_CURRENT_INDEX_IN_LAYER = 8; - static constexpr size_t SR_INITIALIZE_REMAINING_PATH_LEN = 9; - static constexpr size_t SR_PROPAGATE_LEAF = 10; - static constexpr size_t SR_PROPAGATE_LEAF_INDEX = 11; - static constexpr size_t SR_PROPAGATE_TREE_HEIGHT = 12; - static constexpr size_t SR_PATH_LEN_DECREMENTS = 13; - static constexpr size_t SR_END_WHEN_PATH_EMPTY = 14; - static constexpr size_t SR_NEXT_INDEX_IS_HALVED = 16; - static constexpr size_t SR_FINAL_INDEX_IS_0_OR_1 = 17; - static constexpr size_t SR_ASSIGN_CURRENT_NODE_LEFT_OR_RIGHT = 18; - static constexpr size_t SR_ASSIGN_SIBLING_LEFT_OR_RIGHT = 19; - static constexpr size_t SR_OUTPUT_HASH_IS_NEXT_ROWS_CURRENT_NODE = 21; + static constexpr size_t SR_START_AFTER_LATCH = 6; + static constexpr size_t SR_SELECTOR_ON_END = 7; + static constexpr size_t SR_PROPAGATE_READ_ROOT = 8; + static constexpr size_t SR_PROPAGATE_WRITE = 9; + static constexpr size_t SR_PROPAGATE_WRITE_ROOT = 10; + static constexpr size_t SR_PATH_LEN_DECREMENTS = 11; + static constexpr size_t SR_END_WHEN_PATH_EMPTY = 12; + static constexpr size_t SR_NEXT_INDEX_IS_HALVED = 14; + static constexpr size_t SR_FINAL_INDEX_IS_0_OR_1 = 15; + static constexpr size_t SR_ASSIGN_NODE_LEFT_OR_RIGHT_READ = 16; + static constexpr size_t SR_ASSIGN_SIBLING_LEFT_OR_RIGHT_READ = 17; + static constexpr size_t SR_ASSIGN_NODE_LEFT_OR_RIGHT_WRITE = 18; + static constexpr size_t SR_ASSIGN_SIBLING_LEFT_OR_RIGHT_WRITE = 19; + static constexpr size_t SR_OUTPUT_HASH_IS_NEXT_ROWS_READ_NODE = 21; + static constexpr size_t SR_OUTPUT_HASH_IS_NEXT_ROWS_WRITE_NODE = 22; + static constexpr size_t SR_READ_OUTPUT_HASH_IS_READ_ROOT = 23; + static constexpr size_t SR_WRITE_OUTPUT_HASH_IS_WRITE_ROOT = 24; }; } // namespace bb::avm2 diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/merkle_check_event.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/merkle_check_event.hpp index 4b491608eb65..8f07348757a3 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/events/merkle_check_event.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/events/merkle_check_event.hpp @@ -9,15 +9,13 @@ namespace bb::avm2::simulation { struct MerkleCheckEvent { FF leaf_value; + std::optional new_leaf_value; uint64_t leaf_index; std::vector sibling_path; FF root; + std::optional new_root; - bool operator==(const MerkleCheckEvent& other) const - { - return leaf_value == other.leaf_value && leaf_index == other.leaf_index && sibling_path == other.sibling_path && - root == other.root; - } + bool operator==(const MerkleCheckEvent& other) const = default; }; } // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/merkle_check.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/merkle_check.cpp index ce7280853db4..8e20614b16ec 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/merkle_check.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/merkle_check.cpp @@ -31,12 +31,63 @@ void MerkleCheck::assert_membership(const FF& leaf_value, } } - assert(curr_index == 0 || curr_index == 1 && "Merkle check's final node index must be 0 or 1"); - assert(curr_value == root && "Merkle membership or non-membership check failed"); + if (curr_index != 0 && curr_index != 1) { + throw std::runtime_error("Merkle check's final node index must be 0 or 1"); + } + if (curr_value != root) { + throw std::runtime_error("Merkle read check failed"); + } std::vector sibling_vec(sibling_path.begin(), sibling_path.end()); events.emit( { .leaf_value = leaf_value, .leaf_index = leaf_index, .sibling_path = std::move(sibling_vec), .root = root }); } +FF MerkleCheck::write(const FF& current_value, + const FF& new_value, + const uint64_t leaf_index, + std::span sibling_path, + const FF& current_root) +{ + // Gadget breaks if tree_height >= 254 + assert(sibling_path.size() <= 254 && "Merkle path length must be less than 254"); + + FF read_value = current_value; + FF write_value = new_value; + uint64_t curr_index = leaf_index; + + for (size_t i = 0; i < sibling_path.size(); ++i) { + const FF sibling = sibling_path[i]; + bool index_is_even = (curr_index % 2 == 0); + + read_value = index_is_even ? poseidon2.hash({ read_value, sibling }) : poseidon2.hash({ sibling, read_value }); + write_value = + index_is_even ? poseidon2.hash({ write_value, sibling }) : poseidon2.hash({ sibling, write_value }); + + // Halve the index (to get the parent index) as we move up the tree> + // Don't halve on the last iteration because after the loop, + // we want curr_index to be the "final" index (0 or 1). + if (i < sibling_path.size() - 1) { + curr_index >>= 1; + } + } + + if (curr_index != 0 && curr_index != 1) { + throw std::runtime_error("Merkle check's final node index must be 0 or 1"); + } + if (read_value != current_root) { + throw std::runtime_error("Merkle read check failed"); + } + + std::vector sibling_vec(sibling_path.begin(), sibling_path.end()); + events.emit({ .leaf_value = current_value, + .new_leaf_value = new_value, + .leaf_index = leaf_index, + .sibling_path = std::move(sibling_vec), + .root = current_root, + .new_root = write_value }); + + return write_value; +} + } // namespace bb::avm2::simulation diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/merkle_check.hpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/merkle_check.hpp index 1bd11405dc99..cb0a23bf7db7 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/merkle_check.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/merkle_check.hpp @@ -21,6 +21,11 @@ class MerkleCheckInterface { const uint64_t leaf_index, std::span sibling_path, const FF& root) = 0; + virtual FF write(const FF& current_value, + const FF& new_value, + const uint64_t leaf_index, + std::span sibling_path, + const FF& current_root) = 0; }; class MerkleCheck : public MerkleCheckInterface { @@ -35,6 +40,12 @@ class MerkleCheck : public MerkleCheckInterface { std::span sibling_path, const FF& root) override; + FF write(const FF& current_value, + const FF& new_value, + const uint64_t leaf_index, + std::span sibling_path, + const FF& current_root) override; + private: EventEmitterInterface& events; Poseidon2Interface& poseidon2; diff --git a/barretenberg/cpp/src/barretenberg/vm2/simulation/merkle_check.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/simulation/merkle_check.test.cpp index cbf5aaf361df..3af6a5c12821 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/simulation/merkle_check.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/simulation/merkle_check.test.cpp @@ -1,9 +1,12 @@ #include #include +#include #include "barretenberg/vm2/simulation/events/event_emitter.hpp" +#include "barretenberg/vm2/simulation/events/merkle_check_event.hpp" #include "barretenberg/vm2/simulation/lib/merkle.hpp" #include "barretenberg/vm2/simulation/merkle_check.hpp" +#include "barretenberg/vm2/testing/macros.hpp" namespace bb::avm2::simulation { namespace { @@ -51,7 +54,39 @@ TEST(MerkleCheckSimulationTest, AssertMembership) EXPECT_EQ(hash_emitter.dump_events().size(), expected_merkle_rows); } -TEST(MerkleCheckSimulationDeathTest, NegativeBadFinalIndex) +TEST(MerkleCheckSimulationTest, Write) +{ + EventEmitter hash_emitter; + EventEmitter perm_emitter; + Poseidon2 poseidon2(hash_emitter, perm_emitter); + + EventEmitter emitter; + MerkleCheck merkle_check(poseidon2, emitter); + + FF current_value = 333; + FF new_value = 334; + uint64_t leaf_index = 30; + std::vector sibling_path = { 10, 2, 30, 4, 50, 6 }; + FF current_root = root_from_path(current_value, leaf_index, sibling_path); + FF expected_new_root = root_from_path(new_value, leaf_index, sibling_path); + + MerkleCheckEvent expect_event = { + .leaf_value = current_value, + .new_leaf_value = new_value, + .leaf_index = leaf_index, + .sibling_path = sibling_path, + .root = current_root, + .new_root = expected_new_root, + }; + + FF new_root = merkle_check.write(current_value, new_value, leaf_index, sibling_path, current_root); + + EXPECT_EQ(new_root, expected_new_root); + EXPECT_THAT(emitter.dump_events(), ElementsAre(expect_event)); + EXPECT_EQ(hash_emitter.dump_events().size(), sibling_path.size() * 2); +} + +TEST(MerkleCheckSimulationTest, NegativeBadFinalIndex) { NoopEventEmitter hash_emitter; NoopEventEmitter perm_emitter; @@ -65,11 +100,13 @@ TEST(MerkleCheckSimulationDeathTest, NegativeBadFinalIndex) std::vector sibling_path = { 10, 2, 30, 4, 50, 6 }; FF root = root_from_path(leaf_value, leaf_index, sibling_path); - EXPECT_DEATH(merkle_check.assert_membership(leaf_value, leaf_index, sibling_path, root), - "Merkle check's final node index must be 0 or 1"); + EXPECT_THROW_WITH_MESSAGE(merkle_check.assert_membership(leaf_value, leaf_index, sibling_path, root), + "Merkle check's final node index must be 0 or 1"); + EXPECT_THROW_WITH_MESSAGE(merkle_check.write(leaf_value, 334, leaf_index, sibling_path, root), + "Merkle check's final node index must be 0 or 1"); } -TEST(MerkleCheckSimulationDeathTest, NegativeWrongRoot) +TEST(MerkleCheckSimulationTest, NegativeWrongRoot) { NoopEventEmitter hash_emitter; NoopEventEmitter perm_emitter; @@ -83,11 +120,13 @@ TEST(MerkleCheckSimulationDeathTest, NegativeWrongRoot) std::vector sibling_path = { 10, 2, 30, 4, 50, 6 }; FF incorrect_root = 66; - EXPECT_DEATH(merkle_check.assert_membership(leaf_value, leaf_index, sibling_path, incorrect_root), - "Merkle membership or non-membership check failed"); + EXPECT_THROW_WITH_MESSAGE(merkle_check.assert_membership(leaf_value, leaf_index, sibling_path, incorrect_root), + "Merkle read check failed"); + EXPECT_THROW_WITH_MESSAGE(merkle_check.write(leaf_value, 334, leaf_index, sibling_path, incorrect_root), + "Merkle read check failed"); } -TEST(MerkleCheckSimulationDeathTest, NegativeWrongLeafIndex) +TEST(MerkleCheckSimulationTest, NegativeWrongLeafIndex) { NoopEventEmitter hash_emitter; NoopEventEmitter perm_emitter; @@ -101,12 +140,13 @@ TEST(MerkleCheckSimulationDeathTest, NegativeWrongLeafIndex) std::vector sibling_path = { 10, 2, 30, 4, 50, 6 }; FF root = root_from_path(leaf_value, leaf_index, sibling_path); uint64_t incorrect_leaf_index = 31; - - EXPECT_DEATH(merkle_check.assert_membership(leaf_value, incorrect_leaf_index, sibling_path, root), - "Merkle membership or non-membership check failed"); + EXPECT_THROW_WITH_MESSAGE(merkle_check.assert_membership(leaf_value, incorrect_leaf_index, sibling_path, root), + "Merkle read check failed"); + EXPECT_THROW_WITH_MESSAGE(merkle_check.write(leaf_value, 334, incorrect_leaf_index, sibling_path, root), + "Merkle read check failed"); } -TEST(MerkleCheckSimulationDeathTest, NegativeWrongSiblingPath) +TEST(MerkleCheckSimulationTest, NegativeWrongSiblingPath) { NoopEventEmitter hash_emitter; NoopEventEmitter perm_emitter; @@ -122,11 +162,13 @@ TEST(MerkleCheckSimulationDeathTest, NegativeWrongSiblingPath) // corrupt the sibling path sibling_path[2] = 11; - EXPECT_DEATH(merkle_check.assert_membership(leaf_value, leaf_index, sibling_path, root), - "Merkle membership or non-membership check failed"); + EXPECT_THROW_WITH_MESSAGE(merkle_check.assert_membership(leaf_value, leaf_index, sibling_path, root), + "Merkle read check failed"); + EXPECT_THROW_WITH_MESSAGE(merkle_check.write(leaf_value, 334, leaf_index, sibling_path, root), + "Merkle read check failed"); } -TEST(MerkleCheckSimulationDeathTest, NegativeWrongLeafValue) +TEST(MerkleCheckSimulationTest, NegativeWrongLeafValue) { NoopEventEmitter hash_emitter; NoopEventEmitter perm_emitter; @@ -141,8 +183,10 @@ TEST(MerkleCheckSimulationDeathTest, NegativeWrongLeafValue) FF root = root_from_path(leaf_value, leaf_index, sibling_path); FF incorrect_leaf_value = 334; - EXPECT_DEATH(merkle_check.assert_membership(incorrect_leaf_value, leaf_index, sibling_path, root), - "Merkle membership or non-membership check failed"); + EXPECT_THROW_WITH_MESSAGE(merkle_check.assert_membership(incorrect_leaf_value, leaf_index, sibling_path, root), + "Merkle read check failed"); + EXPECT_THROW_WITH_MESSAGE(merkle_check.write(incorrect_leaf_value, 334, leaf_index, sibling_path, root), + "Merkle read check failed"); } } // namespace diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/merkle_check_trace.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/merkle_check_trace.cpp index 8e6e8bc4576f..df7a498e5674 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/merkle_check_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/merkle_check_trace.cpp @@ -24,49 +24,68 @@ void MerkleCheckTraceBuilder::process( // For the current level, gather info about the current pair of nodes // being hashed along with the path-length remaining after this level // to complete the merkle check. - FF current_node = event.leaf_value; + + bool write = event.new_leaf_value.has_value(); + assert(write == event.new_root.has_value()); + + FF read_node = event.leaf_value; + FF write_node = event.new_leaf_value.value_or(FF(0)); + + FF root = event.root; + FF new_root = event.new_root.value_or(FF(0)); + uint64_t current_index_in_layer = event.leaf_index; for (size_t i = 0; i < full_path_len; ++i) { const FF sibling = event.sibling_path[i]; - // path-length decrements by 1 for each level until it reaches 0 - const FF remaining_path_len = FF(full_path_len - i - 1); + // path-length decrements by 1 for each level until it reaches 1 + const FF path_len = FF(full_path_len - i); + const FF remaining_path_len = path_len - 1; const FF remaining_path_len_inv = remaining_path_len == 0 ? FF(0) : remaining_path_len.invert(); // end == 1 when the remaining_path_len == 0 const bool end = remaining_path_len == 0; const bool start = i == 0; // First row in the chain is a start row const bool index_is_even = current_index_in_layer % 2 == 0; - const FF left_node = index_is_even ? current_node : sibling; - const FF right_node = index_is_even ? sibling : current_node; - const FF output_hash = Poseidon2::hash({ left_node, right_node }); + const FF read_left_node = index_is_even ? read_node : sibling; + const FF read_right_node = index_is_even ? sibling : read_node; + const FF read_output_hash = Poseidon2::hash({ read_left_node, read_right_node }); + + const FF write_left_node = write ? index_is_even ? write_node : sibling : FF(0); + const FF write_right_node = write ? index_is_even ? sibling : write_node : FF(0); + const FF write_output_hash = write ? Poseidon2::hash({ write_left_node, write_right_node }) : FF(0); trace.set(row, - { { - { C::merkle_check_sel, 1 }, - { C::merkle_check_leaf, event.leaf_value }, - { C::merkle_check_leaf_index, event.leaf_index }, - { C::merkle_check_tree_height, full_path_len }, - { C::merkle_check_current_node, current_node }, - { C::merkle_check_current_index_in_layer, current_index_in_layer }, - { C::merkle_check_remaining_path_len, remaining_path_len }, + { { { C::merkle_check_sel, 1 }, + { C::merkle_check_read_node, read_node }, + { C::merkle_check_write, write }, + { C::merkle_check_write_node, write_node }, + { C::merkle_check_index, current_index_in_layer }, + { C::merkle_check_path_len, path_len }, { C::merkle_check_remaining_path_len_inv, remaining_path_len_inv }, + { C::merkle_check_read_root, root }, + { C::merkle_check_write_root, new_root }, { C::merkle_check_sibling, sibling }, { C::merkle_check_start, start }, { C::merkle_check_end, end }, { C::merkle_check_index_is_even, index_is_even }, - { C::merkle_check_left_node, left_node }, - { C::merkle_check_right_node, right_node }, + { C::merkle_check_read_left_node, read_left_node }, + { C::merkle_check_read_right_node, read_right_node }, + { C::merkle_check_write_left_node, write_left_node }, + { C::merkle_check_write_right_node, write_right_node }, { C::merkle_check_constant_2, 2 }, - { C::merkle_check_output_hash, output_hash }, - } }); + { C::merkle_check_read_output_hash, read_output_hash }, + { C::merkle_check_write_output_hash, write_output_hash } } }); // Update the current/target node value for the next iteration - current_node = output_hash; + read_node = read_output_hash; + write_node = write_output_hash; current_index_in_layer >>= 1; row++; } + assert(read_node == root); + assert(write_node == new_root); } } diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/merkle_check_trace.test.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/merkle_check_trace.test.cpp index de2f5cb32677..0c566df3a573 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/merkle_check_trace.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/merkle_check_trace.test.cpp @@ -5,6 +5,7 @@ #include #include "barretenberg/crypto/poseidon2/poseidon2.hpp" +#include "barretenberg/vm2/common/field.hpp" #include "barretenberg/vm2/generated/flavor_settings.hpp" #include "barretenberg/vm2/generated/full_row.hpp" #include "barretenberg/vm2/tracegen/merkle_check_trace.hpp" @@ -21,22 +22,32 @@ using FF = R::FF; using Poseidon2 = crypto::Poseidon2; using simulation::MerkleCheckEvent; -TEST(MerkleCheckTraceGenTest, SingleLevelMerkleTree) +TEST(MerkleCheckTraceGenTest, MerkleRead) { TestTraceContainer trace; MerkleCheckTraceBuilder builder; FF leaf_value = FF(123); - uint64_t leaf_index = 0; // Even index - FF sibling_value = FF(456); + uint64_t leaf_index = 1; // Odd index - // Compute expected hash output - FF left_node = leaf_value; // For even index, leaf is left - FF right_node = sibling_value; - FF output_hash = Poseidon2::hash({ left_node, right_node }); + // Level 1 sibling + FF sibling_value_1 = FF(456); - std::vector sibling_path = { sibling_value }; - FF root = output_hash; // Root should match output hash + // Compute hash for level 1 + FF left_node_1 = sibling_value_1; // For odd index, sibling is left + FF right_node_1 = leaf_value; // For odd index, leaf is right + FF output_hash_1 = Poseidon2::hash({ left_node_1, right_node_1 }); + + // Level 2 sibling + FF sibling_value_2 = FF(789); + + // Compute hash for level 2 + FF left_node_2 = output_hash_1; // For odd index 1 in level 1, parent is at index 0 (even) in level 2 + FF right_node_2 = sibling_value_2; + FF output_hash_2 = Poseidon2::hash({ left_node_2, right_node_2 }); + + std::vector sibling_path = { sibling_value_1, sibling_value_2 }; + FF root = output_hash_2; // Root is the final output hash MerkleCheckEvent event = { .leaf_value = leaf_value, .leaf_index = leaf_index, .sibling_path = sibling_path, .root = root @@ -44,60 +55,79 @@ TEST(MerkleCheckTraceGenTest, SingleLevelMerkleTree) builder.process({ event }, trace); - EXPECT_THAT( - trace.as_rows(), - ElementsAre( - // First row is empty - AllOf(Field(&R::merkle_check_sel, 0)), - // First real row - AllOf(Field(&R::merkle_check_sel, 1), - Field(&R::merkle_check_leaf, leaf_value), - Field(&R::merkle_check_leaf_index, leaf_index), - Field(&R::merkle_check_tree_height, 1), - Field(&R::merkle_check_current_node, leaf_value), - Field(&R::merkle_check_current_index_in_layer, leaf_index), - Field(&R::merkle_check_remaining_path_len, 0), // only one layer, so remaining path is 0 immediately - Field(&R::merkle_check_remaining_path_len_inv, 0), - Field(&R::merkle_check_sibling, sibling_value), - Field(&R::merkle_check_start, 1), - Field(&R::merkle_check_end, 1), // done after only one layer - Field(&R::merkle_check_index_is_even, 1), - Field(&R::merkle_check_left_node, left_node), - Field(&R::merkle_check_right_node, right_node), - Field(&R::merkle_check_constant_2, 2), - Field(&R::merkle_check_output_hash, output_hash)))); + EXPECT_THAT(trace.as_rows(), + ElementsAre( + // First row is empty + AllOf(Field(&R::merkle_check_sel, 0)), + // First real row + AllOf(Field(&R::merkle_check_sel, 1), + Field(&R::merkle_check_write, 0), + Field(&R::merkle_check_read_node, leaf_value), + Field(&R::merkle_check_index, leaf_index), + Field(&R::merkle_check_path_len, 2), // path length starts at 2 + Field(&R::merkle_check_remaining_path_len_inv, FF(2 - 1).invert()), + Field(&R::merkle_check_read_root, root), + Field(&R::merkle_check_sibling, sibling_value_1), + Field(&R::merkle_check_start, 1), + Field(&R::merkle_check_end, 0), // Not done yet + Field(&R::merkle_check_index_is_even, 0), // Odd index + Field(&R::merkle_check_read_left_node, left_node_1), + Field(&R::merkle_check_read_right_node, right_node_1), + Field(&R::merkle_check_constant_2, 2), + Field(&R::merkle_check_read_output_hash, output_hash_1)), + // Second real row + AllOf(Field(&R::merkle_check_sel, 1), + Field(&R::merkle_check_write, 0), + Field(&R::merkle_check_read_node, output_hash_1), // Previous output becomes new leaf + Field(&R::merkle_check_index, 0), // Index should be 0 at level 2 + Field(&R::merkle_check_path_len, 1), // Remaining path length is 0 + Field(&R::merkle_check_remaining_path_len_inv, 0), + Field(&R::merkle_check_read_root, root), + Field(&R::merkle_check_sibling, sibling_value_2), + Field(&R::merkle_check_start, 0), + Field(&R::merkle_check_end, 1), // Done after two layers + Field(&R::merkle_check_index_is_even, 1), + Field(&R::merkle_check_read_left_node, left_node_2), + Field(&R::merkle_check_read_right_node, right_node_2), + Field(&R::merkle_check_constant_2, 2), + Field(&R::merkle_check_read_output_hash, output_hash_2)))); } -TEST(MerkleCheckTraceGenTest, TwoLevelMerkleTree) +TEST(MerkleCheckTraceGenTest, MerkleWrite) { TestTraceContainer trace; MerkleCheckTraceBuilder builder; FF leaf_value = FF(123); + FF new_leaf_value = FF(456); uint64_t leaf_index = 1; // Odd index // Level 1 sibling FF sibling_value_1 = FF(456); // Compute hash for level 1 - FF left_node_1 = sibling_value_1; // For odd index, sibling is left - FF right_node_1 = leaf_value; // For odd index, leaf is right - FF output_hash_1 = Poseidon2::hash({ left_node_1, right_node_1 }); + // For odd index, sibling is left, leaf is right + FF read_output_hash_1 = Poseidon2::hash({ sibling_value_1, leaf_value }); + FF write_output_hash_1 = Poseidon2::hash({ sibling_value_1, new_leaf_value }); // Level 2 sibling FF sibling_value_2 = FF(789); // Compute hash for level 2 - FF left_node_2 = output_hash_1; // For odd index 1 in level 1, parent is at index 0 (even) in level 2 - FF right_node_2 = sibling_value_2; - FF output_hash_2 = Poseidon2::hash({ left_node_2, right_node_2 }); + // For odd index 1 in level 1, parent is at index 0 (even) in level 2 + FF read_output_hash_2 = Poseidon2::hash({ read_output_hash_1, sibling_value_2 }); + FF write_output_hash_2 = Poseidon2::hash({ write_output_hash_1, sibling_value_2 }); std::vector sibling_path = { sibling_value_1, sibling_value_2 }; - FF root = output_hash_2; // Root is the final output hash + FF read_root = read_output_hash_2; + FF write_root = write_output_hash_2; - MerkleCheckEvent event = { - .leaf_value = leaf_value, .leaf_index = leaf_index, .sibling_path = sibling_path, .root = root - }; + MerkleCheckEvent event = { .leaf_value = leaf_value, + .new_leaf_value = new_leaf_value, + .leaf_index = leaf_index, + .sibling_path = sibling_path, + .root = read_root, + .new_root = write_root }; builder.process({ event }, trace); @@ -107,41 +137,49 @@ TEST(MerkleCheckTraceGenTest, TwoLevelMerkleTree) AllOf(Field(&R::merkle_check_sel, 0)), // First real row AllOf(Field(&R::merkle_check_sel, 1), - Field(&R::merkle_check_leaf, leaf_value), - Field(&R::merkle_check_leaf_index, leaf_index), - Field(&R::merkle_check_tree_height, 2), - Field(&R::merkle_check_current_node, leaf_value), - Field(&R::merkle_check_current_index_in_layer, leaf_index), - Field(&R::merkle_check_remaining_path_len, 1), // remaining path length is 1 after one layer - Field(&R::merkle_check_remaining_path_len_inv, FF(1).invert()), + Field(&R::merkle_check_write, 1), + Field(&R::merkle_check_read_node, leaf_value), + Field(&R::merkle_check_write_node, new_leaf_value), + Field(&R::merkle_check_index, leaf_index), + Field(&R::merkle_check_path_len, 2), // path length starts at 2 + Field(&R::merkle_check_remaining_path_len_inv, FF(2 - 1).invert()), + Field(&R::merkle_check_read_root, read_root), + Field(&R::merkle_check_write_root, write_root), Field(&R::merkle_check_sibling, sibling_value_1), Field(&R::merkle_check_start, 1), Field(&R::merkle_check_end, 0), // Not done yet Field(&R::merkle_check_index_is_even, 0), // Odd index - Field(&R::merkle_check_left_node, left_node_1), - Field(&R::merkle_check_right_node, right_node_1), + Field(&R::merkle_check_read_left_node, sibling_value_1), + Field(&R::merkle_check_read_right_node, leaf_value), + Field(&R::merkle_check_write_left_node, sibling_value_1), + Field(&R::merkle_check_write_right_node, new_leaf_value), Field(&R::merkle_check_constant_2, 2), - Field(&R::merkle_check_output_hash, output_hash_1)), + Field(&R::merkle_check_read_output_hash, read_output_hash_1), + Field(&R::merkle_check_write_output_hash, write_output_hash_1)), // Second real row AllOf(Field(&R::merkle_check_sel, 1), - Field(&R::merkle_check_leaf, leaf_value), - Field(&R::merkle_check_leaf_index, leaf_index), - Field(&R::merkle_check_tree_height, 2), - Field(&R::merkle_check_current_node, output_hash_1), // Previous output becomes new leaf - Field(&R::merkle_check_current_index_in_layer, 0), // Index should be 0 at level 2 - Field(&R::merkle_check_remaining_path_len, 0), // Remaining path length is 0 + Field(&R::merkle_check_write, 1), + Field(&R::merkle_check_read_node, read_output_hash_1), // Previous output becomes new leaf + Field(&R::merkle_check_write_node, write_output_hash_1), + Field(&R::merkle_check_index, 0), // Index should be 0 at level 2 + Field(&R::merkle_check_path_len, 1), // Remaining path length is 0 Field(&R::merkle_check_remaining_path_len_inv, 0), + Field(&R::merkle_check_read_root, read_root), + Field(&R::merkle_check_write_root, write_root), Field(&R::merkle_check_sibling, sibling_value_2), Field(&R::merkle_check_start, 0), Field(&R::merkle_check_end, 1), // Done after two layers Field(&R::merkle_check_index_is_even, 1), - Field(&R::merkle_check_left_node, left_node_2), - Field(&R::merkle_check_right_node, right_node_2), + Field(&R::merkle_check_read_left_node, read_output_hash_1), + Field(&R::merkle_check_read_right_node, sibling_value_2), + Field(&R::merkle_check_write_left_node, write_output_hash_1), + Field(&R::merkle_check_write_right_node, sibling_value_2), Field(&R::merkle_check_constant_2, 2), - Field(&R::merkle_check_output_hash, output_hash_2)))); + Field(&R::merkle_check_read_output_hash, read_output_hash_2), + Field(&R::merkle_check_write_output_hash, write_output_hash_2)))); } -TEST(MerkleCheckTraceGenTest, MultipleEvents) +TEST(MerkleCheckTraceGenTest, MixedEvents) { TestTraceContainer trace; MerkleCheckTraceBuilder builder; @@ -159,14 +197,18 @@ TEST(MerkleCheckTraceGenTest, MultipleEvents) // Second event FF leaf_value_2 = FF(333); + FF new_leaf_value_2 = FF(444); uint64_t leaf_index_2 = 11; FF sibling_value_2 = FF(444); - FF output_hash_2 = Poseidon2::hash({ sibling_value_2, leaf_value_2 }); + FF read_output_hash_2 = Poseidon2::hash({ sibling_value_2, leaf_value_2 }); + FF write_output_hash_2 = Poseidon2::hash({ sibling_value_2, new_leaf_value_2 }); MerkleCheckEvent event2 = { .leaf_value = leaf_value_2, + .new_leaf_value = new_leaf_value_2, .leaf_index = leaf_index_2, .sibling_path = { sibling_value_2 }, - .root = output_hash_2 }; + .root = read_output_hash_2, + .new_root = write_output_hash_2 }; builder.process({ event1, event2 }, trace); @@ -174,40 +216,43 @@ TEST(MerkleCheckTraceGenTest, MultipleEvents) ElementsAre( // First row is empty AllOf(Field(&R::merkle_check_sel, 0)), - // First real row + // First real row (read) AllOf(Field(&R::merkle_check_sel, 1), - Field(&R::merkle_check_leaf, leaf_value_1), - Field(&R::merkle_check_leaf_index, leaf_index_1), - Field(&R::merkle_check_tree_height, 1), - Field(&R::merkle_check_current_node, leaf_value_1), - Field(&R::merkle_check_current_index_in_layer, leaf_index_1), - Field(&R::merkle_check_remaining_path_len, 0), + Field(&R::merkle_check_write, 0), + Field(&R::merkle_check_read_node, leaf_value_1), + Field(&R::merkle_check_index, leaf_index_1), + Field(&R::merkle_check_path_len, 1), Field(&R::merkle_check_remaining_path_len_inv, 0), + Field(&R::merkle_check_read_root, output_hash_1), Field(&R::merkle_check_sibling, sibling_value_1), Field(&R::merkle_check_start, 1), Field(&R::merkle_check_end, 1), Field(&R::merkle_check_index_is_even, 1), - Field(&R::merkle_check_left_node, leaf_value_1), - Field(&R::merkle_check_right_node, sibling_value_1), + Field(&R::merkle_check_read_left_node, leaf_value_1), + Field(&R::merkle_check_read_right_node, sibling_value_1), Field(&R::merkle_check_constant_2, 2), - Field(&R::merkle_check_output_hash, output_hash_1)), - // Second real row + Field(&R::merkle_check_read_output_hash, output_hash_1)), + // Second real row (write) AllOf(Field(&R::merkle_check_sel, 1), - Field(&R::merkle_check_leaf, leaf_value_2), - Field(&R::merkle_check_leaf_index, leaf_index_2), - Field(&R::merkle_check_tree_height, 1), - Field(&R::merkle_check_current_node, leaf_value_2), - Field(&R::merkle_check_current_index_in_layer, leaf_index_2), - Field(&R::merkle_check_remaining_path_len, 0), + Field(&R::merkle_check_write, 1), + Field(&R::merkle_check_read_node, leaf_value_2), + Field(&R::merkle_check_write_node, new_leaf_value_2), + Field(&R::merkle_check_index, leaf_index_2), + Field(&R::merkle_check_path_len, 1), Field(&R::merkle_check_remaining_path_len_inv, 0), + Field(&R::merkle_check_read_root, read_output_hash_2), + Field(&R::merkle_check_write_root, write_output_hash_2), Field(&R::merkle_check_sibling, sibling_value_2), Field(&R::merkle_check_start, 1), Field(&R::merkle_check_end, 1), Field(&R::merkle_check_index_is_even, 0), - Field(&R::merkle_check_left_node, sibling_value_2), - Field(&R::merkle_check_right_node, leaf_value_2), + Field(&R::merkle_check_read_left_node, sibling_value_2), + Field(&R::merkle_check_read_right_node, leaf_value_2), + Field(&R::merkle_check_write_left_node, sibling_value_2), + Field(&R::merkle_check_write_right_node, new_leaf_value_2), Field(&R::merkle_check_constant_2, 2), - Field(&R::merkle_check_output_hash, output_hash_2)))); + Field(&R::merkle_check_read_output_hash, read_output_hash_2), + Field(&R::merkle_check_write_output_hash, write_output_hash_2)))); } } // namespace diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen_helper.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen_helper.cpp index 97368404b447..4e0098612c78 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen_helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen_helper.cpp @@ -356,7 +356,8 @@ TraceContainer AvmTraceGenHelper::generate_trace(EventsContainer&& events) std::make_unique>(), std::make_unique>(), // Merkle checks - std::make_unique>()); + std::make_unique>(), + std::make_unique>()); AVM_TRACK_TIME("tracegen/interactions", parallel_for(jobs_interactions.size(), [&](size_t i) { jobs_interactions[i]->process(trace); }));