-
Notifications
You must be signed in to change notification settings - Fork 164
feat(batch kernel): wire up INPUT_NOTES_COMMITMENT & note erasure
#2905
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
base: next
Are you sure you want to change the base?
Changes from all commits
01f5f62
79967d6
feeb1cc
622bee3
fc74536
8746a94
0e9e806
a4f8bf5
6304eef
92502cf
f85ebac
e295049
d62e9e7
623d1cf
174ed7e
c1496dd
4ee8a17
0a80c7c
08cd5ac
91a2e3b
4abe140
af662e6
65158db
74a4b8b
9f4f2f8
c6178b7
d502cc6
5bde6bf
bf4eedd
8d18cb2
ef594bb
df9ee18
5df0369
273fdf0
941d204
a259c82
dc7558f
d7973e8
43ffbc1
0914d80
f94484c
150bc93
b9194f6
ff1f7ec
23eba90
0355fc3
97138b2
e571bb4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,187 @@ | ||||||||||||
| use miden::core::crypto::hashes::poseidon2 | ||||||||||||
|
|
||||||||||||
| use miden::batch_kernel::memory | ||||||||||||
| use { | ||||||||||||
| INPUT_NOTE_CONSUMPTION_OFFSET, | ||||||||||||
| INPUT_NOTE_ERASED, | ||||||||||||
| INPUT_NOTE_ERASURE_EXPECTED, | ||||||||||||
| NOTE_ENTRY_FELT_LEN, | ||||||||||||
| OUTPUT_NOTE_IS_CREATED_OFFSET, | ||||||||||||
| } from miden::batch_kernel::memory | ||||||||||||
| use {ERR_BATCH_NOTE_CONSUMED_BEFORE_CREATED} from miden::batch_kernel::errors | ||||||||||||
|
|
||||||||||||
| # ERRORS | ||||||||||||
| # ================================================================================================= | ||||||||||||
|
|
||||||||||||
| const ERR_BATCH_INPUT_NOTE_NOT_CONSUMED = | ||||||||||||
| "an input-note list entry was not consumed by any transaction" | ||||||||||||
|
|
||||||||||||
| const ERR_BATCH_OUTPUT_NOTE_NOT_CREATED = | ||||||||||||
| "an output-note list entry was not created by any transaction" | ||||||||||||
|
|
||||||||||||
| # ASSERTIONS | ||||||||||||
| # ================================================================================================= | ||||||||||||
|
|
||||||||||||
| #! Asserts every output-note list entry was created by exactly one transaction (with the per-tx | ||||||||||||
| #! binding, this proves the list is exactly the union of the per-transaction output notes, so a host | ||||||||||||
| #! cannot fabricate an erasure with a note no transaction creates). | ||||||||||||
| #! | ||||||||||||
| #! The matching input-note checks (every entry consumed exactly once, none left pending-erasure) are | ||||||||||||
| #! folded into the single pass in [`compute_input_notes_commitment`]. | ||||||||||||
| #! | ||||||||||||
| #! Inputs: [] | ||||||||||||
| #! Outputs: [] | ||||||||||||
| proc assert_all_output_notes_created | ||||||||||||
| exec.memory::get_num_output_notes | ||||||||||||
| # => [num_output_notes] | ||||||||||||
|
|
||||||||||||
| # Iterate from num_output_notes - 1 down to 0. | ||||||||||||
| dup neq.0 | ||||||||||||
| while.true | ||||||||||||
| sub.1 | ||||||||||||
| # => [idx] | ||||||||||||
|
|
||||||||||||
| dup exec.memory::output_note_flags_ptr add.OUTPUT_NOTE_IS_CREATED_OFFSET mem_load | ||||||||||||
| # => [is_created, idx] | ||||||||||||
| assert.err=ERR_BATCH_OUTPUT_NOTE_NOT_CREATED | ||||||||||||
|
|
||||||||||||
| dup neq.0 | ||||||||||||
| # => [should_loop, idx] | ||||||||||||
| end | ||||||||||||
| drop | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| # INPUT NOTES COMMITMENT | ||||||||||||
| # ================================================================================================= | ||||||||||||
|
|
||||||||||||
| #! Absorbs input-note list entry `idx`'s 8-felt `(NULLIFIER, NOTE_ID_OR_EMPTY)` tuple into the batch | ||||||||||||
| #! hasher state held in memory (overwrite-mode poseidon2, matching `Hasher::hash_elements`). | ||||||||||||
| #! | ||||||||||||
| #! Inputs: [idx] | ||||||||||||
| #! Outputs: [] | ||||||||||||
| proc absorb_input_entry | ||||||||||||
| # The entry occupies one double word [entry_ptr, entry_ptr + NOTE_ENTRY_FELT_LEN). | ||||||||||||
| exec.memory::input_note_entry_ptr | ||||||||||||
|
Comment on lines
+57
to
+64
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this procedure doc comment, I'd make it more obvious that Also applies to the the output, which is the hash in memory. |
||||||||||||
| # => [entry_ptr] | ||||||||||||
| dup add.NOTE_ENTRY_FELT_LEN swap | ||||||||||||
| # => [entry_ptr, end_ptr] | ||||||||||||
| exec.memory::load_batch_hasher_state | ||||||||||||
| # => [RATE0, RATE1, CAPACITY, entry_ptr, end_ptr] | ||||||||||||
| exec.poseidon2::absorb_double_words_from_memory | ||||||||||||
| # => [RATE0', RATE1', CAPACITY', end_ptr, end_ptr] | ||||||||||||
| exec.memory::save_batch_hasher_state | ||||||||||||
|
Comment on lines
+67
to
+72
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I'd maybe keep the hasher state on the stack even if it pollutes the inputs/outputs more. If we want to keep memory, I would use local memory of |
||||||||||||
| # => [end_ptr, end_ptr] | ||||||||||||
| drop drop | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| #! Processes one input-note list entry: asserts the entry was consumed exactly once and is not | ||||||||||||
| #! left expected-to-be-erased, then absorbs it into the batch hasher unless it was erased. | ||||||||||||
| #! | ||||||||||||
| #! The absorbed_count is only incremented by 1 if the entry was not erased. | ||||||||||||
| #! | ||||||||||||
| #! Inputs: [idx, absorbed_count, num] | ||||||||||||
| #! Outputs: [idx + 1, absorbed_count, num] | ||||||||||||
| proc process_input_entry | ||||||||||||
| # Assert this entry was consumed exactly once and is not left expected-to-be-erased. | ||||||||||||
| dup exec.memory::input_note_flags_ptr | ||||||||||||
| # => [flags_ptr, idx, absorbed_count, num] | ||||||||||||
| dup add.INPUT_NOTE_CONSUMPTION_OFFSET mem_load | ||||||||||||
| # => [consumption, flags_ptr, idx, absorbed_count, num] | ||||||||||||
| assert.err=ERR_BATCH_INPUT_NOTE_NOT_CONSUMED | ||||||||||||
| # => [flags_ptr, idx, absorbed_count, num] | ||||||||||||
| mem_load | ||||||||||||
| # => [erasure, idx, absorbed_count, num] | ||||||||||||
| dup neq.INPUT_NOTE_ERASURE_EXPECTED assert.err=ERR_BATCH_NOTE_CONSUMED_BEFORE_CREATED | ||||||||||||
| # => [erasure, idx, absorbed_count, num] | ||||||||||||
|
|
||||||||||||
| # Absorb the entry unless it was erased (created-and-consumed in this batch). | ||||||||||||
| neq.INPUT_NOTE_ERASED | ||||||||||||
| # => [not_erased, idx, absorbed_count, num] | ||||||||||||
| if.true | ||||||||||||
| dup exec.absorb_input_entry | ||||||||||||
| swap add.1 swap | ||||||||||||
| # => [idx, absorbed_count+1, num] | ||||||||||||
| end | ||||||||||||
| add.1 | ||||||||||||
| end | ||||||||||||
|
mmagician marked this conversation as resolved.
Comment on lines
+105
to
+106
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
|
||||||||||||
| #! Computes INPUT_NOTES_COMMITMENT as the sequential poseidon2 hash of the non-erased | ||||||||||||
| #! `(NULLIFIER, NOTE_ID_OR_EMPTY)` entries of the nullifier-sorted input-note list (erased entries | ||||||||||||
| #! are skipped). | ||||||||||||
| #! | ||||||||||||
| #! The single pass over the input entries also enforces the epilogue invariants on each entry: it | ||||||||||||
| #! was consumed exactly once and is not left expected-to-be-erased (i.e. any created-and-consumed | ||||||||||||
| #! note had its creator processed). | ||||||||||||
| #! | ||||||||||||
| #! Inputs: [] | ||||||||||||
| #! Outputs: [INPUT_NOTES_COMMITMENT] | ||||||||||||
| proc compute_input_notes_commitment | ||||||||||||
| # Initialize the batch hasher state in memory. | ||||||||||||
| exec.poseidon2::init_no_padding | ||||||||||||
| exec.memory::save_batch_hasher_state | ||||||||||||
|
|
||||||||||||
| exec.memory::get_num_input_notes | ||||||||||||
| push.0 push.0 | ||||||||||||
| # => [idx, absorbed_count, num] | ||||||||||||
|
|
||||||||||||
| dup dup.3 neq | ||||||||||||
| # => [should_loop, idx, absorbed_count, num] | ||||||||||||
| while.true | ||||||||||||
|
zeapoz marked this conversation as resolved.
|
||||||||||||
| exec.process_input_entry | ||||||||||||
| # => [idx+1, absorbed_count, num] (absorbed_count + 1 if entry was not erased) | ||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
nit: that's the concern of process_input_entry |
||||||||||||
| dup dup.3 neq | ||||||||||||
| # => [should_loop, idx+1, absorbed_count, num] | ||||||||||||
| end | ||||||||||||
| # => [idx, absorbed_count, num] | ||||||||||||
| drop swap drop | ||||||||||||
| # => [absorbed_count] | ||||||||||||
|
|
||||||||||||
| # With no non-erased entries the commitment is the empty word, matching the early return in | ||||||||||||
| # `build_input_note_commitment` (this is not the hash of zero elements). Otherwise squeeze the | ||||||||||||
| # accumulated state. | ||||||||||||
| eq.0 | ||||||||||||
| if.true | ||||||||||||
| padw | ||||||||||||
| # => [EMPTY_WORD] | ||||||||||||
| else | ||||||||||||
| exec.memory::load_batch_hasher_state | ||||||||||||
| exec.poseidon2::squeeze_digest | ||||||||||||
| # => [INPUT_NOTES_COMMITMENT] | ||||||||||||
| end | ||||||||||||
|
mmagician marked this conversation as resolved.
Comment on lines
+139
to
+150
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need this, it's sufficient to I think this means also that we can remove |
||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| # OUTPUT NOTES COMMITMENT | ||||||||||||
| # ================================================================================================= | ||||||||||||
|
|
||||||||||||
| #! Computes the batch's output-notes commitment (the batch note tree root). | ||||||||||||
| #! | ||||||||||||
| #! Placeholder: returns the empty word until the batch note tree is wired up. | ||||||||||||
| #! | ||||||||||||
| #! Inputs: [] | ||||||||||||
| #! Outputs: [OUTPUT_NOTES_COMMITMENT] | ||||||||||||
| #! | ||||||||||||
| #! TODO: hash the batch's output notes into the batch note tree (SMT) root. | ||||||||||||
| proc compute_output_notes_commitment | ||||||||||||
| padw | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| # EPILOGUE | ||||||||||||
| # ================================================================================================= | ||||||||||||
|
|
||||||||||||
| #! Verifies the note-tracking results and computes the batch's note commitments. | ||||||||||||
| #! | ||||||||||||
| #! Asserts every output-note list entry was created, then computes the input- and output-notes | ||||||||||||
| #! commitments. The per-input-entry invariants (consumed exactly once, no pending erasure) are | ||||||||||||
| #! enforced inside the input-commitment pass. | ||||||||||||
| #! | ||||||||||||
| #! Inputs: [] | ||||||||||||
| #! Outputs: [INPUT_NOTES_COMMITMENT, OUTPUT_NOTES_COMMITMENT] | ||||||||||||
| #! | ||||||||||||
| #! TODO: authenticate unauthenticated, non-erased input notes against BLOCK_COMMITMENT's chain MMR. | ||||||||||||
| pub proc finalize | ||||||||||||
| exec.assert_all_output_notes_created | ||||||||||||
| exec.compute_output_notes_commitment | ||||||||||||
| # => [OUTPUT_NOTES_COMMITMENT] | ||||||||||||
| exec.compute_input_notes_commitment | ||||||||||||
| # => [INPUT_NOTES_COMMITMENT, OUTPUT_NOTES_COMMITMENT] | ||||||||||||
| end | ||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # Error constants shared by batch kernel modules. | ||
|
|
||
| # ERRORS | ||
| # ================================================================================================= | ||
|
|
||
| pub const ERR_BATCH_NOTE_CONSUMED_BEFORE_CREATED = | ||
| "an erased input note was consumed before the transaction that created it" |
Uh oh!
There was an error while loading. Please reload this page.