Skip to content

feat: insert unpadded note inputs into advice_inputs#2232

Merged
bobbinth merged 19 commits intonextfrom
mmagician-build-recipient
Jan 13, 2026
Merged

feat: insert unpadded note inputs into advice_inputs#2232
bobbinth merged 19 commits intonextfrom
mmagician-build-recipient

Conversation

@mmagician
Copy link
Copy Markdown
Collaborator

@mmagician mmagician commented Jan 6, 2026

For NoteInputs constructed from a values: Vec<Felt>, the advice map used be populated with:

  1. The commitment to the padded values -> vector of padded values
  2. Hash of the commitment -> number of un-padded values

With this PR, the first entry 1. changes to:

  1. The commitment to the un-padded values -> vector of un-padded values

Since we're now using the padded version of adv.push_mapvaln.8, the data written to memory stays the same (padded to the next multiple of 8), but the trailing zeros are not used to compute (and to verify) the commitment.

closes #2129 (although not by changing build_recipient, as indicated here)
closes #2036

EDIT: the first iteration still committed to padded values. Changed to commit to unpadded inputs

@mmagician mmagician force-pushed the mmagician-build-recipient branch from d089d6f to bc31d97 Compare January 6, 2026 13:06
@mmagician mmagician changed the base branch from mmagician-remove-lib-inputs-check to next January 6, 2026 13:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR changes how NoteInputs are stored in the advice map, moving from padded to unpadded values. This simplifies the assembly code by removing the need for rounding logic when reading note inputs.

Key changes:

  • NoteInputs::to_elements() now returns unpadded values instead of padded values
  • Assembly code uses adv.push_mapvaln.8 which handles padding automatically when reading from the advice map
  • Removed rounding logic in write_inputs_to_memory procedure that was previously needed to validate padded input counts

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
crates/miden-protocol/src/note/inputs.rs Modified to_elements() to return unpadded values, simplifying the API while maintaining correct commitment computation
crates/miden-protocol/asm/protocol/active_note.masm Changed to adv.push_mapvaln.8 and removed rounding logic, as padding is now handled by the VM instruction
crates/miden-testing/src/kernel_tests/tx/test_note.rs Updated test cases to use 8 values (exact block size) instead of 13, and added assertions to verify advice map contents contain unpadded values
CHANGELOG.md Documented the breaking change in advice map format

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mmagician mmagician requested a review from bobbinth January 8, 2026 15:29
@mmagician mmagician marked this pull request as ready for review January 8, 2026 15:29
Copy link
Copy Markdown
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you! I left a few small comments inline.

Comment on lines +313 to +321
# drop the hasher state and dest_ptr'
dropw dropw dropw drop
# OS => [NOTE_INPUTS_COMMITMENT, num_inputs, dest_ptr]

# compute and validate the inputs commitment (over the unpadded values)
dup.5 dup.5 swap
exec.note::compute_inputs_commitment
assert_eqw.err=ERR_NOTE_DATA_DOES_NOT_MATCH_COMMITMENT
# => [num_inputs, dest_ptr]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We don't really need to call compute_inputs_commitment here. The pipe_words_to_memory (or pipe_double_words_to_memory) have already done the heavy-lifting of computing the hash - so, we just need to extract it from the stack. This could be done like so:

# => [C, B, A, dest_ptr', NOTE_INPUTS_COMMITMENT, num_inputs, dest_ptr]

exec.rpo256::squeeze_digest
# => [COMPUTED_COMMITMENT, dest_ptr', NOTE_INPUTS_COMMITMENT, num_inputs, dest_ptr]

movup.4 drop
# => [COMPUTED_COMMITMENT, NOTE_INPUTS_COMMITMENT, num_inputs, dest_ptr]

assert_eqw.err=ERR_NOTE_DATA_DOES_NOT_MATCH_COMMITMENT
# => [num_inputs, dest_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.

The issue with this is that pipe_words_to_memory computes the hash over the padded inputs (we need to pad with zeros to obtain full words for copying) - and with this PR, we've switched to committing to unpadded inputs, so the results will mismatch.

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 agree this is a bit wasteful - we're only using the instruction to move data from advice stack to memory, and performing the verification separately. Ideally we'd have either a way to:

  • A) purely move words to memory without hashing, call it copy_words_to_memory
  • B) pipe an arbitrary number of elements, with the hashing done with exec.rpo256::hash_elements - i.e. similar to the current pipe_{words/double_words}_to_memory, but one that works over the exact number of elements, not full words. Call it pipe_elements_to_memory.

I can foresee use cases for both instructions, so maybe both are useful independently of which approach we take here?


In any case for this PR we won't have this instruction in miden-vm ready. But once the new instruction(s) is available, I'd prefer approach B) here, as actually reduces the surface of exposed procedures and lets us get rid of the note::compute_inputs_commitment procedure (pipe_elements_to_memory would take care of exactly computing the inputs commitment)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The issue with this is that pipe_words_to_memory computes the hash over the padded inputs (we need to pad with zeros to obtain full words for copying) - and with this PR, we've switched to committing to unpadded inputs, so the results will mismatch.

