feat: minimal batch kernel#2905
Draft
mmagician wants to merge 1 commit into
Draft
Conversation
Replaces the skeleton kernel from the parent PR with the recursive unhashing chain that verifies every batch output back to the public TRANSACTIONS_COMMITMENT. MASM: - lib/prologue.masm: pipes (tx_id, account_id) tuples keyed by TRANSACTIONS_COMMITMENT and per-tx headers keyed by each verified tx_id; tracks the running min of expiration_block_num. - lib/note_tracker.masm: pipes per-tx (NULLIFIER, EMPTY_OR_COMMITMENT) and (NOTE_ID, METADATA_COMMITMENT) tuples keyed by the verified per-tx INPUT_NOTES_COMMITMENT / OUTPUT_NOTES_COMMITMENT, absorbs into a batch-level sequential hasher, squeezes the final digest. - lib/memory.masm: pointer constants + accessor procs. - main.masm: orchestrates prologue + note_tracker + expiration read and produces the final output stack. Rust: - BatchId::hash_input_elements and TransactionId::input_elements exposed as pub(crate) helpers so the Rust hashers and the kernel advice builder share a single source of truth for the felt layouts. - BatchKernel::build_advice_inputs now populates the advice map with the layered map structure the kernel verifies. - LocalBatchProver::prove cross-checks the kernel's batch_expiration_block_num against proposed_batch.batch_expiration_block_num. Tests: happy path now asserts the real commitments + expiration value, plus four tampering tests that corrupt different layers of the advice chain and verify the kernel aborts with the matching error message.
mmagician
commented
May 15, 2026
| # AS: [len_felts, data...] | ||
|
|
||
| adv_push.1 div.4 | ||
| # Stack: [num_words, TRANSACTIONS_COMMITMENT, TX_TUPLES_PTR] |
Collaborator
Author
There was a problem hiding this comment.
Pointer variable names in stack comments should be lowercase
| movup.5 swap | ||
| # Stack: [num_words, tx_header_ptr, TX_ID, tx_index, num_transactions] | ||
|
|
||
| exec.mem::pipe_words_to_memory |
Collaborator
Author
There was a problem hiding this comment.
I think we can use pipe_preimage_to_memory instead and avoid the word equality assertion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Second PR in the #2884 split. Stacks on top of #2904 (the skeleton kernel +
ProvenBatchproof field). Review that PR first.Fills in the verification chain that the skeleton left as a TODO. Every felt feeding the kernel's outputs is now reconstructed from the advice provider and anchored in the public
TRANSACTIONS_COMMITMENT.MASM (under
crates/miden-protocol/asm/kernels/batch/lib/):prologue.masm: pipes the(tx_id, account_id)tuple list keyed byTRANSACTIONS_COMMITMENTinto memory and asserts the sequential hash matches the public input. Then for each verifiedtx_id, pipes the felt sequence thatTransactionId::newhashes and asserts the hash matches. Maintains the running min ofexpiration_block_num.note_tracker.masm: per transaction, pipes the(NULLIFIER, EMPTY_OR_COMMITMENT)/(NOTE_ID, METADATA_COMMITMENT)tuple lists keyed by the previously-verified per-tx commitment, asserts the hash matches, then absorbs the verified data into a batch-level sequential hasher.memory.masm: pointer constants and accessor procedures.main.masmrewritten to orchestrate the above and emit the real outputs.Rust:
BatchId::hash_input_elementsandTransactionId::input_elementsare exposed aspub(crate)helpers so the Rust hashers and the kernel's advice builder share a single source of truth for the felt layout.BatchKernel::build_advice_inputsnow populates the advice map with the layered structure the kernel walks.LocalBatchProver::provecross-checks the kernel'sbatch_expiration_block_numoutput againstproposed_batch.batch_expiration_block_num().Tests:
batch_kernel_happy_pathnow asserts the real commitments and expiration value instead of zeros.rejects_wrong_transactions_commitment,rejects_tampered_layer_2,rejects_tampered_input_notes,rejects_tampered_output_notes) corrupt different layers of the advice chain and assert the kernel aborts with the matching error message.TODOs in
main.masmenumerate the remaining checks (recursiveExecutionProofverification, intra-batch unauthenticated-note erasure,BLOCK_HASHverification, batch size limits,BatchNoteTreeSMT root, etc.) that are out of scope for this PR.Test plan
cargo nextest run -p miden-testing --lib kernel_tests::batch::batch_kernel(5 tests)make lintscripts/check-features.sh