Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: siloing in tails #6167

Merged
merged 15 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,18 @@ library Constants {
uint256 internal constant GLOBAL_VARIABLES_LENGTH = 6 + GAS_FEES_LENGTH;
uint256 internal constant APPEND_ONLY_TREE_SNAPSHOT_LENGTH = 2;
uint256 internal constant L1_TO_L2_MESSAGE_LENGTH = 6;
uint256 internal constant L2_TO_L1_MESSAGE_LENGTH = 2;
uint256 internal constant L2_TO_L1_MESSAGE_LENGTH = 3;
uint256 internal constant SCOPED_L2_TO_L1_MESSAGE_LENGTH = L2_TO_L1_MESSAGE_LENGTH + 1;
uint256 internal constant MAX_BLOCK_NUMBER_LENGTH = 2;
uint256 internal constant NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH = 3;
uint256 internal constant NULLIFIER_KEY_VALIDATION_REQUEST_CONTEXT_LENGTH = 4;
uint256 internal constant SCOPED_NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH =
NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH + 1;
uint256 internal constant PARTIAL_STATE_REFERENCE_LENGTH = 6;
uint256 internal constant READ_REQUEST_LENGTH = 2;
uint256 internal constant NOTE_HASH_LENGTH = 2;
uint256 internal constant NOTE_HASH_CONTEXT_LENGTH = 3;
uint256 internal constant SCOPED_NOTE_HASH_LENGTH = NOTE_HASH_LENGTH + 2;
uint256 internal constant NULLIFIER_LENGTH = 3;
uint256 internal constant SCOPED_NULLIFIER_LENGTH = NULLIFIER_LENGTH + 1;
uint256 internal constant SIDE_EFFECT_LENGTH = 2;
uint256 internal constant STATE_REFERENCE_LENGTH =
APPEND_ONLY_TREE_SNAPSHOT_LENGTH + PARTIAL_STATE_REFERENCE_LENGTH;
Expand Down
35 changes: 18 additions & 17 deletions noir-projects/aztec-nr/aztec/src/context/private_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,11 @@ impl ContextInterface for PrivateContext {
}

fn push_new_note_hash(&mut self, note_hash: Field) {
self.new_note_hashes.push(NoteHash { value: note_hash, counter: self.side_effect_counter });
self.side_effect_counter = self.side_effect_counter + 1;
self.new_note_hashes.push(NoteHash { value: note_hash, counter: self.next_counter() });
}

fn push_new_nullifier(&mut self, nullifier: Field, nullified_note_hash: Field) {
self.new_nullifiers.push(Nullifier { value: nullifier, note_hash: nullified_note_hash, counter: self.side_effect_counter });
self.side_effect_counter = self.side_effect_counter + 1;
self.new_nullifiers.push(Nullifier { value: nullifier, note_hash: nullified_note_hash, counter: self.next_counter() });
}
}

Expand Down Expand Up @@ -193,15 +191,13 @@ impl PrivateContext {
}

pub fn push_note_hash_read_request(&mut self, note_hash: Field) {
let side_effect = ReadRequest { value: note_hash, counter: self.side_effect_counter };
let side_effect = ReadRequest { value: note_hash, counter: self.next_counter() };
self.note_hash_read_requests.push(side_effect);
self.side_effect_counter = self.side_effect_counter + 1;
}

pub fn push_nullifier_read_request(&mut self, nullifier: Field) {
let request = ReadRequest { value: nullifier, counter: self.side_effect_counter };
let request = ReadRequest { value: nullifier, counter: self.next_counter() };
self.nullifier_read_requests.push(request);
self.side_effect_counter = self.side_effect_counter + 1;
}

