Skip to content

Commit 367dfc0

Browse files
author
AztecBot
committed
Merge branch 'next' into merge-train/barretenberg
2 parents cb4521f + a2ba3b4 commit 367dfc0

File tree

46 files changed

+884
-352
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+884
-352
lines changed

cspell.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"Celestia",
6060
"chainid",
6161
"chainsafe",
62+
"chaum",
6263
"cheatcode",
6364
"cheatcodes",
6465
"checkpointed",
@@ -161,8 +162,11 @@
161162
"homomorphic",
162163
"hypernova",
163164
"ierc",
165+
"ified",
166+
"ifying",
164167
"IGSE",
165168
"incentivized",
169+
"includable",
166170
"incrementation",
167171
"indexeddb",
168172
"interruptible",
@@ -367,6 +371,7 @@
367371
"unshifted",
368372
"unsiloed",
369373
"unsynched",
374+
"unvalidated",
370375
"unzipit",
371376
"updateable",
372377
"upperfirst",

noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/accumulated_data/assert_array_appended.nr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ mod tests {
685685

686686
#[test]
687687
fn assert_array_appended_with_items_beyond_source_length_succeeds() {
688-
// This test exibits the counter-intuitive optimisation where items beyond the source length will still get copied,
688+
// This test exhibits the counter-intuitive optimization where items beyond the source length will still get copied,
689689
// but the dest length will ignore them.
690690
let source: ClaimedLengthArray<Field, 3> =
691691
ClaimedLengthArray { array: [30, 40, 50], length: 2 };

noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/accumulated_data/assert_sorted_padded_transformed_array.nr

Lines changed: 58 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ use types::{
66
utils::arrays::ClaimedLengthArray,
77
};
88

9-
/// Validates that the `sorted_padded_transformed_array` is sorted in ascending order by counter and that all
9+
/// Validates that the `output_array` is sorted in ascending order by counter and that all
1010
/// transformations and padding are correctly applied.
1111
///
1212
/// ### Arguments
1313
/// - `original_array`: The original array of unsorted items with a claimed length.
14-
/// - `padded_items`: The array of padded items to be added to the `sorted_padded_transformed_array`.
15-
/// - `sorted_padded_transformed_array`: The array of items that have been sorted, padded, and transformed.
14+
/// - `padded_items`: The array of padded items to be added to the `output_array`.
15+
/// - `output_array`: The array of items that have been sorted, padded, and transformed.
1616
/// - `assert_transformed`: A user-provided assertion function that verifies the transformation of each item.
1717
///
1818
/// ### Argument requirements:
@@ -23,28 +23,28 @@ use types::{
2323
/// - `assert_transformed` must guarantee that the transformed value is empty if and only if the original item is empty.
2424
///
2525
/// This function checks that:
26-
/// 1. Each item in the `original_array` is correctly transformed and placed in the `sorted_padded_transformed_array`.
27-
/// 2. The items within the `sorted_padded_transformed_array` are sorted in ascending order by their counters.
26+
/// 1. Each item in the `original_array` is correctly transformed and placed in the `output_array`.
27+
/// 2. The items within the `output_array` are sorted in ascending order by their counters.
2828
/// 3. The items in the `padded_items` within the range [original_array.length, CappedSize) are correctly padded to the
29-
/// `sorted_padded_transformed_array` after the `original_array.length` items from `original_array`.
30-
/// 4. All items within the claimed length in the `sorted_padded_transformed_array` must have non-zero counter.
31-
/// 5. All items beyond the claimed length in the `sorted_padded_transformed_array` must have zero counter.
29+
/// `output_array` after the `original_array.length` items from `original_array`.
30+
/// 4. All items within the claimed length in the `output_array` must have non-zero counter.
31+
/// 5. All items beyond the claimed length in the `output_array` must have zero counter.
3232
///
3333
/// ### Notes:
3434
/// 1. `CappedSize` must be large enough to cover all valid items in `original_array`
3535
/// (i.e. `CappedSize >= original_array.length`).
3636
/// 2. Items in `padded_items` with index < `original_array.length` or >= `CappedSize` are ignored.
3737
/// 3. `is_transformed` does not need to validate counters. This function ensures that each item in
38-
/// `sorted_padded_transformed_array` has the same counter as its corresponding item in either `original_array` or
38+
/// `output_array` has the same counter as its corresponding item in either `original_array` or
3939
/// `padded_items`.
4040
/// 4. This function can only be called at most once per side effect type. Once padded items have been added to the
41-
/// `sorted_padded_transformed_array`, the array cannot be used again as the `original_array` for this function.
42-
/// 5. The items beyond `CappedSize` in the `sorted_padded_transformed_array` must have a counter of 0, but their values
41+
/// `output_array`, the array cannot be used again as the `original_array` for this function.
42+
/// 5. The items beyond `CappedSize` in the `output_array` must have a counter of 0, but their values
4343
/// are not checked here. However, if any of them are not nullish, the tail circuits will fail to validate that the
4444
/// array is "dense trimmed". The non-nullish values cannot be used for squashing, since they are beyond the claimed
4545
/// length of the array.
4646
///
47-
/// Expected structure of the output `sorted_padded_transformed_array`:
47+
/// Expected structure of the output `output_array`:
4848
/// [...sorted_items_from_original_array, ...padded_items, ...empty_items]
4949
///
5050
/// Example:
@@ -60,7 +60,7 @@ use types::{
6060
pub fn assert_sorted_padded_transformed_array_capped_size<Value, TransformedValue, let N: u32, Env, let CappedSize: u32>(
6161
original_array: ClaimedLengthArray<Value, N>, // "kept" values (after squashing)
6262
padded_items: [Value; N],
63-
sorted_padded_transformed_array: ClaimedLengthArray<TransformedValue, N>,
63+
output_array: ClaimedLengthArray<TransformedValue, N>,
6464
// "Transformed" here means: "assert siloed" or "assert siloed & unique-ified".
6565
assert_transformed: fn[Env](Value, TransformedValue) -> (),
6666
)
@@ -71,7 +71,7 @@ where
7171
assert_sorted_padded_transformed_i_array_capped_size::<_, _, _, _, CappedSize>(
7272
original_array,
7373
padded_items,
74-
sorted_padded_transformed_array,
74+
output_array,
7575
|prev, out, _i| assert_transformed(prev, out),
7676
);
7777
}
@@ -87,27 +87,28 @@ where
8787
let mut num_padded_items = 0;
8888
for i in original_array_length..CappedSize {
8989
if padded_items[i].counter() == MAX_U32_VALUE {
90+
// Only padding items have this counter.
9091
num_padded_items += 1;
9192
}
9293
}
9394
num_padded_items
9495
}
9596

96-
/// Same as `assert_sorted_padded_transformed_array_capped_size`, but the callback `assert_transformed_i` has an
97-
/// additional index (`i`) argument.
97+
/// Same as `assert_sorted_padded_transformed_array_capped_size` (see that fn for more details), but this callback
98+
/// `assert_transformed_i` has an additional index (`i`) argument.
9899
/// Used for note hashes to compute the unique note hash value with the index.
99100
pub fn assert_sorted_padded_transformed_i_array_capped_size<Value, TransformedValue, let N: u32, Env, let CappedSize: u32>(
100101
original_array: ClaimedLengthArray<Value, N>,
101102
padded_items: [Value; N],
102-
sorted_padded_transformed_array: ClaimedLengthArray<TransformedValue, N>,
103+
output_array: ClaimedLengthArray<TransformedValue, N>,
103104
assert_transformed_i: fn[Env](Value, TransformedValue, u32) -> (),
104105
)
105106
where
106107
Value: Ordered + Empty,
107108
TransformedValue: Ordered + Empty,
108109
{
109110
// Safety: The hints are constrained by `assert_sorted_padded_transformed_i_array_capped_size_with_hints`.
110-
let (sorted_index_hints, num_padded_items) = unsafe {
111+
let (sorted_index_hints, num_padded_items_hint) = unsafe {
111112
let sorted_indexes = get_order_hints(original_array.array).sorted_indexes;
112113
let num_padded_items =
113114
get_num_padded_items(padded_items, original_array.length, CappedSize);
@@ -117,20 +118,23 @@ where
117118
assert_sorted_padded_transformed_i_array_capped_size_with_hints::<_, _, _, _, CappedSize>(
118119
original_array,
119120
padded_items,
120-
sorted_padded_transformed_array,
121+
output_array,
121122
assert_transformed_i,
122123
sorted_index_hints,
123-
num_padded_items,
124+
num_padded_items_hint,
124125
)
125126
}
126127

128+
/// @param original_array - is technically the so-called `kept_` array that's already been through squashing; it's "original" from
129+
/// the perspective of this function and the transformations it will apply.
130+
/// @param CappedSize - is a comptime constant for the number of siloing iterations this variant of the circuit supports.
127131
fn assert_sorted_padded_transformed_i_array_capped_size_with_hints<Value, TransformedValue, let N: u32, Env, let CappedSize: u32>(
128132
original_array: ClaimedLengthArray<Value, N>,
129133
padded_items: [Value; N],
130-
sorted_padded_transformed_array: ClaimedLengthArray<TransformedValue, N>,
134+
output_array: ClaimedLengthArray<TransformedValue, N>, // after sorting, siloing, padding, etc.
131135
assert_transformed_i: fn[Env](Value, TransformedValue, u32) -> (),
132136
sorted_index_hints: [u32; N],
133-
num_padded_items: u32,
137+
num_padded_items_hint: u32,
134138
)
135139
where
136140
Value: Ordered + Empty,
@@ -142,78 +146,88 @@ where
142146
"CappedSize not large enough to cover all valid items in original_array",
143147
);
144148

145-
// The claimed length of the result array is the original array length plus the hinted number of padded items.
149+
// The claimed length of the result array (`output_array`) should be the original array length
150+
// plus the hinted number of padded items.
146151
// It is checked below to ensure that all items within the claimed length do not have a counter of 0.
147-
let result_array_length = original_array_length + num_padded_items;
152+
// We also assert below that items between original_array_length and result_array_length (in the resulting array)
153+
// have all the characteristics of padding items.
154+
let result_array_length = original_array_length + num_padded_items_hint;
148155

149-
let mut should_be_padded = false;
156+
let mut should_be_padding = false;
150157
let mut should_be_empty = false;
151158
for i in 0..N {
152-
let output_item_i = sorted_padded_transformed_array.array[i];
159+
let output_item_i = output_array.array[i];
153160

154161
// Note: because `CappedSize` is known at compile-time, Noir is clever enough to only compute the `else` block
155162
// `CappedSize` number of times, instead of `N` times.
156163
// This is why we do siloing (via `assert_transformed_i`) in the reset circuit instead of the tail: we can
157164
// iterate over much smaller arrays by choosing a proper reset circuit variant.
158165
if i >= CappedSize {
159-
// Ensure that all items with index >= `CappedSize` have a counter of 0.
166+
// Ensure that all items with index >= `CappedSize` have a counter of 0. A counter of `0` implies
167+
// the item is nullish (because all non-nullish items are assigned a counter by the Init / Inner kernels
168+
// (or by this reset circuit in the case of padding items)).
160169
// It's fine that the value is not checked here, see Note 5 in the comment at the top to know why.
161170
// Without this check, an original item can be mapped to a trailing item.
162171
// For an example, see the test `use_items_outside_of_capped_size_to_add_random_item`.
163172
// Comment out this check and the test will fail because no error is raised.
164173
assert_eq(output_item_i.counter(), 0, "Trailing items must have counter 0");
165174
} else {
166-
should_be_padded |= i == original_array_length;
175+
should_be_padding |= i == original_array_length;
167176
should_be_empty |= i == result_array_length;
168177

169178
let original = original_array.array[i];
170179
let sorted_index = sorted_index_hints[i];
171180
let padded_item = padded_items[i];
172181

173-
let (from, to_index) = if should_be_padded {
174-
// For i >= `original_array.length`, `sorted_padded_transformed_array[i]` is from `padded_items[i]`.
182+
// Naming: We're mapping "from" the original_array "to" the output_array:
183+
let (from, to_index) = if should_be_padding {
184+
// For i >= `original_array.length`, `output_array[i]` is from `padded_items[i]`.
175185
(padded_item, i)
176186
} else {
177187
// For i < `original_array.length`, we loop through the items in `original_array`, ensuring that every
178188
// item within the range [0, original_array.length) is mapped to an item in the
179-
// `sorted_padded_transformed_array` at `sorted_index`.
189+
// `output_array` at `sorted_index`.
180190
//
181191
// We can be certain that `sorted_index` must be < `original_array.length`, because:
182-
// - Items with index >= `CappedSize` in the `sorted_padded_transformed_array` have counter 0 (checked
192+
// - Items with index >= `CappedSize` in the `output_array` have counter 0 (checked
183193
// in the above `if` block).
184-
// - Items within the range [original_array.length, CappedSize) in the `sorted_padded_transformed_array`
185-
// are padded items, which must have a counter of `MAX_U32_VALUE` or 0.
194+
// - Items within the range [original_array.length, result_array_length) in the `output_array`
195+
// are padded items, which must have a counter of `MAX_U32_VALUE`.
196+
// - Items within the range [result_array_length, CappedSize) in the `output_array`
197+
// must have a counter of 0.
186198
// - Items within the range [0, original_array.length) in the `original_array` must not have a counter
187199
// of 0 (requirement of the parameter) or `MAX_U32_VALUE` (checked above).
188200
(original, sorted_index)
189201
};
190202

191203
// Validate that the transformation of the value is correct.
192-
let to = sorted_padded_transformed_array.array[to_index];
204+
// "Transformation" =
205+
// - Siloing (for nullifiers and logs)
206+
// - Siloing and unique-ifying for notes.
207+
let to = output_array.array[to_index];
193208
assert_transformed_i(from, to, to_index);
194209

195210
// Validate that the counter of the transformed item matches the counter of the original/padded item.
196211
assert_eq(from.counter(), to.counter(), "mapped item has mismatch counter");
197212

198-
if !should_be_padded {
213+
if !should_be_padding {
199214
// Validate that counters within the range [0, original_array.length) are strictly increasing.
200215
// Since all items within the range [0, original_array.length) in the `original_array` must have a
201216
// unique counter (a requirement of the parameter), this check guarantees that all items in the
202-
// `sorted_padded_transformed_array` within the same range can't be skipped or mapped to more than once.
217+
// `output_array` within the same range can't be skipped or mapped to more than once.
203218
if i != 0 {
204219
assert(
205-
output_item_i.counter()
206-
> sorted_padded_transformed_array.array[i - 1].counter(),
220+
output_item_i.counter() > output_array.array[i - 1].counter(),
207221
"value array must be sorted by counter in ascending order",
208222
);
209223
}
210224
}
211225

212-
// Validate that all items within the claimed length of the `sorted_padded_transformed_array` do not have a
226+
// Validate that all items within the claimed length of the `output_array` do not have a
213227
// counter of 0, and items beyond the claimed length must have a counter of 0.
214228
// Without this check, the hinted `num_padded_items` could be larger than the number of non-empty padded
215-
// items, allowing empty items within the claimed length of the `sorted_padded_transformed_array`. And the
216-
// empty items can be used to add random items to the `sorted_padded_transformed_array` if this function
229+
// items, allowing empty items within the claimed length of the `output_array`. And the
230+
// empty items can be used to add random items to the `output_array` if this function
217231
// is called again.
218232
// For an example, see the test `use_empty_items_within_claimed_length_to_add_random_item`.
219233
// Comment out this check and the test will fail because no error is raised.
@@ -238,9 +252,9 @@ where
238252
}
239253
}
240254

241-
// Validate that the length of the `sorted_padded_transformed_array` is the `original_array_length` plus the hinted
255+
// Validate that the length of the `output_array` is the `original_array_length` plus the hinted
242256
// `num_padded_items`.
243-
assert_eq(sorted_padded_transformed_array.length, result_array_length);
257+
assert_eq(output_array.length, result_array_length);
244258
}
245259

246260
mod tests {

noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/accumulated_data/assert_sorted_padded_transformed_array/check_padded_items.nr

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
11
use types::traits::Empty;
22

3-
// Utility to check the padded items provided by the user.
4-
// - Checks that all items outside the range [num_original_items, CappedSize) are empty.
5-
// - Checks that non-empty items within the range are consecutive.
6-
// Note: Technically, values outside this range could be non-empty, since they are ignored. However, enforcing emptiness
7-
// helps prevent unexpected output if the array is misconfigured.
3+
/// Utility to validate the layout of the padded items provided by the user.
4+
///
5+
/// Our target (created in a later fn): [<-- original ("kept") items -->|<-- padding -->|0, ..., 0]
6+
/// ^ ^
7+
/// | |
8+
/// `num_original_items` `capped_size`: the number of elements this reset
9+
/// | circuit is capable of processing.
10+
/// | |
11+
/// v v
12+
/// `padded_items`: [0, ... , 0|<-- padding -->|0, ..., 0]
13+
///
14+
/// So `padded_items` is _solely the padding_!!!
15+
///
16+
/// - Checks that all items outside the range [num_original_items, CappedSize) are empty.
17+
/// - Checks that non-empty items within the range are consecutive. (So we do technically allow 0 padding, as
18+
/// long as it's all on the rhs).
19+
///
20+
/// Note: Technically, values outside this range could be non-empty, since they are ignored. However, enforcing emptiness
21+
/// helps prevent unexpected output if the array is misconfigured.
822
pub unconstrained fn check_padded_items<T, let N: u32>(
923
padded_items: [T; N],
1024
num_original_items: u32,

noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/accumulated_data/assert_sorted_transformed_array/get_order_hints.nr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ impl<let N: u32> Eq for OrderHints<N> {
1616
/// Generates hints for more efficient validation in `assert_sorted_transformed_array`.
1717
///
1818
/// ### Inputs
19-
/// - `original_array`: The array whose items are to be sorted.
19+
/// - `original_array`: The array whose items are to be sorted by their counter.
2020
///
2121
/// ### Outputs
2222
/// `OrderHints`: Metadata describing how items should be mapped and ordered. It contains:

noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/components/private_call_data_validator.nr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ impl PrivateCallDataValidator {
9191
);
9292

9393
self.validate_against_previous_kernel(previous_kernel);
94+
95+
// The call request at the top of the stack should match the current call being executed.
96+
let private_call_stack_length = previous_kernel.end.private_call_stack.length;
97+
let call_request =
98+
previous_kernel.end.private_call_stack.array[private_call_stack_length - 1];
99+
self.validate_against_call_request(call_request);
94100
}
95101

96102
/// For Init and Inner.
@@ -161,12 +167,6 @@ impl PrivateCallDataValidator {
161167
"anchor block header mismatch",
162168
);
163169
assert_eq(this_call.tx_context, constants.tx_context, "mismatch tx context");
164-
165-
// The call request at the top of the stack should match the current call being executed.
166-
let private_call_stack_length = previous_kernel.end.private_call_stack.length;
167-
let call_request =
168-
previous_kernel.end.private_call_stack.array[private_call_stack_length - 1];
169-
self.validate_against_call_request(call_request);
170170
}
171171

172172
/// For Inner only.

0 commit comments

Comments
 (0)