This shouldn't be an issue. Because of how the padding rule works for RPO, padding the last permutation with zeros should not change the resulting hash. Previously, there was an issue which how to do this but adv.push_mapvaln.8 instruction solves this.

So, we should be able to use pipe_double_words_to_memory and then just get the digest from the values on the stack. This would avoid the need to hash the memory again.

purely move words to memory without hashing, call it copy_words_to_memory

This could work but it would double the cost (in terms of the number of cycles and memory accesses). The main idea of pipe_double_words_to_memory (and other instructions) is that we can copy to memory and hash at the same time. The ability to specify the padding amount adv.push_mapvaln let's us work with any number of inputs.

pipe an arbitrary number of elements, with the hashing done with exec.rpo256::hash_elements - i.e. similar to the current pipe_{words/double_words}_to_memory, but one that works over the exact number of elements, not full words. Call it pipe_elements_to_memory.

We could (and maybe should) add such a procedure - but it would be much more expensive (like several times more expensive) then the pipe_double_words_to_memory approach.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In any case for this PR we won't have this instruction in miden-vm ready. But once the new instruction(s) is available, I'd prefer approach B) here, as actually reduces the surface of exposed procedures and lets us get rid of the note::compute_inputs_commitment procedure (pipe_elements_to_memory would take care of exactly computing the inputs commitment)

The main motivation for introducing adv.push_mapvaln.8 was to avoid using such a procedure :)

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.

@mmagician mmagician requested a review from bobbinth January 9, 2026 09:47
@mmagician mmagician requested a review from bobbinth January 13, 2026 10:16
Copy link
Copy Markdown
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you!

@bobbinth bobbinth merged commit b82dc0b into next Jan 13, 2026
19 checks passed
@bobbinth bobbinth deleted the mmagician-build-recipient branch January 13, 2026 23:37
afa7789 pushed a commit to afa7789/miden-base that referenced this pull request Jan 15, 2026
afa7789 pushed a commit to afa7789/miden-base that referenced this pull request Jan 15, 2026
Farukest added a commit to Farukest/miden-base that referenced this pull request Jan 31, 2026
Since note storage items are no longer padded (after PR 0xMiden#2232), the
actual length of storage_items in the advice map equals num_items.
The separate advice map entry for storage item count is therefore
redundant.

This change removes:
- The advice map entry inserting num_storage_items (tx_args.rs)
- The lookup and validation of num_storage_items (kernel_process.rs)
- The test assertion for the removed advice map entry (test_note.rs)

Closes 0xMiden#2317
Farukest added a commit to Farukest/miden-base that referenced this pull request Jan 31, 2026
Since note storage items are no longer padded (after PR 0xMiden#2232), the
actual length of storage_items in the advice map equals num_items.
The separate advice map entry for storage item count is therefore
redundant.

This change removes:
- The advice map entry inserting num_storage_items (tx_args.rs)
- The lookup and validation of num_storage_items (kernel_process.rs)
- The test assertion for the removed advice map entry (test_note.rs)

Closes 0xMiden#2317
Farukest added a commit to Farukest/miden-base that referenced this pull request Jan 31, 2026
Since note storage items are no longer padded (after PR 0xMiden#2232), the
actual length of storage_items in the advice map equals num_items.
The separate advice map entry for storage item count is therefore
redundant.

This change removes:
- The advice map entry inserting num_storage_items (tx_args.rs)
- The lookup and validation of num_storage_items (kernel_process.rs)
- The test assertion for the removed advice map entry (test_note.rs)

Closes 0xMiden#2317
PhilippGackstatter added a commit that referenced this pull request Feb 2, 2026
Since note storage items are no longer padded (after PR #2232), the
actual length of storage_items in the advice map equals num_items.
The separate advice map entry for storage item count is therefore
redundant.

This change removes:
- The advice map entry inserting num_storage_items (tx_args.rs)
- The lookup and validation of num_storage_items (kernel_process.rs)
- The test assertion for the removed advice map entry (test_note.rs)

Closes #2317

Co-authored-by: Philipp Gackstatter <PhilippGackstatter@users.noreply.github.com>
afa7789 pushed a commit to afa7789/miden-base that referenced this pull request Mar 9, 2026
…den#2376)

Since note storage items are no longer padded (after PR 0xMiden#2232), the
actual length of storage_items in the advice map equals num_items.
The separate advice map entry for storage item count is therefore
redundant.

This change removes:
- The advice map entry inserting num_storage_items (tx_args.rs)
- The lookup and validation of num_storage_items (kernel_process.rs)
- The test assertion for the removed advice map entry (test_note.rs)

Closes 0xMiden#2317

Co-authored-by: Philipp Gackstatter <PhilippGackstatter@users.noreply.github.com>
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.

note::build_recipient should insert padded inputs into advice map Trial Unhashing in extract_note_inputs May Be Unnecessary

3 participants