pub fn request_app_nullifier_secret_key(&mut self, account: AztecAddress) -> Field {
Expand All @@ -227,7 +223,7 @@ impl PrivateContext {
// docs:start:context_message_portal
pub fn message_portal(&mut self, recipient: EthAddress, content: Field) {
// docs:end:context_message_portal
let message = L2ToL1Message { recipient, content };
let message = L2ToL1Message { recipient, content, counter: self.next_counter() };
self.new_l2_to_l1_msgs.push(message);
}

Expand Down Expand Up @@ -259,9 +255,8 @@ impl PrivateContext {
let contract_address = self.this_address();
let log_slice = log.to_be_bytes_arr();
let log_hash = compute_unencrypted_log_hash(contract_address, event_selector, log);
let side_effect = SideEffect { value: log_hash, counter: self.side_effect_counter };
let side_effect = SideEffect { value: log_hash, counter: self.next_counter() };
self.unencrypted_logs_hashes.push(side_effect);
self.side_effect_counter = self.side_effect_counter + 1;
// 44 = addr (32) + selector (4) + raw log len (4) + processed log len (4)
self.unencrypted_log_preimages_length += 44 + log_slice.len().to_field();
// call oracle
Expand All @@ -278,10 +273,10 @@ impl PrivateContext {
pub fn emit_contract_class_unencrypted_log<N>(&mut self, log: [Field; N]) {
let event_selector = 5; // TODO: compute actual event selector.
let contract_address = self.this_address();
let log_hash = emit_contract_class_unencrypted_log_private_internal(contract_address, event_selector, log, self.side_effect_counter);
let side_effect = SideEffect { value: log_hash, counter: self.side_effect_counter };
let counter = self.next_counter();
let log_hash = emit_contract_class_unencrypted_log_private_internal(contract_address, event_selector, log, counter);
let side_effect = SideEffect { value: log_hash, counter };
self.unencrypted_logs_hashes.push(side_effect);
self.side_effect_counter = self.side_effect_counter + 1;
// 44 = addr (32) + selector (4) + raw log len (4) + processed log len (4)
self.unencrypted_log_preimages_length += 44 + N*32;
}
Expand All @@ -296,18 +291,18 @@ impl PrivateContext {
) where [Field; N]: LensForEncryptedLog<N, M, L> {
// TODO(1139): perform encryption in the circuit
// The oracle call should come last, but we require the encrypted value for now
let counter = self.next_counter();
let encrypted_log: [Field; M] = emit_encrypted_log(
contract_address,
storage_slot,
note_type_id,
encryption_pub_key,
preimage,
self.side_effect_counter
counter
);
let log_hash = compute_encrypted_log_hash(encrypted_log);
let side_effect = SideEffect { value: log_hash, counter: self.side_effect_counter };
let side_effect = SideEffect { value: log_hash, counter };
self.encrypted_logs_hashes.push(side_effect);
self.side_effect_counter = self.side_effect_counter + 1;
let encrypted_log_byte_len = 112 + 32 * (N + 3);
// + processed log len (4)
self.encrypted_log_preimages_length += encrypted_log_byte_len + 4;
Expand Down Expand Up @@ -600,6 +595,12 @@ impl PrivateContext {
);
}
}

fn next_counter(&mut self) -> u32 {
let counter = self.side_effect_counter;
self.side_effect_counter += 1;
counter
}
}

impl Empty for PrivateContext {
Expand Down
23 changes: 12 additions & 11 deletions noir-projects/aztec-nr/aztec/src/context/public_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,14 @@ impl PublicContext {

// Keep private or ask the AVM team if you want to change it.
fn push_nullifier_read_request(&mut self, nullifier: Field) {
let request = ReadRequest { value: nullifier, counter: self.side_effect_counter };
let request = ReadRequest { value: nullifier, counter: self.next_counter() };
self.nullifier_read_requests.push(request);
self.side_effect_counter = self.side_effect_counter + 1;
}

// Keep private or ask the AVM team if you want to change it.
fn push_nullifier_non_existent_read_request(&mut self, nullifier: Field) {
let request = ReadRequest { value: nullifier, counter: self.side_effect_counter };
let request = ReadRequest { value: nullifier, counter: self.next_counter() };
self.nullifier_non_existent_read_requests.push(request);
self.side_effect_counter = self.side_effect_counter + 1;
}

pub fn finish(self) -> PublicCircuitPublicInputs {
Expand Down Expand Up @@ -171,6 +169,12 @@ impl PublicContext {
};
pub_circuit_pub_inputs
}

fn next_counter(&mut self) -> u32 {
let counter = self.side_effect_counter;
self.side_effect_counter += 1;
counter
}
}

impl ContextInterface for PublicContext {
Expand Down Expand Up @@ -199,17 +203,15 @@ impl ContextInterface for PublicContext {
}

fn push_new_note_hash(&mut self, note_hash: Field) {
self.new_note_hashes.push(NoteHash { value: note_hash, counter: self.side_effect_counter });
self.side_effect_counter = self.side_effect_counter + 1;
self.new_note_hashes.push(NoteHash { value: note_hash, counter: self.next_counter() });
}

fn push_new_nullifier(&mut self, nullifier: Field, _nullified_note_hash: Field) {
self.new_nullifiers.push(Nullifier {
value: nullifier,
note_hash: 0, // cannot nullify pending notes in public context
counter: self.side_effect_counter
counter: self.next_counter()
});
self.side_effect_counter = self.side_effect_counter + 1;
}
}

Expand Down Expand Up @@ -249,7 +251,7 @@ impl PublicContextInterface for PublicContext {
}

fn message_portal(&mut self, recipient: EthAddress, content: Field) {
let message = L2ToL1Message { recipient, content };
let message = L2ToL1Message { recipient, content, counter: self.next_counter() };
self.new_l2_to_l1_msgs.push(message);
}

Expand Down Expand Up @@ -281,9 +283,8 @@ impl PublicContextInterface for PublicContext {
event_selector,
log
);
let side_effect = SideEffect { value: log_hash, counter: self.side_effect_counter };
let side_effect = SideEffect { value: log_hash, counter: self.next_counter() };
self.unencrypted_logs_hashes.push(side_effect);
self.side_effect_counter = self.side_effect_counter + 1;
// 44 = addr (32) + selector (4) + raw log len (4) + processed log len (4)
self.unencrypted_log_preimages_length = self.unencrypted_log_preimages_length + 44 + log_slice.len().to_field();
// Call oracle to broadcast log
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ fn contract_logic(private_call: PrivateCallData) {
}

pub fn validate_previous_kernel_values(end: PrivateAccumulatedData) {
assert(end.new_nullifiers[0].value != 0, "The 0th nullifier in the accumulated nullifier array is zero");
assert(
end.new_nullifiers[0].value() != 0, "The 0th nullifier in the accumulated nullifier array is zero"
);
}

pub fn validate_call_against_request(private_call: PrivateCallData, request: CallRequest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ use dep::types::{
abis::{
kernel_data::PrivateKernelData,
kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsBuilder, PublicKernelCircuitPublicInputs},
note_hash::NoteHashContext, nullifier::Nullifier, side_effect::{SideEffect, Ordered}, gas::Gas
note_hash::ScopedNoteHash, nullifier::ScopedNullifier, side_effect::{SideEffect, Ordered}, gas::Gas
},
constants::{
MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_ENCRYPTED_LOGS_PER_TX,
MAX_UNENCRYPTED_LOGS_PER_TX
},
hash::{compute_note_hash_nonce, compute_unique_siloed_note_hash},
hash::{
compute_l2_to_l1_hash, compute_note_hash_nonce, compute_unique_siloed_note_hash, silo_note_hash,
silo_nullifier
},
utils::arrays::{array_length, array_to_bounded_vec, assert_sorted_array}
};

Expand All @@ -24,14 +27,14 @@ struct KernelCircuitPublicInputsComposer {
public_inputs: PrivateKernelCircuitPublicInputsBuilder,
previous_kernel: PrivateKernelData,
// Final data
note_hashes: [NoteHashContext; MAX_NEW_NOTE_HASHES_PER_TX],
nullifiers: [Nullifier; MAX_NEW_NULLIFIERS_PER_TX],
note_hashes: [ScopedNoteHash; MAX_NEW_NOTE_HASHES_PER_TX],
nullifiers: [ScopedNullifier; MAX_NEW_NULLIFIERS_PER_TX],
// Hints
transient_nullifier_indexes_for_note_hashes: [u64; MAX_NEW_NOTE_HASHES_PER_TX],
transient_note_hash_indexes_for_nullifiers: [u64; MAX_NEW_NULLIFIERS_PER_TX],
sorted_note_hashes: [NoteHashContext; MAX_NEW_NOTE_HASHES_PER_TX],
sorted_note_hashes: [ScopedNoteHash; MAX_NEW_NOTE_HASHES_PER_TX],
sorted_note_hashes_indexes: [u64; MAX_NEW_NOTE_HASHES_PER_TX],
sorted_nullifiers: [Nullifier; MAX_NEW_NULLIFIERS_PER_TX],
sorted_nullifiers: [ScopedNullifier; MAX_NEW_NULLIFIERS_PER_TX],
sorted_nullifiers_indexes: [u64; MAX_NEW_NULLIFIERS_PER_TX],
sorted_encrypted_log_hashes: [SideEffect; MAX_ENCRYPTED_LOGS_PER_TX],
sorted_encrypted_log_hashes_indexes: [u64; MAX_ENCRYPTED_LOGS_PER_TX],
Expand All @@ -42,13 +45,13 @@ struct KernelCircuitPublicInputsComposer {
impl KernelCircuitPublicInputsComposer {
pub fn new(
previous_kernel: PrivateKernelData,
note_hashes: [NoteHashContext; MAX_NEW_NOTE_HASHES_PER_TX],
nullifiers: [Nullifier; MAX_NEW_NULLIFIERS_PER_TX],
note_hashes: [ScopedNoteHash; MAX_NEW_NOTE_HASHES_PER_TX],
nullifiers: [ScopedNullifier; MAX_NEW_NULLIFIERS_PER_TX],
transient_nullifier_indexes_for_note_hashes: [u64; MAX_NEW_NOTE_HASHES_PER_TX],
transient_note_hash_indexes_for_nullifiers: [u64; MAX_NEW_NULLIFIERS_PER_TX],
sorted_note_hashes: [NoteHashContext; MAX_NEW_NOTE_HASHES_PER_TX],
sorted_note_hashes: [ScopedNoteHash; MAX_NEW_NOTE_HASHES_PER_TX],
sorted_note_hashes_indexes: [u64; MAX_NEW_NOTE_HASHES_PER_TX],
sorted_nullifiers: [Nullifier; MAX_NEW_NULLIFIERS_PER_TX],
sorted_nullifiers: [ScopedNullifier; MAX_NEW_NULLIFIERS_PER_TX],
sorted_nullifiers_indexes: [u64; MAX_NEW_NULLIFIERS_PER_TX],
sorted_encrypted_log_hashes: [SideEffect; MAX_ENCRYPTED_LOGS_PER_TX],
sorted_encrypted_log_hashes_indexes: [u64; MAX_ENCRYPTED_LOGS_PER_TX],
Expand Down Expand Up @@ -122,20 +125,50 @@ impl KernelCircuitPublicInputsComposer {

fn silo_values(&mut self) {
self.silo_note_hashes();
// TODO: Move siloing from init/inner circuits to here.
self.silo_nullifiers();
self.silo_l2_to_l1_messages();
}

fn silo_note_hashes(&mut self) {
let first_nullifier = self.public_inputs.end.new_nullifiers.get_unchecked(0);
assert(first_nullifier.value != 0, "The 0th nullifier in the accumulated nullifier array is zero");
let first_nullifier = self.public_inputs.end.new_nullifiers.get_unchecked(0).value();
assert(first_nullifier != 0, "The 0th nullifier in the accumulated nullifier array is zero");

let note_hashes = self.public_inputs.end.new_note_hashes.storage;
for i in 0..MAX_NEW_NOTE_HASHES_PER_TX {
let note_hash = note_hashes[i];
if note_hash.value != 0 {
let nonce = compute_note_hash_nonce(first_nullifier.value, i);
let unique_note_hash = compute_unique_siloed_note_hash(nonce, note_hash.value);
self.public_inputs.end.new_note_hashes.storage[i].value = unique_note_hash;
if note_hash.value() != 0 {
let siloed = silo_note_hash(note_hash.contract_address, note_hash.value());
let nonce = compute_note_hash_nonce(first_nullifier, i);
let unique_note_hash = compute_unique_siloed_note_hash(nonce, siloed);
self.public_inputs.end.new_note_hashes.storage[i].note_hash.value = unique_note_hash;
}
}
}

fn silo_nullifiers(&mut self) {
let nullifiers = self.public_inputs.end.new_nullifiers.storage;
for i in 1..MAX_NEW_NOTE_HASHES_PER_TX { // i starts from 1 to skip the first nullifier.
let nullifier = nullifiers[i];
if nullifier.value() != 0 {
let siloed = silo_nullifier(nullifier.contract_address, nullifier.value());
self.public_inputs.end.new_nullifiers.storage[i].nullifier.value = siloed;
}
}
}

fn silo_l2_to_l1_messages(&mut self) {
let l2_to_l1_msgs = self.public_inputs.end.new_l2_to_l1_msgs.storage;
let tx_context = self.previous_kernel.public_inputs.constants.tx_context;
for i in 0..l2_to_l1_msgs.len() {
let msg = l2_to_l1_msgs[i];
if !msg.contract_address.is_zero() {
let siloed = compute_l2_to_l1_hash(
msg.contract_address,
tx_context.version,
tx_context.chain_id,
msg.message
);
self.public_inputs.end.new_l2_to_l1_msgs.storage[i].message.content = siloed;
}
}
}
Expand Down Expand Up @@ -209,7 +242,7 @@ impl KernelCircuitPublicInputsComposer {
assert(self.note_hashes[i].nullifier_counter == 0, "Unresolved transient note hash");
}
for i in 0..self.nullifiers.len() {
assert(self.nullifiers[i].note_hash == 0, "Unresolved transient nullifier");
assert(self.nullifiers[i].nullified_note_hash() == 0, "Unresolved transient nullifier");
}

self.public_inputs.end.new_note_hashes = array_to_bounded_vec(self.note_hashes);
Expand Down
Loading
Loading