@@ -23,11 +23,69 @@ use types::{
2323 MAX_NULLIFIER_READ_REQUESTS_PER_TX , MAX_NULLIFIERS_PER_TX , MAX_PRIVATE_LOGS_PER_TX ,
2424 MAX_U32_VALUE , SIDE_EFFECT_MASKING_ADDRESS ,
2525 },
26- hash ::{compute_unique_siloed_note_hash , silo_note_hash , silo_nullifier , silo_private_log },
26+ hash ::{
27+ compute_note_nonce_and_unique_note_hash , compute_siloed_note_hash , compute_siloed_nullifier ,
28+ compute_siloed_private_log ,
29+ },
2730 side_effect ::{Counted , Scoped },
2831 utils::arrays::ClaimedLengthArray ,
2932};
3033
34+ pub fn silo_note_hash (note_hash : Scoped <Counted <NoteHash >>) -> Scoped <Counted <NoteHash >> {
35+ let mut siloed = note_hash ;
36+ siloed .inner .inner =
37+ compute_siloed_note_hash (note_hash .contract_address , note_hash .innermost ());
38+
39+ // We set the contract address to zero to indicate that the note hash has been siloed.
40+ // The reset output validator will check the contract address of the first note hash to ensure that siloing has not
41+ // been performed in a previous reset.
42+ siloed .contract_address = AztecAddress ::zero ();
43+
44+ siloed
45+ }
46+
47+ pub fn uniquify_siloed_note_hash (
48+ siloed_note_hash : Scoped <Counted <NoteHash >>,
49+ first_nullifier : Field ,
50+ index_in_tx : u32 ,
51+ ) -> Scoped <Counted <NoteHash >> {
52+ let mut uniquified = siloed_note_hash ;
53+ uniquified .inner .inner = compute_note_nonce_and_unique_note_hash (
54+ siloed_note_hash .inner .inner ,
55+ first_nullifier ,
56+ index_in_tx ,
57+ );
58+ uniquified
59+ }
60+
61+ pub fn silo_nullifier (nullifier : Scoped <Counted <Nullifier >>) -> Scoped <Counted <Nullifier >> {
62+ let mut siloed = nullifier ;
63+ siloed .inner .inner .value =
64+ compute_siloed_nullifier (nullifier .contract_address , nullifier .innermost ().value );
65+
66+ // We set the contract address to zero to indicate that the nullifier has been siloed.
67+ // The reset output validator will check the contract address of the first nullifier to ensure that siloing has not
68+ // been performed in a previous reset.
69+ siloed .contract_address = AztecAddress ::zero ();
70+
71+ siloed
72+ }
73+
74+ pub fn silo_private_log (
75+ private_log : Scoped <Counted <PrivateLogData >>,
76+ ) -> Scoped <Counted <PrivateLogData >> {
77+ let mut siloed = private_log ;
78+ siloed .inner .inner .log =
79+ compute_siloed_private_log (private_log .contract_address , private_log .innermost ().log );
80+
81+ // We set the contract address to zero to indicate that the private log has been siloed.
82+ // The reset output validator will check the contract address of the first private log to ensure that siloing has not
83+ // been performed in a previous reset.
84+ siloed .contract_address = AztecAddress ::zero ();
85+
86+ siloed
87+ }
88+
3189pub struct ResetOutputComposer {
3290 pub previous_kernel : PrivateKernelCircuitPublicInputs ,
3391 pub padded_side_effects : PaddedSideEffects ,
@@ -142,19 +200,18 @@ impl ResetOutputComposer {
142200 // Calling this in the unconstrained context is not a problem. Since it doesn't matter if there are non-empty
143201 // items outside of the range [num_kept_note_hashes, NoteHashSiloingAmount). The values will simply be ignored.
144202 // Having the check here is useful to catch any bugs where the padded values are not configured correctly by mistake.
145- check_padded_items (
203+ let num_padded_items = check_padded_items (
146204 padded_note_hashes ,
147205 num_kept_note_hashes ,
148206 NoteHashSiloingAmount ,
149207 );
150208
151209 let mut padded_unique_siloed_sorted_kept_note_hashes = sorted_kept_note_hashes ;
152210
153- for i in 0 ..sorted_kept_note_hashes . array . len () {
211+ for i in 0 ..num_kept_note_hashes + num_padded_items {
154212 // Push padding:
155- if ( i >= num_kept_note_hashes )
213+ if i >= num_kept_note_hashes {
156214 // We only apply padding if the executor of this circuit provides padding as input:
157- & (padded_note_hashes [i ] != 0 ) {
158215 // We 'push' so that the length increments.
159216 // Note: beyond `NoteHashSiloingAmount`, these so-called "padded" note_hashes
160217 // will be empty, because we just called `check_padded_items`.
@@ -176,7 +233,7 @@ impl ResetOutputComposer {
176233 let siloed_note_hash = silo_note_hash (note_hash );
177234
178235 // Unique:
179- let unique_siloed_note_hash = compute_unique_siloed_note_hash (
236+ let unique_siloed_note_hash = uniquify_siloed_note_hash (
180237 siloed_note_hash ,
181238 self .previous_kernel .claimed_first_nullifier ,
182239 i ,
@@ -224,7 +281,7 @@ impl ResetOutputComposer {
224281 // This means the "revertible from private-land" note_hashes cannot be made unique in
225282 // private-land, since the uniqueness can only be derived in public-land, because the
226283 // revertible notes' indices (within the note_hashes of the tx) will only be known in
227- // public-land. See `compute_unique_siloed_note_hash ` for more explanation on how the
284+ // public-land. See `compute_note_nonce_and_unique_note_hash ` for more explanation on how the
228285 // uniqueness (aka note_nonce) is derived.
229286 //
230287 // In summary:
@@ -239,18 +296,11 @@ impl ResetOutputComposer {
239296 self .previous_kernel .claimed_revertible_counter ,
240297 );
241298
242- padded_unique_siloed_sorted_kept_note_hashes .array [i ]. inner . inner = if is_non_revertible {
299+ padded_unique_siloed_sorted_kept_note_hashes .array [i ] = if is_non_revertible {
243300 unique_siloed_note_hash
244301 } else {
245302 siloed_note_hash
246303 };
247-
248- // Why is it doing this? Is the contract_address being overloaded to mean something else?
249- // Oh, is it being used to say "This has already been siloed"?
250- // TODO: Why not use an extra bool to convey that?
251- // A contract address will be assigned to the padding within constrained-land (see validate_sorted_siloed_unique_padded_note_hashes).
252- padded_unique_siloed_sorted_kept_note_hashes .array [i ].contract_address =
253- AztecAddress ::zero ();
254304 }
255305 padded_unique_siloed_sorted_kept_note_hashes
256306 }
@@ -270,19 +320,18 @@ impl ResetOutputComposer {
270320 // Calling this in the unconstrained context is not a problem. Since it doesn't matter if there are non-empty
271321 // items outside of the range [num_nullifiers, NullifierSiloingAmount). The values will simply be ignored.
272322 // Having the check here is useful to catch any bugs where the padded values are not configured correctly by mistake.
273- check_padded_items (
323+ let num_padded_items = check_padded_items (
274324 padded_nullifiers ,
275325 num_kept_nullifiers ,
276326 NullifierSiloingAmount ,
277327 );
278328
279329 let mut padded_siloed_sorted_kept_nullifiers = sorted_kept_nullifiers ;
280330
281- for i in 0 ..sorted_kept_nullifiers . array . len () {
331+ for i in 0 ..num_kept_nullifiers + num_padded_items {
282332 // Push padding:
283- if ( i >= num_kept_nullifiers )
333+ if i >= num_kept_nullifiers {
284334 // we only apply padding if the executor of this circuit provides padding as input:
285- & (padded_nullifiers [i ] != 0 ) {
286335 padded_siloed_sorted_kept_nullifiers .push (Nullifier {
287336 value : padded_nullifiers [i ],
288337 note_hash : 0 ,
@@ -295,11 +344,8 @@ impl ResetOutputComposer {
295344 .scope (SIDE_EFFECT_MASKING_ADDRESS ));
296345 }
297346
298- // Silo:
299- padded_siloed_sorted_kept_nullifiers .array [i ].inner .inner .value =
300- silo_nullifier (padded_siloed_sorted_kept_nullifiers .array [i ]);
301- // A contract address will be assigned to the padding within constrained-land (see validate_sorted_siloed_padded_nullifiers).
302- padded_siloed_sorted_kept_nullifiers .array [i ].contract_address = AztecAddress ::zero ();
347+ let nullifier = padded_siloed_sorted_kept_nullifiers .array [i ];
348+ padded_siloed_sorted_kept_nullifiers .array [i ] = silo_nullifier (nullifier );
303349 }
304350
305351 padded_siloed_sorted_kept_nullifiers
@@ -320,7 +366,7 @@ impl ResetOutputComposer {
320366 // Calling this in the unconstrained context is not a problem. Since it doesn't matter if there are non-empty
321367 // items outside of the range [num_private_logs, PrivateLogSiloingAmount). The values will simply be ignored.
322368 // Having the check here is useful to catch any bugs where the padded values are not configured correctly by mistake.
323- check_padded_items (
369+ let num_padded_items = check_padded_items (
324370 padded_private_logs ,
325371 num_kept_private_logs ,
326372 PrivateLogSiloingAmount ,
@@ -329,11 +375,10 @@ impl ResetOutputComposer {
329375 // The ordering of adjectives in this name is intentional (back to front).
330376 let mut padded_siloed_sorted_kept_private_logs = sorted_kept_private_logs ;
331377
332- for i in 0 ..sorted_kept_private_logs . array . len () {
378+ for i in 0 ..num_kept_private_logs + num_padded_items {
333379 // Pad:
334- if ( i >= num_kept_private_logs )
380+ if i >= num_kept_private_logs {
335381 // we only apply padding if the executor of this circuit provides padding as input:
336- & (padded_private_logs [i ].length != 0 ) {
337382 padded_siloed_sorted_kept_private_logs .push (PrivateLogData {
338383 log : padded_private_logs [i ],
339384 note_hash_counter : 0 , // Recall: this is only used to hint which note (if any) this log corresponds to.
@@ -346,11 +391,8 @@ impl ResetOutputComposer {
346391 .scope (SIDE_EFFECT_MASKING_ADDRESS ));
347392 }
348393
349- // Silo:
350- padded_siloed_sorted_kept_private_logs .array [i ].inner .inner .log =
351- silo_private_log (padded_siloed_sorted_kept_private_logs .array [i ]);
352- // A contract address will be assigned to the padding within constrained-land (see validate_sorted_siloed_padded_private_logs).
353- padded_siloed_sorted_kept_private_logs .array [i ].contract_address = AztecAddress ::zero ();
394+ let private_log = padded_siloed_sorted_kept_private_logs .array [i ];
395+ padded_siloed_sorted_kept_private_logs .array [i ] = silo_private_log (private_log );
354396 }
355397
356398 padded_siloed_sorted_kept_private_logs
0 commit comments