Skip to content

Commit

Permalink
Merge branch 'master' into as/smt-verification-upmodule-update-4
Browse files Browse the repository at this point in the history
  • Loading branch information
Rumata888 authored Jun 19, 2024
2 parents a937f0e + e37809b commit 1902b3c
Show file tree
Hide file tree
Showing 34 changed files with 238 additions and 196 deletions.
33 changes: 33 additions & 0 deletions barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,34 @@ template <typename Flavor> class ProtoGalaxyTests : public testing::Test {
}
}

/**
* @brief Testing one valid round of folding followed by the decider.
* @brief For additional robustness we give one of the circuits more public inputs than the other
*
*/
static void test_full_protogalaxy_simple()
{
// Construct a first circuit with some public inputs
Builder builder1;
construct_circuit(builder1);
bb::MockCircuits::add_arithmetic_gates_with_public_inputs(builder1, /*num_gates=*/4);

// Construct a second circuit with no public inputs
Builder builder2;
construct_circuit(builder2);

// Construct the prover/verifier instances for each
TupleOfInstances instances;
construct_prover_and_verifier_instance(instances, builder1);
construct_prover_and_verifier_instance(instances, builder2);

// Perform prover and verifier folding
auto [prover_accumulator, verifier_accumulator] = fold_and_verify(get<0>(instances), get<1>(instances));
check_accumulator_target_sum_manual(prover_accumulator, true);

decide_and_verify(prover_accumulator, verifier_accumulator, true);
}

