Skip to content

feat: minimal batch kernel#2905

Draft
mmagician wants to merge 1 commit into
mmagician-claude/batch-kernel-skeletonfrom
mmagician-claude/batch-kernel-logic
Draft

feat: minimal batch kernel#2905
mmagician wants to merge 1 commit into
mmagician-claude/batch-kernel-skeletonfrom
mmagician-claude/batch-kernel-logic

Conversation

@mmagician
Copy link
Copy Markdown
Collaborator

Summary

Second PR in the #2884 split. Stacks on top of #2904 (the skeleton kernel + ProvenBatch proof 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 by TRANSACTIONS_COMMITMENT into memory and asserts the sequential hash matches the public input. Then for each verified tx_id, pipes the felt sequence that TransactionId::new hashes and asserts the hash matches. Maintains the running min of expiration_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.masm rewritten to orchestrate the above and emit the real outputs.

Rust:

  • BatchId::hash_input_elements and TransactionId::input_elements are exposed as pub(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_inputs now populates the advice map with the layered structure the kernel walks.
  • LocalBatchProver::prove cross-checks the kernel's batch_expiration_block_num output against proposed_batch.batch_expiration_block_num().

Tests:

  • batch_kernel_happy_path now asserts the real commitments and expiration value instead of zeros.
  • Four tampering tests (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.masm enumerate the remaining checks (recursive ExecutionProof verification, intra-batch unauthenticated-note erasure, BLOCK_HASH verification, batch size limits, BatchNoteTree SMT 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 lint
  • scripts/check-features.sh

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 mmagician changed the title feat: batch kernel verification chain + tests feat: minimal batch kernel May 12, 2026
# AS: [len_felts, data...]

adv_push.1 div.4
# Stack: [num_words, TRANSACTIONS_COMMITMENT, TX_TUPLES_PTR]
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use pipe_preimage_to_memory instead and avoid the word equality assertion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants