Skip to content

Commit

Permalink
feat: Sync from noir (#12022)
Browse files Browse the repository at this point in the history
Automated pull of development from the
[noir](https://github.com/noir-lang/noir) programming language, a
dependency of Aztec.
BEGIN_COMMIT_OVERRIDE
fix: format global attributes
(noir-lang/noir#7401)
chore: box `Closure` in `comptime::Value` enum
(noir-lang/noir#7400)
chore: allow opting in to displaying benchmark comments
(noir-lang/noir#7399)
chore: box `ExprValue` in `Value` enum
(noir-lang/noir#7388)
chore: pull out refactored methods from u128 branch
(noir-lang/noir#7385)
feat: require safety comments instead of safety doc comments
(noir-lang/noir#7295)
END_COMMIT_OVERRIDE

---------

Co-authored-by: Tom French <[email protected]>
  • Loading branch information
AztecBot and TomAFrench authored Feb 17, 2025
1 parent 0c9b274 commit ef462bb
Show file tree
Hide file tree
Showing 175 changed files with 885 additions and 557 deletions.
2 changes: 1 addition & 1 deletion .noir-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
38eeee39a98a62747dcca3b31b409151761d4ef1
b7ace682af1ab8a43308457302f08b151af342db
38 changes: 19 additions & 19 deletions noir-projects/aztec-nr/aztec/src/context/private_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,8 @@ impl PrivateContext {
// validate that we siloed secret key corresponds to correct siloing of the master secret key that hashes
// to `pk_m_hash`.

/// Safety: Kernels verify that the key validation request is valid and below we verify that a request
/// for the correct public key has been received.
// Safety: Kernels verify that the key validation request is valid and below we verify that a request
// for the correct public key has been received.
let request = unsafe { get_key_validation_request(pk_m_hash, key_index) };
assert_eq(request.pk_m.hash(), pk_m_hash, "Obtained invalid key validation request");

Expand Down Expand Up @@ -391,11 +391,11 @@ impl PrivateContext {
let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;
let start_side_effect_counter = self.side_effect_counter;

/// Safety: The oracle simulates the private call and returns the value of the side effects counter after
/// execution of the call (which means that end_side_effect_counter - start_side_effect_counter is
/// the number of side effects that took place), along with the hash of the return values. We validate these
/// by requesting a private kernel iteration in which the return values are constrained to hash
/// to `returns_hash` and the side effects counter to increment from start to end.
// Safety: The oracle simulates the private call and returns the value of the side effects counter after
// execution of the call (which means that end_side_effect_counter - start_side_effect_counter is
// the number of side effects that took place), along with the hash of the return values. We validate these
// by requesting a private kernel iteration in which the return values are constrained to hash
// to `returns_hash` and the side effects counter to increment from start to end.
let (end_side_effect_counter, returns_hash) = unsafe {
call_private_function_internal(
contract_address,
Expand Down Expand Up @@ -494,12 +494,12 @@ impl PrivateContext {
let counter = self.next_counter();

let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;
/// Safety: TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.
/// WARNING: This is insecure and should be temporary!
/// The oracle hashes the arguments and returns a new args_hash.
/// new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.
/// We don't validate or compute it in the circuit because a) it's harder to do with slices, and
/// b) this is only temporary.
// Safety: TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.
// WARNING: This is insecure and should be temporary!
// The oracle hashes the arguments and returns a new args_hash.
// new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.
// We don't validate or compute it in the circuit because a) it's harder to do with slices, and
// b) this is only temporary.
let args_hash = unsafe {
enqueue_public_function_call_internal(
contract_address,
Expand Down Expand Up @@ -550,12 +550,12 @@ impl PrivateContext {
let counter = self.next_counter();

let mut is_static_call = is_static_call | self.inputs.call_context.is_static_call;
/// Safety: TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.
/// WARNING: This is insecure and should be temporary!
/// The oracle hashes the arguments and returns a new args_hash.
/// new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.
/// We don't validate or compute it in the circuit because a) it's harder to do with slices, and
/// b) this is only temporary.
// Safety: TODO(https://github.com/AztecProtocol/aztec-packages/issues/8985): Fix this.
// WARNING: This is insecure and should be temporary!
// The oracle hashes the arguments and returns a new args_hash.
// new_args = [selector, ...old_args], so as to make it suitable to call the public dispatch function.
// We don't validate or compute it in the circuit because a) it's harder to do with slices, and
// b) this is only temporary.
let args_hash = unsafe {
set_public_teardown_function_call_internal(
contract_address,
Expand Down
44 changes: 22 additions & 22 deletions noir-projects/aztec-nr/aztec/src/context/public_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,22 @@ impl PublicContext {
where
T: Serialize<N>,
{
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe { emit_public_log(Serialize::serialize(log).as_slice()) };
}

pub fn note_hash_exists(_self: Self, note_hash: Field, leaf_index: Field) -> bool {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe { note_hash_exists(note_hash, leaf_index) } == 1
}

pub fn l1_to_l2_msg_exists(_self: Self, msg_hash: Field, msg_leaf_index: Field) -> bool {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe { l1_to_l2_msg_exists(msg_hash, msg_leaf_index) } == 1
}

pub fn nullifier_exists(_self: Self, unsiloed_nullifier: Field, address: AztecAddress) -> bool {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe { nullifier_exists(unsiloed_nullifier, address.to_field()) } == 1
}

Expand Down Expand Up @@ -73,7 +73,7 @@ impl PublicContext {
}

pub fn message_portal(_self: &mut Self, recipient: EthAddress, content: Field) {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe { send_l2_to_l1_msg(recipient, content) };
}

Expand Down Expand Up @@ -114,29 +114,29 @@ impl PublicContext {
}

pub fn push_note_hash(_self: &mut Self, note_hash: Field) {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe { emit_note_hash(note_hash) };
}
pub fn push_nullifier(_self: &mut Self, nullifier: Field) {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe { emit_nullifier(nullifier) };
}

pub fn this_address(_self: Self) -> AztecAddress {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe {
address()
}
}
pub fn msg_sender(_self: Self) -> AztecAddress {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe {
sender()
}
}
pub fn selector(_self: Self) -> FunctionSelector {
// The selector is the first element of the calldata when calling a public function through dispatch.
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
let raw_selector: [Field; 1] = unsafe { calldata_copy(0, 1) };
FunctionSelector::from_field(raw_selector[0])
}
Expand All @@ -148,70 +148,70 @@ impl PublicContext {
self.args_hash.unwrap_unchecked()
}
pub fn transaction_fee(_self: Self) -> Field {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe {
transaction_fee()
}
}

pub fn chain_id(_self: Self) -> Field {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe {
chain_id()
}
}
pub fn version(_self: Self) -> Field {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe {
version()
}
}
pub fn block_number(_self: Self) -> Field {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe {
block_number()
}
}
pub fn timestamp(_self: Self) -> u64 {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe {
timestamp()
}
}
pub fn fee_per_l2_gas(_self: Self) -> Field {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe {
fee_per_l2_gas()
}
}
pub fn fee_per_da_gas(_self: Self) -> Field {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe {
fee_per_da_gas()
}
}

pub fn l2_gas_left(_self: Self) -> Field {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe {
l2_gas_left()
}
}
pub fn da_gas_left(_self: Self) -> Field {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe {
da_gas_left()
}
}
pub fn is_static_call(_self: Self) -> bool {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe { is_static_call() } == 1
}

pub fn raw_storage_read<let N: u32>(_self: Self, storage_slot: Field) -> [Field; N] {
let mut out = [0; N];
for i in 0..N {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
out[i] = unsafe { storage_read(storage_slot + i as Field) };
}
out
Expand All @@ -226,7 +226,7 @@ impl PublicContext {

pub fn raw_storage_write<let N: u32>(_self: Self, storage_slot: Field, values: [Field; N]) {
for i in 0..N {
/// Safety: AVM opcodes are constrained by the AVM itself
// Safety: AVM opcodes are constrained by the AVM itself
unsafe { storage_write(storage_slot + i as Field, values[i]) };
}
}
Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/context/returns_hash.nr
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl ReturnsHash {
where
T: Deserialize<N>,
{
/// Safety: We verify that the value returned by `load` is the preimage of `hash`, fully constraining it.
// Safety: We verify that the value returned by `load` is the preimage of `hash`, fully constraining it.
let preimage: [Field; N] = unsafe { execution_cache::load(self.hash) };
assert_eq(self.hash, hash_args_array(preimage));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,8 @@ where

let mut log_bytes_padding_to_mult_31 =
get_arr_of_size__log_bytes_padding__from_PT::<(N * 32) + 64>();
/// Safety: this randomness won't be constrained to be random. It's in the
/// interest of the executor of this fn to encrypt with random bytes.
// Safety: this randomness won't be constrained to be random. It's in the
// interest of the executor of this fn to encrypt with random bytes.
log_bytes_padding_to_mult_31 = unsafe { get_random_bytes() };

let mut log_bytes = get_arr_of_size__log_bytes__from_PT::<(N * 32) + 64>();
Expand Down Expand Up @@ -406,7 +406,7 @@ where
offset += log_bytes_as_fields.len();

for i in offset..PRIVATE_LOG_SIZE_IN_FIELDS {
/// Safety: randomness cannot be constrained.
// Safety: randomness cannot be constrained.
final_log[i] = unsafe { random() };
}

Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/history/note_inclusion.nr
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ impl ProveNoteInclusion for BlockHeader {
{
let note_hash = compute_note_hash_for_nullify(note, storage_slot);

/// Safety: The witness is only used as a "magical value" that makes the merkle proof below pass. Hence it's safe.
// Safety: The witness is only used as a "magical value" that makes the merkle proof below pass. Hence it's safe.
let witness = unsafe {
get_note_hash_membership_witness(self.global_variables.block_number as u32, note_hash)
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ trait ProveNullifierInclusion {
impl ProveNullifierInclusion for BlockHeader {
fn prove_nullifier_inclusion(self, nullifier: Field) {
// 1) Get the membership witness of the nullifier
/// Safety: The witness is only used as a "magical value" that makes the proof below pass. Hence it's safe.
// Safety: The witness is only used as a "magical value" that makes the proof below pass. Hence it's safe.
let witness = unsafe {
get_nullifier_membership_witness(self.global_variables.block_number as u32, nullifier)
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ trait ProveNullifierNonInclusion {
impl ProveNullifierNonInclusion for BlockHeader {
fn prove_nullifier_non_inclusion(self, nullifier: Field) {
// 1) Get the membership witness of a low nullifier of the nullifier
/// Safety: The witness is only used as a "magical value" that makes the proof below pass. Hence it's safe.
// Safety: The witness is only used as a "magical value" that makes the proof below pass. Hence it's safe.
let witness = unsafe {
get_low_nullifier_membership_witness(
self.global_variables.block_number as u32,
Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/history/public_storage.nr
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl PublicStorageHistoricalRead for BlockHeader {
);

// 2) Get the membership witness for the tree index.
/// Safety: The witness is only used as a "magical value" that makes the proof below pass. Hence it's safe.
// Safety: The witness is only used as a "magical value" that makes the proof below pass. Hence it's safe.
let witness = unsafe {
get_public_data_witness(
self.global_variables.block_number as u32,
Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub unconstrained fn get_ovsk_app(ovpk_m_hash: Field) -> Field {
// keys at once since the constraints for reading them all are actually fewer than if we read them one at a time - any
// read keys that are not required by the caller can simply be discarded.
pub fn get_public_keys(account: AztecAddress) -> PublicKeys {
/// Safety: Public keys are constrained by showing their inclusion in the address's preimage.
// Safety: Public keys are constrained by showing their inclusion in the address's preimage.
let (public_keys, partial_address) = unsafe { get_public_keys_and_partial_address(account) };
assert_eq(
account,
Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/messaging.nr
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub fn process_l1_to_l2_message(

// We prove that `message_hash` is in the tree by showing the derivation of the tree root, using a merkle path we
// get from an oracle.
/// Safety: The witness is only used as a "magical value" that makes the merkle proof below pass. Hence it's safe.
// Safety: The witness is only used as a "magical value" that makes the merkle proof below pass. Hence it's safe.
let (_leaf_index, sibling_path) =
unsafe { get_l1_to_l2_membership_witness(contract_address, message_hash, secret) };

Expand Down
6 changes: 3 additions & 3 deletions noir-projects/aztec-nr/aztec/src/note/note_getter/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ pub fn get_note<Note, let N: u32>(
where
Note: NoteInterface<N> + NullifiableNote,
{
/// Safety: Constraining that we got a valid note from the oracle is fairly straightforward: all we need to do
/// is check that the metadata is correct, and that the note exists.
// Safety: Constraining that we got a valid note from the oracle is fairly straightforward: all we need to do
// is check that the metadata is correct, and that the note exists.
let note = unsafe { get_note_internal(storage_slot) };
check_note_header(*context, note);

Expand All @@ -107,7 +107,7 @@ pub fn get_notes<Note, let N: u32, PREPROCESSOR_ARGS, FILTER_ARGS>(
where
Note: NoteInterface<N> + NullifiableNote + Eq,
{
/// Safety: The notes are constrained below.
// Safety: The notes are constrained below.
let opt_notes = unsafe { get_notes_internal(storage_slot, options) };

// We apply the constraints in a separate function instead of inlining them here to make it easier to test that
Expand Down
4 changes: 2 additions & 2 deletions noir-projects/aztec-nr/aztec/src/oracle/block_header.nr
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn get_block_header_at(block_number: u32, context: PrivateContext) -> BlockH
);

// 3) Get the header hint of a given block from an oracle
/// Safety: The header is constrained to be in the archive tree below.
// Safety: The header is constrained to be in the archive tree below.
let header = unsafe { get_block_header_at_internal(block_number) };

// 4) We make sure that the header hint we received from the oracle exists in the state tree and is the actual header
Expand All @@ -62,7 +62,7 @@ fn constrain_get_block_header_at_internal(
let block_hash = header_hint.hash();

// 2) Get the membership witness of the block in the archive tree
/// Safety: The witness is only used as a "magical value" that makes the merkle proof below pass. Hence it's safe.
// Safety: The witness is only used as a "magical value" that makes the merkle proof below pass. Hence it's safe.
let witness = unsafe { get_archive_membership_witness(last_archive_block_number, block_hash) };

// 3) Check that the block is in the archive (i.e. the witness is valid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ pub unconstrained fn set_public_teardown_function_call_internal(
}

pub fn notify_set_min_revertible_side_effect_counter(counter: u32) {
/// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe
/// to call.
// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe
// to call.
unsafe { notify_set_min_revertible_side_effect_counter_oracle_wrapper(counter) };
}

Expand Down
4 changes: 2 additions & 2 deletions noir-projects/aztec-nr/aztec/src/oracle/execution_cache.nr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/// Stores values represented as slice in execution cache to be later obtained by its hash.
pub fn store(values: [Field]) {
/// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe
/// to call. When loading the values, however, the caller must check that the values are indeed the preimage.
// Safety: This oracle call returns nothing: we only call it for its side effects. It is therefore always safe
// to call. When loading the values, however, the caller must check that the values are indeed the preimage.
unsafe { store_in_execution_cache_oracle_wrapper(values) };
}

Expand Down
Loading

0 comments on commit ef462bb

Please sign in to comment.