/**
* @brief Testing two valid rounds of folding followed by the decider.
*
Expand Down Expand Up @@ -489,6 +517,11 @@ TYPED_TEST(ProtoGalaxyTests, CombineAlpha)
TestFixture::test_combine_alpha();
}

TYPED_TEST(ProtoGalaxyTests, FullProtogalaxySimple)
{
TestFixture::test_full_protogalaxy_simple();
}

TYPED_TEST(ProtoGalaxyTests, FullProtogalaxyTest)
{
TestFixture::test_full_protogalaxy();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,22 +104,6 @@ std::shared_ptr<typename ProverInstances::Instance> ProtoGalaxyProver_<ProverIns
});
}

// Fold the public inputs and send to the verifier
size_t el_idx = 0;
for (auto& el : next_accumulator->proving_key.public_inputs) {
el *= lagranges[0];
size_t inst = 0;
for (size_t inst_idx = 1; inst_idx < ProverInstances::NUM; inst_idx++) {
auto& instance = instances[inst_idx];
// TODO(https://github.com/AztecProtocol/barretenberg/issues/830)
if (instance->proving_key.num_public_inputs >= next_accumulator->proving_key.num_public_inputs) {
el += instance->proving_key.public_inputs[el_idx] * lagranges[inst];
inst++;
};
}
el_idx++;
}

// Evaluate the combined batching α_i univariate at challenge to obtain next α_i and send it to the
// verifier, where i ∈ {0,...,NUM_SUBRELATIONS - 1}
auto& folded_alphas = next_accumulator->alphas;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,19 +115,7 @@ std::shared_ptr<typename VerifierInstances::Instance> ProtoGalaxyVerifier_<Verif
next_accumulator->verification_key->num_public_inputs = accumulator->verification_key->num_public_inputs;
next_accumulator->public_inputs =
std::vector<FF>(static_cast<size_t>(next_accumulator->verification_key->num_public_inputs), 0);
size_t public_input_idx = 0;
for (auto& public_input : next_accumulator->public_inputs) {
size_t inst = 0;
for (auto& instance : instances) {
// TODO(https://github.com/AztecProtocol/barretenberg/issues/830)
if (instance->verification_key->num_public_inputs >=
next_accumulator->verification_key->num_public_inputs) {
public_input += instance->public_inputs[public_input_idx] * lagranges[inst];
inst++;
}
}
public_input_idx++;
}

next_accumulator->is_accumulator = true;

// Compute next folding parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,21 +177,6 @@ std::shared_ptr<typename VerifierInstances::Instance> ProtoGalaxyRecursiveVerifi
// Compute ϕ
fold_commitments(lagranges, instances, next_accumulator);

next_accumulator->public_inputs =
std::vector<FF>(static_cast<size_t>(next_accumulator->verification_key->num_public_inputs), 0);
size_t public_input_idx = 0;
for (auto& public_input : next_accumulator->public_inputs) {
size_t inst = 0;
for (auto& instance : instances) {
if (instance->verification_key->num_public_inputs >=
next_accumulator->verification_key->num_public_inputs) {
public_input += instance->public_inputs[public_input_idx] * lagranges[inst];
inst++;
};
}
public_input_idx++;
}

size_t alpha_idx = 0;
for (auto& alpha : next_accumulator->alphas) {
alpha = FF(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ template <typename Flavor> bool UltraVerifier_<Flavor>::verify_proof(const HonkP
transcript = std::make_shared<Transcript>(proof);
VerifierCommitments commitments{ key };
OinkVerifier<Flavor> oink_verifier{ key, transcript };
auto [relation_parameters, witness_commitments, _, alphas] = oink_verifier.verify();
auto [relation_parameters, witness_commitments, public_inputs, alphas] = oink_verifier.verify();

// Copy the witness_commitments over to the VerifierCommitments
for (auto [wit_comm_1, wit_comm_2] : zip_view(commitments.get_witness(), witness_commitments.get_all())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1473,8 +1473,9 @@ TEST_F(AvmExecutionTests, msmOpCode)

EXPECT_EQ(returndata, expected_output);

validate_trace(std::move(trace));
validate_trace(std::move(trace), public_inputs);
}

// Positive test for Kernel Input opcodes
TEST_F(AvmExecutionTests, kernelInputOpcodes)
{
Expand Down
28 changes: 28 additions & 0 deletions docs/docs/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,34 @@ Aztec is in full-speed development. Literally every version breaks compatibility
Earlier we had just one function - `transfer()` which used authwits to handle the case where a contract/user wants to transfer funds on behalf of another user.
To reduce circuit sizes and proof times, we are breaking up `transfer` and introducing a dedicated `transferFrom()` function like in the ERC20 standard.

### [Aztec.nr] `note_getter` returns `BoundedVec`

The `get_notes` and `view_notes` function no longer return an array of options (i.e. `[Option<Note>, N_NOTES]`) but instead a `BoundedVec<Note, N_NOTES>`. This better conveys the useful property the old array had of having all notes collapsed at the beginning of the array, which allows for powerful optimizations and gate count reduction when setting the `options.limit` value.

A `BoundedVec` has a `max_len()`, which equals the number of elements it can hold, and a `len()`, which equals the number of elements it currently holds. Since `len()` is typically not knwon at compile time, iterating over a `BoundedVec` looks slightly different than iterating over an array of options:

```diff
- let option_notes = get_notes(options);
- for i in 0..option_notes.len() {
- if option_notes[i].is_some() {
- let note = option_notes[i].unwrap_unchecked();
- }
- }
+ let notes = get_notes(options);
+ for i in 0..notes.max_len() {
+ if i < notes.len() {
+ let note = notes.get_unchecked(i);
+ }
+ }
```

To further reduce gate count, you can iterate over `options.limit` instead of `max_len()`, since `options.limit` is guaranteed to be larger or equal to `len()`, and smaller or equal to `max_len()`:

```diff
- for i in 0..notes.max_len() {
+ for i in 0..options.limit {
```

### [Aztec.nr] `options.limit` has to be constant

The `limit` parameter in `NoteGetterOptions` and `NoteViewerOptions` is now required to be a compile-time constant. This allows performing loops over this value, which leads to reduced circuit gate counts when setting a `limit` value.
Expand Down
31 changes: 19 additions & 12 deletions noir-projects/aztec-nr/aztec/src/note/note_getter.nr
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ pub fn get_notes<Note, N, M, FILTER_ARGS>(
context: &mut PrivateContext,
storage_slot: Field,
options: NoteGetterOptions<Note, N, M, FILTER_ARGS>
) -> [Option<Note>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] where Note: NoteInterface<N, M> {
) -> BoundedVec<Note, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL> where Note: NoteInterface<N, M> {
let opt_notes = get_notes_internal(storage_slot, options);

constrain_get_notes_internal(context, storage_slot, opt_notes, options)
Expand All @@ -115,8 +115,8 @@ fn constrain_get_notes_internal<Note, N, M, FILTER_ARGS>(
storage_slot: Field,
opt_notes: [Option<Note>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL],
options: NoteGetterOptions<Note, N, M, FILTER_ARGS>
) -> [Option<Note>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] where Note: NoteInterface<N, M> {
let mut returned_notes = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];
) -> BoundedVec<Note, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL> where Note: NoteInterface<N, M> {
let mut returned_notes = BoundedVec::new();

// The filter is applied first to avoid pushing note read requests for notes we're not interested in. Note that
// while the filter function can technically mutate the contents of the notes (as opposed to simply removing some),
Expand All @@ -126,7 +126,6 @@ fn constrain_get_notes_internal<Note, N, M, FILTER_ARGS>(
let filter_args = options.filter_args;
let filtered_notes = filter_fn(opt_notes, filter_args);

let mut num_notes = 0;
let mut prev_fields = [0; N];
for i in 0..filtered_notes.len() {
let opt_note = filtered_notes[i];
Expand All @@ -151,14 +150,12 @@ fn constrain_get_notes_internal<Note, N, M, FILTER_ARGS>(
// resulting in a smaller circuit and faster proving times.
// We write at returned_notes[num_notes] because num_notes is only advanced when we have a value in
// filtered_notes.
returned_notes[num_notes] = Option::some(note);
num_notes += 1;
returned_notes.push(note);
};
}

assert(num_notes <= options.limit, "Got more notes than limit.");

assert(num_notes != 0, "Cannot return zero notes");
assert(returned_notes.len() <= options.limit, "Got more notes than limit.");
assert(returned_notes.len() != 0, "Cannot return zero notes");

returned_notes
}
Expand Down Expand Up @@ -223,12 +220,13 @@ unconstrained fn get_notes_internal<Note, N, M, FILTER_ARGS>(
unconstrained pub fn view_notes<Note, N, M>(
storage_slot: Field,
options: NoteViewerOptions<Note, N, M>
) -> [Option<Note>; MAX_NOTES_PER_PAGE] where Note: NoteInterface<N, M> {
) -> BoundedVec<Note, MAX_NOTES_PER_PAGE> where Note: NoteInterface<N, M> {
let (num_selects, select_by_indexes, select_by_offsets, select_by_lengths, select_values, select_comparators, sort_by_indexes, sort_by_offsets, sort_by_lengths, sort_order) = flatten_options(options.selects, options.sorts);
let placeholder_opt_notes = [Option::none(); MAX_NOTES_PER_PAGE];
let placeholder_fields = [0; VIEW_NOTE_ORACLE_RETURN_LENGTH];
let placeholder_note_length = [0; N];
oracle::notes::get_notes(

let notes_array = oracle::notes::get_notes(
storage_slot,
num_selects,
select_by_indexes,
Expand All @@ -246,7 +244,16 @@ unconstrained pub fn view_notes<Note, N, M>(
placeholder_opt_notes,
placeholder_fields,
placeholder_note_length
)
);

let mut notes = BoundedVec::new();
for i in 0..notes_array.len() {
if notes_array[i].is_some() {
notes.push(notes_array[i].unwrap_unchecked());
}
}

notes
}

unconstrained fn flatten_options<Note, N>(
Expand Down
21 changes: 17 additions & 4 deletions noir-projects/aztec-nr/aztec/src/note/note_getter/test.nr
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ fn build_valid_note(value: Field) -> MockNote {
MockNote::new(value).contract_address(cheatcodes::get_contract_address()).storage_slot(storage_slot).build()
}

fn assert_equivalent_vec_and_array<T, N>(vec: BoundedVec<T, N>, arr: [Option<T>; N]) where T: Eq {
let mut count = 0;

for i in 0..N {
if arr[i].is_some() {
assert_eq(arr[i].unwrap(), vec.get(count));
count += 1;
}
}

assert_eq(count, vec.len());
}

#[test]
fn processes_single_note() {
let mut env = setup();
Expand All @@ -32,7 +45,7 @@ fn processes_single_note() {
let options = NoteGetterOptions::new();
let returned = constrain_get_notes_internal(&mut context, storage_slot, notes_to_constrain, options);

assert_eq(returned, notes_to_constrain);
assert_equivalent_vec_and_array(returned, notes_to_constrain);
assert_eq(context.note_hash_read_requests.len(), 1);
}

Expand All @@ -48,7 +61,7 @@ fn processes_many_notes() {
let options = NoteGetterOptions::new();
let returned = constrain_get_notes_internal(&mut context, storage_slot, notes_to_constrain, options);

assert_eq(returned, notes_to_constrain);
assert_equivalent_vec_and_array(returned, notes_to_constrain);
assert_eq(context.note_hash_read_requests.len(), 2);
}

Expand Down Expand Up @@ -78,7 +91,7 @@ fn collapses_notes_at_the_beginning_of_the_array() {
expected[5] = Option::some(build_valid_note(5));
expected[6] = Option::some(build_valid_note(6));

assert_eq(returned, expected);
assert_equivalent_vec_and_array(returned, expected);
}

#[test(should_fail_with="Cannot return zero notes")]
Expand Down Expand Up @@ -137,7 +150,7 @@ fn applies_filter_before_constraining() {
let mut expected = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];
expected[0] = Option::some(build_valid_note(42));

assert_eq(returned, expected);
assert_equivalent_vec_and_array(returned, expected);
assert_eq(context.note_hash_read_requests.len(), 1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl<Note> PrivateImmutable<Note, UnconstrainedContext> {
// docs:start:view_note
unconstrained pub fn view_note<N, M>(self) -> Note where Note: NoteInterface<N, M> {
let mut options = NoteViewerOptions::new();
view_notes(self.storage_slot, options.set_limit(1))[0].unwrap()
view_notes(self.storage_slot, options.set_limit(1)).get(0)
}
// docs:end:view_note
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl<Note> PrivateMutable<Note, UnconstrainedContext> {
// docs:start:view_note
unconstrained pub fn view_note<N, M>(self) -> Note where Note: NoteInterface<N, M> {
let mut options = NoteViewerOptions::new();
view_notes(self.storage_slot, options.set_limit(1))[0].unwrap()
view_notes(self.storage_slot, options.set_limit(1)).get(0)
}
// docs:end:view_note
}
8 changes: 3 additions & 5 deletions noir-projects/aztec-nr/aztec/src/state_vars/private_set.nr
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,8 @@ impl<Note> PrivateSet<Note, &mut PrivateContext> {
pub fn get_notes<N, M, FILTER_ARGS>(
self,
options: NoteGetterOptions<Note, N, M, FILTER_ARGS>
) -> [Option<Note>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] where Note: NoteInterface<N, M> {
let storage_slot = self.storage_slot;
let opt_notes = get_notes(self.context, storage_slot, options);
opt_notes
) -> BoundedVec<Note, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL> where Note: NoteInterface<N, M> {
get_notes(self.context, self.storage_slot, options)
}
// docs:end:get_notes
}
Expand All @@ -71,7 +69,7 @@ impl<Note> PrivateSet<Note, UnconstrainedContext> {
unconstrained pub fn view_notes<N, M>(
self,
options: NoteViewerOptions<Note, N, M>
) -> [Option<Note>; MAX_NOTES_PER_PAGE] where Note: NoteInterface<N, M> {
) -> BoundedVec<Note, MAX_NOTES_PER_PAGE> where Note: NoteInterface<N, M> {
view_notes(self.storage_slot, options)
}
// docs:end:view_notes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ impl<Context> EasyPrivateUint<&mut PrivateContext> {

// docs:start:get_notes
let options = NoteGetterOptions::with_filter(filter_notes_min_sum, subtrahend as Field);
let maybe_notes = self.set.get_notes(options);
let notes = self.set.get_notes(options);
// docs:end:get_notes

let mut minuend: u64 = 0;
for i in 0..options.limit {
if maybe_notes[i].is_some() {
let note = maybe_notes[i].unwrap_unchecked();
if i < notes.len() {
let note = notes.get_unchecked(i);

// Removes the note from the owner's set of notes.
// docs:start:remove
Expand Down
14 changes: 7 additions & 7 deletions noir-projects/aztec-nr/value-note/src/balance_utils.nr
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ unconstrained pub fn get_balance_with_offset(set: PrivateSet<ValueNote, Unconstr
let mut balance = 0;
// docs:start:view_notes
let mut options = NoteViewerOptions::new();
let opt_notes = set.view_notes(options.set_offset(offset));
let notes = set.view_notes(options.set_offset(offset));
// docs:end:view_notes
let len = opt_notes.len();
for i in 0..len {
if opt_notes[i].is_some() {
balance += opt_notes[i].unwrap_unchecked().value;
for i in 0..options.limit {
if i < notes.len() {
balance += notes.get_unchecked(i).value;
}
}
if (opt_notes[len - 1].is_some()) {
balance += get_balance_with_offset(set, offset + opt_notes.len() as u32);

if (notes.len() == options.limit) {
balance += get_balance_with_offset(set, offset + options.limit);
}

balance
Expand Down
Loading

0 comments on commit 1902b3c

Please sign in to comment.