diff --git a/cspell.json b/cspell.json index 9acd495666a6..54f3a02b6bc0 100644 --- a/cspell.json +++ b/cspell.json @@ -11,8 +11,8 @@ "asyncify", "auditability", "authwit", - "authwits", "authwitness", + "authwits", "Automine", "autonat", "autorun", @@ -228,6 +228,7 @@ "Reserialize", "retag", "rethrown", + "revertibles", "rollup", "rollups", "rushstack", diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr index 5737775889ef..a5cbf9768809 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/private_kernel_data.nr @@ -24,6 +24,7 @@ impl PrivateKernelData { self.vk_index }; let index_hint = unsafe { + //@safety The index is checked to be in the allowed list below. find_index_hint(allowed_indices, |index: u32| index == index_in_allowed_list) }; assert(index_hint < N, "Invalid vk index"); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/debug_log.nr b/noir-projects/noir-protocol-circuits/crates/types/src/debug_log.nr index 706139c84090..666cb6363fb2 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/debug_log.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/debug_log.nr @@ -11,8 +11,11 @@ pub fn debug_log(msg: str) { /// debug_log_format("get_2(slot:{0}) =>\n\t0:{1}\n\t1:{2}", [storage_slot, note0_hash, note1_hash]); /// debug_log_format("whole array: {}", [e1, e2, e3, e4]); pub fn debug_log_format(msg: str, args: [Field; N]) { - // This oracle call returns nothing: we only call it for its side effects. It is therefore always safe to call. - unsafe { debug_log_oracle_wrapper(msg, args) }; + unsafe { + //@safety This oracle call returns nothing: we only call it for its side effects. It is therefore always safe + // to call. + debug_log_oracle_wrapper(msg, args) + }; } pub unconstrained fn debug_log_oracle_wrapper( diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/variable_merkle_tree.nr b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/variable_merkle_tree.nr index 701646552f29..2cd4c6aae97e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/variable_merkle_tree.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/variable_merkle_tree.nr @@ -33,7 +33,11 @@ impl VariableMerkleTree { // pub fn new_sha(leaves: [Field; N], num_non_empty_leaves: u32) -> Self { // Find size of tree required - let height = unsafe { get_height(num_non_empty_leaves, 0) }; + let height = unsafe { + //@safety This is safe because we derive next and previous powers of 2 below based on the value + // and the powers are then checked against the num non empty leaves. + get_height(num_non_empty_leaves, 0) + }; let next_power_2 = 2 << height; let prev_power_2 = next_power_2 / 2; assert( diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/proof/vk_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/proof/vk_data.nr index cede48d01a51..e401f688f203 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/proof/vk_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/proof/vk_data.nr @@ -14,8 +14,10 @@ impl VkData { pub fn validate_in_vk_tree(self, vk_tree_root: Field, allowed_indices: [u32; N]) { self.vk.check_hash(); - let index_hint = - unsafe { find_index_hint(allowed_indices, |index: u32| index == self.vk_index) }; + let index_hint = unsafe { + //@safety The index is checked to be in the allowed list below. + find_index_hint(allowed_indices, |index: u32| index == self.vk_index) + }; assert(index_hint < N, "Invalid vk index"); assert_eq(allowed_indices[index_hint], self.vk_index, "Invalid vk index"); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr index 3f3c91c38854..9bef13eca843 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr @@ -65,12 +65,14 @@ where BoundedVec::from_parts_unchecked(array, len) } +// Helper function to find the index of the first element in an array that satisfies a given predicate. pub unconstrained fn find_index_hint( array: [T; N], find: fn[Env](T) -> bool, ) -> u32 { let mut index = N; for i in 0..N { + // We check `index == N` to ensure that we only update the index if we haven't found a match yet. if (index == N) & find(array[i]) { index = i; } @@ -104,7 +106,11 @@ pub fn array_length(array: [T; N]) -> u32 where T: Empty + Eq, { - let length = unsafe { find_index_hint(array, |elem: T| is_empty(elem)) }; + // We get the length by checking the index of the first empty element. + let length = unsafe { + //@safety This is safe because we have validated the array and the element emptyness is checked below. + find_index_hint(array, |elem: T| is_empty(elem)) + }; if length != 0 { assert(!is_empty(array[length - 1])); } @@ -243,7 +249,10 @@ fn test_array_length_invalid_arrays() { fn find_index_greater_than_min() { let values = [10, 20, 30, 40]; let min = 22; - let index = unsafe { find_index_hint(values, |v: Field| min.lt(v)) }; + let index = unsafe { + //@safety The result is checked in the assert_eq below. + find_index_hint(values, |v: Field| min.lt(v)) + }; assert_eq(index, 2); } @@ -251,7 +260,10 @@ fn find_index_greater_than_min() { fn find_index_not_found() { let values = [10, 20, 30, 40]; let min = 100; - let index = unsafe { find_index_hint(values, |v: Field| min.lt(v)) }; + let index = unsafe { + //@safety The result is checked in the assert_eq below. + find_index_hint(values, |v: Field| min.lt(v)) + }; assert_eq(index, 4); } @@ -259,8 +271,8 @@ fn find_index_not_found() { fn test_array_concat() { let array0 = [1, 2, 3]; let array1 = [4, 5]; - let concated = array_concat(array0, array1); - assert_eq(concated, [1, 2, 3, 4, 5]); + let concatenated = array_concat(array0, array1); + assert_eq(concatenated, [1, 2, 3, 4, 5]); } #[test] diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_array.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_array.nr index f2ad12fd38ec..2c1acbc21ddb 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_array.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_array.nr @@ -91,8 +91,10 @@ mod tests { } pub fn check_and_execute(self) { - let combined = - unsafe { combine_arrays(self.original_array_lt, self.original_array_gte) }; + let combined = unsafe { + //@safety The value is checked against the combined array below. + combine_arrays(self.original_array_lt, self.original_array_gte) + }; assert_eq(combined, self.combined_array); self.execute(); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_transformed_array.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_transformed_array.nr index 082f33ebdd69..f41bb6a88123 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_transformed_array.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_combined_transformed_array.nr @@ -117,6 +117,7 @@ mod tests { pub fn check_and_execute(self) { let combined = unsafe { + //@safety The value is checked against the combined array below. combine_and_transform_arrays( self.original_array_lt, self.original_array_gte, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_exposed_sorted_transformed_value_array/get_order_hints.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_exposed_sorted_transformed_value_array/get_order_hints.nr index 25071de486de..6b46ceda13f9 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_exposed_sorted_transformed_value_array/get_order_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_exposed_sorted_transformed_value_array/get_order_hints.nr @@ -99,12 +99,18 @@ mod tests { impl TestBuilder { pub fn asc_to_equal(self, expected: [OrderHint; N]) { - let hints = unsafe { get_order_hints_asc(self.array) }; + let hints = unsafe { + //@safety The value is checked against expected below. + get_order_hints_asc(self.array) + }; assert_eq(hints, expected); } pub fn desc_to_equal(self, expected: [OrderHint; N]) { - let hints = unsafe { get_order_hints_desc(self.array) }; + let hints = unsafe { + //@safety The value is checked against expected below. + get_order_hints_desc(self.array) + }; assert_eq(hints, expected); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_sorted_transformed_value_arrays/get_split_order_hints.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_sorted_transformed_value_arrays/get_split_order_hints.nr index 25a2d44ed9ff..a427e5658123 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_sorted_transformed_value_arrays/get_split_order_hints.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_sorted_transformed_value_arrays/get_split_order_hints.nr @@ -132,12 +132,18 @@ mod tests { impl TestBuilder { pub fn asc_to_equal(self, expected: SplitOrderHints) { - let hints = unsafe { get_split_order_hints_asc(self.array, self.split_counter) }; + let hints = unsafe { + //@safety The value is checked against expected below. + get_split_order_hints_asc(self.array, self.split_counter) + }; assert_eq(hints, expected); } pub fn desc_to_equal(self, expected: SplitOrderHints) { - let hints = unsafe { get_split_order_hints_desc(self.array, self.split_counter) }; + let hints = unsafe { + //@safety The value is checked against expected below. + get_split_order_hints_desc(self.array, self.split_counter) + }; assert_eq(hints, expected); } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_transformed_value_arrays.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_transformed_value_arrays.nr index 105ce5372b6c..dee90e8f95b5 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_transformed_value_arrays.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/assert_split_transformed_value_arrays.nr @@ -59,8 +59,10 @@ where T: Ordered + Empty + Eq, S: Empty + Eq, { - let num_non_revertibles = - unsafe { find_index_hint(sorted_array, |n: T| n.counter() >= split_counter) }; + let num_non_revertibles = unsafe { + //@safety The value is checked in the assert below. + find_index_hint(sorted_array, |n: T| n.counter() >= split_counter) + }; assert_split_transformed_value_arrays_with_hint( sorted_array, diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_result.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_result.nr index 6d0a31443b55..5d0c1a66cb0e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_result.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_result.nr @@ -26,7 +26,10 @@ pub unconstrained fn get_sorted_result( #[test] fn get_sorted_hints_asc_non_padded() { let values = [40, 60, 20, 50]; - let res = unsafe { get_sorted_result(values, |a: u32, b: u32| a < b) }; + let res = unsafe { + //@safety The result is checked in the assert_eq below. + get_sorted_result(values, |a: u32, b: u32| a < b) + }; assert_eq(res.sorted_array, [20, 40, 50, 60]); assert_eq(res.sorted_index_hints, [1, 3, 0, 2]); assert_eq(res.original_index_hints, [2, 0, 3, 1]); @@ -35,7 +38,10 @@ fn get_sorted_hints_asc_non_padded() { #[test] fn get_sorted_hints_desc_non_padded() { let values = [40, 20, 60, 50]; - let res = unsafe { get_sorted_result(values, |a: u32, b: u32| b < a) }; + let res = unsafe { + //@safety The result is checked in the assert_eq below. + get_sorted_result(values, |a: u32, b: u32| b < a) + }; assert_eq(res.sorted_array, [60, 50, 40, 20]); assert_eq(res.sorted_index_hints, [2, 3, 0, 1]); } @@ -43,8 +49,10 @@ fn get_sorted_hints_desc_non_padded() { #[test] fn get_sorted_hints_asc_padded() { let values = [40, 60, 20, 50, 0, 0]; - let res = - unsafe { get_sorted_result(values, |a: u32, b: u32| (a != 0) & ((b == 0) | (a < b))) }; + let res = unsafe { + //@safety The result is checked in the assert_eq below. + get_sorted_result(values, |a: u32, b: u32| (a != 0) & ((b == 0) | (a < b))) + }; assert_eq(res.sorted_array, [20, 40, 50, 60, 0, 0]); assert_eq(res.sorted_index_hints, [1, 3, 0, 2, 4, 5]); assert_eq(res.original_index_hints, [2, 0, 3, 1, 4, 5]); @@ -53,8 +61,10 @@ fn get_sorted_hints_asc_padded() { #[test] fn get_sorted_hints_desc_padded() { let values = [40, 60, 20, 50, 0, 0]; - let res = - unsafe { get_sorted_result(values, |a: u32, b: u32| (a != 0) & ((b == 0) | (b < a))) }; + let res = unsafe { + //@safety The result is checked in the assert_eq below. + get_sorted_result(values, |a: u32, b: u32| (a != 0) & ((b == 0) | (b < a))) + }; assert_eq(res.sorted_array, [60, 50, 40, 20, 0, 0]); assert_eq(res.sorted_index_hints, [2, 0, 3, 1, 4, 5]); assert_eq(res.original_index_hints, [1, 3, 0, 2, 4, 5]); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_tuple.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_tuple.nr index 569983a9344d..a5809f3d5d39 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_tuple.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/get_sorted_tuple.nr @@ -28,7 +28,10 @@ fn get_sorted_tuple_asc() { SortedTuple { elem: 5, original_index: 3 }, SortedTuple { elem: 9, original_index: 2 }, ]; - let sorted = unsafe { get_sorted_tuple(original, |a: u64, b: u64| a < b) }; + let sorted = unsafe { + //@safety The result is checked in the assert_eq below. + get_sorted_tuple(original, |a: u64, b: u64| a < b) + }; for i in 0..4 { assert_eq(sorted[i].elem, expected[i].elem); assert_eq(sorted[i].original_index, expected[i].original_index); diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by.nr index f8eaddc7a232..6a6c4ffe4049 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by.nr @@ -8,10 +8,10 @@ pub unconstrained fn sort_by( ordering: fn[Env](T, T) -> bool, ) -> [T; N] { let mut result = array; - let sorted_index = unsafe { get_sorting_index(array, ordering) }; + let sorted_index = get_sorting_index(array, ordering); // Ensure the indexes are correct for i in 0..N { - let pos = unsafe { find_index_hint(sorted_index, |index: u32| index == i) }; + let pos = find_index_hint(sorted_index, |index: u32| index == i); assert(sorted_index[pos] == i); } // Sort the array using the indexes diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by_counter.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by_counter.nr index d4cd7176d875..9fdf92dfc096 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by_counter.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays/sort_by_counter.nr @@ -39,13 +39,19 @@ mod tests { fn asc_values_to_equal(values: [u32; N], expected: [u32; N]) { let items = values.map(|value| TestValue { value: value as Field, counter: value }); - let sorted = unsafe { sort_by_counter_asc(items).map(|item: TestValue| item.counter) }; + let sorted = unsafe { + //@safety The result is checked in the assert_eq below. + sort_by_counter_asc(items).map(|item: TestValue| item.counter) + }; assert_eq(sorted, expected); } fn desc_values_to_equal(values: [u32; N], expected: [u32; N]) { let items = values.map(|value| TestValue { value: value as Field, counter: value }); - let sorted = unsafe { sort_by_counter_desc(items).map(|item: TestValue| item.counter) }; + let sorted = unsafe { + //@safety The result is checked in the assert_eq below. + sort_by_counter_desc(items).map(|item: TestValue| item.counter) + }; assert_eq(sorted, expected); } @@ -119,7 +125,10 @@ mod tests { TestValue::empty(), TestValue::empty(), ]; - let sorted = unsafe { sort_by_counter_asc(original) }; + let sorted = unsafe { + //@safety The result is checked in the assert_eq below. + sort_by_counter_asc(original) + }; assert_eq(sorted, expected); } @@ -143,7 +152,10 @@ mod tests { TestValue::empty(), TestValue::empty(), ]; - let sorted = unsafe { sort_by_counter_desc(original) }; + let sorted = unsafe { + //@safety The result is checked in the assert_eq below. + sort_by_counter_desc(original) + }; assert_eq(sorted, expected); } }