Skip to content

Commit

Permalink
feat(892): add hints for matching transient read requests with corres…
Browse files Browse the repository at this point in the history
…pondi… (#1995)

Add hints for matching transient read requests with corresponding
commitments.
Resolves #892 

# Checklist:
Remove the checklist to signal you've completed it. Enable auto-merge if
the PR is ready to merge.
- [x] If the pull request requires a cryptography review (e.g.
cryptographic algorithm implementations) I have added the 'crypto' tag.
- [x] I have reviewed my diff in github, line by line and removed
unexpected formatting changes, testing logs, or commented-out code.
- [x] Every change is related to the PR description.
- [x] I have
[linked](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue)
this pull request to relevant issues (if any exist).
  • Loading branch information
jeanmon authored Sep 5, 2023
1 parent fa60d66 commit 0955bb7
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 24 deletions.
1 change: 0 additions & 1 deletion circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ using aztec3::circuits::abis::KernelCircuitPublicInputs;
using aztec3::circuits::abis::NewContractData;
using aztec3::circuits::abis::ReadRequestMembershipWitness;

using aztec3::utils::array_length;
using aztec3::utils::array_push;
using aztec3::utils::is_array_empty;
using aztec3::utils::push_array_to_array;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ TEST_F(native_private_kernel_tests, native_accumulate_transient_read_requests)
private_inputs_init.private_call.read_request_membership_witnesses[0].is_transient = true;

std::array<fr, MAX_READ_REQUESTS_PER_TX> hint_to_commitments{};
hint_to_commitments[0] = private_inputs_init.private_call.read_request_membership_witnesses[0].hint_to_commitment;
hint_to_commitments[0] = fr(1);

DummyBuilder builder = DummyBuilder("native_private_kernel_tests__native_accumulate_transient_read_requests");
auto public_inputs = native_private_kernel_circuit_initial(builder, private_inputs_init);
Expand All @@ -76,7 +76,7 @@ TEST_F(native_private_kernel_tests, native_accumulate_transient_read_requests)
private_inputs_inner.private_call.call_stack_item.public_inputs.read_requests[0] = fr(12);
private_inputs_inner.private_call.read_request_membership_witnesses[0].is_transient = true;

hint_to_commitments[1] = private_inputs_inner.private_call.read_request_membership_witnesses[0].hint_to_commitment;
hint_to_commitments[1] = fr(0);

// We need to update the previous_kernel's private_call_stack because the current_call_stack_item has changed
// i.e. we changed the new_commitments and read_requests of the current_call_stack_item's public_inputs
Expand Down Expand Up @@ -117,7 +117,7 @@ TEST_F(native_private_kernel_tests, native_transient_read_requests_no_match)
private_inputs_init.private_call.read_request_membership_witnesses[0].is_transient = true;

std::array<fr, MAX_READ_REQUESTS_PER_TX> hint_to_commitments{};
hint_to_commitments[0] = private_inputs_init.private_call.read_request_membership_witnesses[0].hint_to_commitment;
hint_to_commitments[0] = fr(1);

DummyBuilder builder = DummyBuilder("native_private_kernel_tests__native_transient_read_requests_no_match");
auto public_inputs = native_private_kernel_circuit_initial(builder, private_inputs_init);
Expand All @@ -133,7 +133,7 @@ TEST_F(native_private_kernel_tests, native_transient_read_requests_no_match)
private_inputs_inner.private_call.call_stack_item.public_inputs.read_requests[0] = fr(12);
private_inputs_inner.private_call.read_request_membership_witnesses[0].is_transient = true;

hint_to_commitments[1] = private_inputs_inner.private_call.read_request_membership_witnesses[0].hint_to_commitment;
hint_to_commitments[1] = fr(0); // There is not correct possible value.

// We need to update the previous_kernel's private_call_stack because the current_call_stack_item has changed
// i.e. we changed the new_commitments and read_requests of the current_call_stack_item's public_inputs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "aztec3/utils/circuit_errors.hpp"
#include "aztec3/utils/dummy_circuit_builder.hpp"

#include <cstddef>
#include <barretenberg/numeric/uint256/uint256.hpp>

namespace {
using NT = aztec3::utils::types::NativeTypes;
Expand All @@ -34,9 +34,6 @@ void initialise_end_values(PreviousKernelData<NT> const& previous_kernel,

namespace aztec3::circuits::kernel::private_kernel {

// TODO(https://github.com/AztecProtocol/aztec-packages/issues/892): optimized based on hints
// regarding matching a read request to a commitment
// i.e., we get pairs i,j such that read_requests[i] == new_commitments[j]
void match_reads_to_commitments(DummyCircuitBuilder& builder,
std::array<NT::fr, MAX_READ_REQUESTS_PER_TX> const& read_requests,
std::array<NT::fr, MAX_READ_REQUESTS_PER_TX> const& hint_to_commitments,
Expand All @@ -46,16 +43,14 @@ void match_reads_to_commitments(DummyCircuitBuilder& builder,
for (size_t rr_idx = 0; rr_idx < MAX_READ_REQUESTS_PER_TX; rr_idx++) {
const auto& read_request = read_requests[rr_idx];
const auto& hint_to_commitment = hint_to_commitments[rr_idx];
const auto hint_pos = static_cast<size_t>(uint64_t(hint_to_commitment));

if (read_request != 0) {
size_t match_pos = MAX_NEW_COMMITMENTS_PER_TX;
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/892): inefficient
// O(n^2) inner loop will be optimized via matching hints
for (size_t c_idx = 0; c_idx < MAX_NEW_COMMITMENTS_PER_TX; c_idx++) {
match_pos = (read_request == new_commitments[c_idx]) ? c_idx : match_pos;
if (hint_pos < MAX_NEW_COMMITMENTS_PER_TX) {
match_pos = read_request == new_commitments[hint_pos] ? hint_pos : match_pos;
}

// Transient reads MUST match a pending commitment
builder.do_assert(
match_pos != MAX_NEW_COMMITMENTS_PER_TX,
format("read_request at position [",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ TEST_F(native_private_kernel_ordering_tests, native_matching_one_read_request_to
std::array<fr, MAX_NEW_COMMITMENTS_PER_TX> siloed_commitments{};
std::array<fr, MAX_NEW_COMMITMENTS_PER_TX> unique_siloed_commitments{};
std::array<fr, MAX_READ_REQUESTS_PER_TX> read_requests{};
std::array<fr, MAX_READ_REQUESTS_PER_TX> hints{};

std::array<ReadRequestMembershipWitness<NT, PRIVATE_DATA_TREE_HEIGHT>, MAX_READ_REQUESTS_PER_TX>
read_request_membership_witnesses{};

Expand All @@ -50,6 +52,7 @@ TEST_F(native_private_kernel_ordering_tests, native_matching_one_read_request_to
siloed_commitments[0] == 0 ? 0 : compute_unique_commitment<NT>(nonce, siloed_commitments[0]);

read_requests[0] = siloed_commitments[0];
// hints[0] == fr(0) due to the default initialization of hints
read_request_membership_witnesses[0].is_transient = true;

auto& previous_kernel = private_inputs_inner.previous_kernel;
Expand All @@ -58,7 +61,7 @@ TEST_F(native_private_kernel_ordering_tests, native_matching_one_read_request_to
previous_kernel.public_inputs.end.new_commitments = siloed_commitments;
previous_kernel.public_inputs.end.read_requests = read_requests;

PrivateKernelInputsOrdering<NT> private_inputs{ previous_kernel, std::array<fr, MAX_READ_REQUESTS_PER_TX>{} };
PrivateKernelInputsOrdering<NT> private_inputs{ previous_kernel, hints };

DummyBuilder builder =
DummyBuilder("native_private_kernel_ordering_tests__native_matching_one_read_request_to_commitment_works");
Expand All @@ -77,6 +80,8 @@ TEST_F(native_private_kernel_ordering_tests, native_matching_some_read_requests_
std::array<fr, MAX_NEW_COMMITMENTS_PER_TX> siloed_commitments{};
std::array<fr, MAX_NEW_COMMITMENTS_PER_TX> unique_siloed_commitments{};
std::array<fr, MAX_READ_REQUESTS_PER_TX> read_requests{};
std::array<fr, MAX_READ_REQUESTS_PER_TX> hints{};

std::array<ReadRequestMembershipWitness<NT, PRIVATE_DATA_TREE_HEIGHT>, MAX_READ_REQUESTS_PER_TX>
read_request_membership_witnesses{};

Expand All @@ -96,14 +101,16 @@ TEST_F(native_private_kernel_ordering_tests, native_matching_some_read_requests_
read_requests[1] = siloed_commitments[3];
read_request_membership_witnesses[0].is_transient = true;
read_request_membership_witnesses[1].is_transient = true;
hints[0] = fr(1);
hints[1] = fr(3);

auto& previous_kernel = private_inputs_inner.previous_kernel;

previous_kernel.public_inputs.end.new_nullifiers = new_nullifiers;
previous_kernel.public_inputs.end.new_commitments = siloed_commitments;
previous_kernel.public_inputs.end.read_requests = read_requests;

PrivateKernelInputsOrdering<NT> private_inputs{ previous_kernel, std::array<fr, MAX_READ_REQUESTS_PER_TX>{} };
PrivateKernelInputsOrdering<NT> private_inputs{ previous_kernel, hints };

DummyBuilder builder =
DummyBuilder("native_private_kernel_ordering_tests__native_matching_some_read_requests_to_commitments_works");
Expand All @@ -123,13 +130,14 @@ TEST_F(native_private_kernel_ordering_tests, native_read_request_unknown_fails)

std::array<fr, MAX_NEW_COMMITMENTS_PER_TX> siloed_commitments{};
std::array<fr, MAX_READ_REQUESTS_PER_TX> read_requests{};
std::array<fr, MAX_READ_REQUESTS_PER_TX> hints{};
std::array<ReadRequestMembershipWitness<NT, PRIVATE_DATA_TREE_HEIGHT>, MAX_READ_REQUESTS_PER_TX>
read_request_membership_witnesses{};

for (size_t c_idx = 0; c_idx < MAX_NEW_COMMITMENTS_PER_TX; c_idx++) {
siloed_commitments[c_idx] = NT::fr::random_element(); // create random commitment
read_requests[c_idx] = siloed_commitments[c_idx]; // create random read requests
// ^ will match each other!
siloed_commitments[c_idx] = NT::fr::random_element(); // create random commitment
read_requests[c_idx] = siloed_commitments[c_idx]; // create random read requests
hints[c_idx] = fr(c_idx); // ^ will match each other!
read_request_membership_witnesses[c_idx].is_transient = true; // ordering circuit only allows transient reads
}
read_requests[3] = NT::fr::random_element(); // force one read request not to match
Expand All @@ -139,7 +147,7 @@ TEST_F(native_private_kernel_ordering_tests, native_read_request_unknown_fails)
previous_kernel.public_inputs.end.new_commitments = siloed_commitments;
previous_kernel.public_inputs.end.read_requests = read_requests;

PrivateKernelInputsOrdering<NT> private_inputs{ previous_kernel, std::array<fr, MAX_READ_REQUESTS_PER_TX>{} };
PrivateKernelInputsOrdering<NT> private_inputs{ previous_kernel, hints };

DummyBuilder builder = DummyBuilder("native_private_kernel_ordering_tests__native_read_request_unknown_fails");
native_private_kernel_circuit_ordering(builder, private_inputs);
Expand Down
29 changes: 25 additions & 4 deletions yarn-project/aztec-rpc/src/kernel_prover/kernel_prover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
AztecAddress,
CONTRACT_TREE_HEIGHT,
Fr,
MAX_NEW_COMMITMENTS_PER_TX,
MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL,
MAX_READ_REQUESTS_PER_CALL,
MAX_READ_REQUESTS_PER_TX,
Expand All @@ -19,7 +20,7 @@ import {
makeEmptyProof,
makeTuple,
} from '@aztec/circuits.js';
import { assertLength } from '@aztec/foundation/serialize';
import { Tuple, assertLength } from '@aztec/foundation/serialize';

import { KernelProofCreator, ProofCreator, ProofOutput, ProofOutputFinal } from './proof_creator.js';
import { ProvingDataOracle } from './proving_data_oracle.js';
Expand Down Expand Up @@ -85,9 +86,6 @@ export class KernelProver {
proof: makeEmptyProof(),
};

//TODO(#892): Dealing with this ticket we will fill the following hint array with the correct hints.
const hintToCommitments = makeTuple(MAX_READ_REQUESTS_PER_TX, Fr.zero);

while (executionStack.length) {
const currentExecution = executionStack.pop()!;
executionStack.push(...currentExecution.nestedExecutions);
Expand Down Expand Up @@ -169,6 +167,10 @@ export class KernelProver {
assertLength<Fr, typeof VK_TREE_HEIGHT>(previousVkMembershipWitness.siblingPath, VK_TREE_HEIGHT),
);

const hintToCommitments = this.getReadRequestHints(
output.publicInputs.end.readRequests,
output.publicInputs.end.newCommitments,
);
const privateInputs = new PrivateKernelInputsOrdering(previousKernelData, hintToCommitments);
const outputFinal = await this.proofCreator.createProofOrdering(privateInputs);

Expand Down Expand Up @@ -239,4 +241,23 @@ export class KernelProver {
commitment: newCommitments[i],
}));
}

private getReadRequestHints(
readRequests: Tuple<Fr, typeof MAX_READ_REQUESTS_PER_TX>,
commitments: Tuple<Fr, typeof MAX_NEW_COMMITMENTS_PER_TX>,
): Tuple<Fr, typeof MAX_READ_REQUESTS_PER_TX> {
const hints = makeTuple(MAX_READ_REQUESTS_PER_TX, Fr.zero);
for (let i = 0; i < MAX_READ_REQUESTS_PER_TX && !readRequests[i].isZero(); i++) {
const equalToRR = (cmt: Fr) => cmt.equals(readRequests[i]);
const result = commitments.findIndex(equalToRR);
if (result == -1) {
throw new Error(
`The read request at index ${i} with value ${readRequests[i].toString()} does not match to any commitment.`,
);
} else {
hints[i] = new Fr(result);
}
}
return hints;
}
}

0 comments on commit 0955bb7

Please sign in to comment.