Skip to content

Commit

Permalink
merged in aztec3
Browse files Browse the repository at this point in the history
  • Loading branch information
dbanks12 committed Apr 4, 2023
2 parents 5cf5c58 + 6c101be commit 49fc01a
Show file tree
Hide file tree
Showing 16 changed files with 766 additions and 508 deletions.
2 changes: 1 addition & 1 deletion cpp/src/barretenberg/crypto/generators/generator_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ constexpr size_t num_hash_indices = 32;
#else
constexpr size_t num_default_generators = 2048;
constexpr size_t num_hash_indices = 32;
constexpr size_t num_generators_per_hash_index = 64;
constexpr size_t num_generators_per_hash_index = 128;
#endif

constexpr size_t hash_indices_generator_offset = 2048;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@
namespace bonk {

/**
* @brief Hashes the evaluation domain to match the 'circuit' approach taken in stdlib/recursion/verification_key/verification_key.hpp.
* @note: in that reference file, the circuit-equivalent of this function is a _method_ of the `evaluation_domain' struct. But we cannot do that with the native `barretenberg::evaluation_domain` type unfortunately, because it's defined in polynomials/evaluation_domain.hpp, and `polynomial` is a bberg library which does not depend on `crypto` in its CMakeLists.txt file. (We'd need `crypto` to be able to call native pedersen functions).
* @brief Hashes the evaluation domain to match the 'circuit' approach taken in
* stdlib/recursion/verification_key/verification_key.hpp.
* @note: in that reference file, the circuit-equivalent of this function is a _method_ of the `evaluation_domain'
* struct. But we cannot do that with the native `barretenberg::evaluation_domain` type unfortunately, because it's
* defined in polynomials/evaluation_domain.hpp, and `polynomial` is a bberg library which does not depend on `crypto`
* in its CMakeLists.txt file. (We'd need `crypto` to be able to call native pedersen functions).
*
* @param domain to compress
* @param composer_type to use when choosing pedersen compression function
* @return barretenberg::fr compression of the evaluation domain as a field
*/
barretenberg::fr compress_native_evaluation_domain(barretenberg::evaluation_domain const& domain, plonk::ComposerType composer_type) {
barretenberg::fr compress_native_evaluation_domain(barretenberg::evaluation_domain const& domain,
plonk::ComposerType composer_type)
{
barretenberg::fr out;
if (composer_type == plonk::ComposerType::PLOOKUP) {
out = crypto::pedersen_commitment::lookup::compress_native({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,12 @@ template <typename B> inline void write(B& buf, verification_key const& key)

inline std::ostream& operator<<(std::ostream& os, verification_key const& key)
{
return os
<< "key.composer_type: " << key.composer_type << "\n"
<< "key.circuit_size: " << static_cast<uint32_t>(key.circuit_size) << "\n"
<< "key.num_public_inputs: " << static_cast<uint32_t>(key.num_public_inputs) << "\n"
<< "key.commitments: " << key.commitments << "\n"
<< "key.contains_recursive_proof: " << key.contains_recursive_proof << "\n"
<< "key.recursive_proof_public_input_indices: " << key.recursive_proof_public_input_indices << "\n";
return os << "key.composer_type: " << key.composer_type << "\n"
<< "key.circuit_size: " << static_cast<uint32_t>(key.circuit_size) << "\n"
<< "key.num_public_inputs: " << static_cast<uint32_t>(key.num_public_inputs) << "\n"
<< "key.commitments: " << key.commitments << "\n"
<< "key.contains_recursive_proof: " << key.contains_recursive_proof << "\n"
<< "key.recursive_proof_public_input_indices: " << key.recursive_proof_public_input_indices << "\n";
};

} // namespace bonk
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ using namespace bonk;
*
* @return verification_key_data randomly generated
*/
verification_key_data rand_vk_data() {
verification_key_data vk_data;
vk_data.composer_type = static_cast<uint32_t>(plonk::ComposerType::STANDARD);
vk_data.circuit_size = 1024; // not random - must be power of 2
vk_data.num_public_inputs = engine.get_random_uint32();
vk_data.commitments["test1"] = g1::element::random_element();
vk_data.commitments["test2"] = g1::element::random_element();
vk_data.commitments["foo1"] = g1::element::random_element();
vk_data.commitments["foo2"] = g1::element::random_element();
info("test0 vk_data commitments: ", vk_data.commitments);
return vk_data;
verification_key_data rand_vk_data()
{
verification_key_data key_data;
key_data.composer_type = static_cast<uint32_t>(plonk::ComposerType::STANDARD);
key_data.circuit_size = 1024; // not random - must be power of 2
key_data.num_public_inputs = engine.get_random_uint32();
key_data.commitments["test1"] = g1::element::random_element();
key_data.commitments["test2"] = g1::element::random_element();
key_data.commitments["foo1"] = g1::element::random_element();
key_data.commitments["foo2"] = g1::element::random_element();
return key_data;
}

/**
Expand Down
1 change: 1 addition & 0 deletions cpp/src/barretenberg/stdlib/merkle_tree/hash_path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace merkle_tree {
using namespace barretenberg;

typedef std::vector<std::pair<fr, fr>> fr_hash_path;
typedef std::vector<fr> fr_sibling_path;
template <typename Ctx> using hash_path = std::vector<std::pair<field_t<Ctx>, field_t<Ctx>>>;

inline fr_hash_path get_new_hash_path(fr_hash_path const& old_path, uint128_t index, fr const& value)
Expand Down
18 changes: 18 additions & 0 deletions cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@ fr_hash_path MemoryTree::get_hash_path(size_t index)
return path;
}

fr_sibling_path MemoryTree::get_sibling_path(size_t index)
{
fr_sibling_path path(depth_);
size_t offset = 0;
size_t layer_size = total_size_;
for (size_t i = 0; i < depth_; i++) {
if (index % 2 == 0) {
path[i] = hashes_[offset + index + 1];
} else {
path[i] = hashes_[offset + index - 1];
}
offset += layer_size;
layer_size >>= 1;
index >>= 1;
}
return path;
}

fr MemoryTree::update_element(size_t index, fr const& value)
{
size_t offset = 0;
Expand Down
2 changes: 2 additions & 0 deletions cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class MemoryTree {

fr_hash_path get_hash_path(size_t index);

fr_sibling_path get_sibling_path(size_t index);

fr update_element(size_t index, fr const& value);

fr root() const { return root_; }
Expand Down
37 changes: 36 additions & 1 deletion cpp/src/barretenberg/stdlib/merkle_tree/memory_tree.test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "memory_tree.hpp"
#include <gtest/gtest.h>
#include "barretenberg/stdlib/types/types.hpp"

using namespace barretenberg;
using namespace plonk::stdlib::merkle_tree;
Expand Down Expand Up @@ -43,3 +42,39 @@ TEST(stdlib_merkle_tree, test_memory_store)
EXPECT_EQ(db.get_hash_path(3), expected);
EXPECT_EQ(db.root(), root);
}

TEST(stdlib_merkle_tree, test_memory_store_sibling_path)
{
fr e00 = 0;
fr e01 = VALUES[1];
fr e02 = VALUES[2];
fr e03 = VALUES[3];
fr e10 = hash_pair_native(e00, e01);
fr e11 = hash_pair_native(e02, e03);
fr root = hash_pair_native(e10, e11);

MemoryTree db(2);
for (size_t i = 0; i < 4; ++i) {
db.update_element(i, VALUES[i]);
}

// Check correct paths are generated for each layer 0 element
fr_sibling_path expected00 = {
e01,
e11,
};
fr_sibling_path expected01 = { e00, e11 };
fr_sibling_path expected02 = {
e03,
e10,
};
fr_sibling_path expected03 = {
e02,
e10,
};
EXPECT_EQ(db.get_sibling_path(0), expected00);
EXPECT_EQ(db.get_sibling_path(1), expected01);
EXPECT_EQ(db.get_sibling_path(2), expected02);
EXPECT_EQ(db.get_sibling_path(3), expected03);
EXPECT_EQ(db.root(), root);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ inline std::pair<size_t, bool> find_closest_leaf(std::vector<nullifier_leaf> con
{
std::vector<uint256_t> diff;
bool repeated = false;
auto new_value_ = uint256_t(new_value);

for (size_t i = 0; i < leaves_.size(); i++) {
auto leaf_value_ = uint256_t(leaves_[i].value);
auto new_value_ = uint256_t(new_value);
if (leaf_value_ > new_value_) {
diff.push_back(leaf_value_);
} else if (leaf_value_ == new_value_) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ class NullifierMemoryTree : public MemoryTree {

const std::vector<barretenberg::fr>& get_hashes() { return hashes_; }
const std::vector<nullifier_leaf>& get_leaves() { return leaves_; }
const nullifier_leaf& get_leaf(size_t index) { return leaves_[index]; }

private:
protected:
using MemoryTree::depth_;
using MemoryTree::hashes_;
using MemoryTree::root_;
Expand Down
2 changes: 2 additions & 0 deletions cpp/src/barretenberg/stdlib/primitives/bool/bool.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,8 @@ TEST(stdlib_bool, must_imply)
EXPECT_EQ(result, true);
}

// TODO: must_imply failure case

TEST(stdlib_bool, must_imply_multiple)
{
honk::StandardHonkComposer composer = honk::StandardHonkComposer();
Expand Down
72 changes: 37 additions & 35 deletions cpp/src/barretenberg/stdlib/primitives/field/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ template <typename Composer, size_t SIZE> field_t<Composer> array_length(std::ar
field_t<Composer> length = 0;
bool_t<Composer> hit_zero = false;
for (const auto& e : arr) {
hit_zero |= e == 0;
bool_t<Composer> is_zero = e.is_zero();
hit_zero.must_imply(is_zero, "Once we've hit the first zero, there must only be zeros thereafter!");
hit_zero |= is_zero;
const field_t<Composer> increment = !hit_zero;
length += increment;
}
Expand Down Expand Up @@ -132,44 +134,44 @@ template <typename Composer, size_t size_1, size_t size_2>
void push_array_to_array(std::array<field_t<Composer>, size_1> const& source,
std::array<field_t<Composer>, size_2>& target)
{
ASSERT(target.size() >= source.size());
field_t<Composer> source_length = array_length<Composer>(source);
field_t<Composer> target_length = array_length<Composer>(target);
const field_t<Composer> overflow_capacity = target.max_size() + 1;

field_t<Composer> j_ct = 0; // circuit-type index for the inner loop
// Find the first empty slot in the target:
field_t<Composer> next_target_index = target_length;

bool_t<Composer> hit_s_zero = false;
bool_t<Composer> not_hit_s_zero = true;

for (size_t i = 0; i < source.max_size(); ++i) {
// Loop over each source value we want to push:
auto& s = source[i];
{
auto is_s_zero = s.is_zero();
hit_s_zero.must_imply(is_s_zero,
"Once we've hit the first source zero, there must only be zeros thereafter!");
hit_s_zero |= is_s_zero;
not_hit_s_zero = !hit_s_zero;
}

// Check if the `source` array is too large vs the remaining capacity of the `target` array
auto source_length_safe = safe_uint_t<Composer>(source_length, sizeof(size_t) * 8, "source_array_len");
auto target_length_safe = safe_uint_t<Composer>(target_length, sizeof(size_t) * 8, "target_array_len");
auto target_capacity_safe =
safe_uint_t<Composer>(field_t<Composer>(target.size()), sizeof(size_t) * 8, "target_array_capacity");
target_capacity_safe.subtract((source_length_safe + target_length_safe),
sizeof(size_t) * 8,
"push_array_to_array target array capacity exceeded");

// Ensure that all the elements after the first zero-element in target are zero
field_t<Composer> num_non_zero_in_target = 0;
for (size_t i = 0; i < size_2; i++) {
num_non_zero_in_target += !target[i].is_zero();
}
num_non_zero_in_target.assert_equal(target_length_safe, "non-zero element in target array after a zero element");
// Triangular loop:
for (size_t j = i; j < target.max_size(); ++j) {
auto& t = target[j];

// Ensure that all the elements after the first zero-element in source are zero
field_t<Composer> num_non_zero_in_source = 0;
for (size_t i = 0; i < size_1; i++) {
num_non_zero_in_source += !source[i].is_zero();
}
num_non_zero_in_source.assert_equal(source_length_safe, "non-zero element in source array after a zero element");

// Finally, insert only non-zero elements from source into target
bool_t<Composer> composer_error_found = !source_length.get_context()->err().empty();
for (size_t i = 0; i < source.size(); i++) {
bool_t<Composer> found = false;

for (size_t j = i; j < target.size(); j++) {
bool_t<Composer> is_target_non_zero = !target[j].is_zero();
target[j] = field_t<Composer>::conditional_assign(
is_target_non_zero, target[j], source[i] * !found * !composer_error_found);
found |= !is_target_non_zero;
// Check whether we've reached the next target index at which we can push `s`:
bool_t<Composer> at_next_target_index = j_ct == next_target_index;

t = field_t<Composer>::conditional_assign(at_next_target_index && not_hit_s_zero, s, t);

j_ct++;
}

next_target_index += not_hit_s_zero;

next_target_index.assert_not_equal(overflow_capacity, "push_array_to_array target array capacity exceeded");

j_ct = i + 1;
}
}

Expand Down
Loading

0 comments on commit 49fc01a

Please sign in to comment.