0xMiden / 0xMiden/protocol

Note-asset commitment schemes are not interchangeable (kernel `remove_all_assets` vs the note's committed-assets commitment)

未关闭
#3,604 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
kernels
主要语言
Rust
星标
132
派生
167
平均合并
1 天 23 小时
30 天内合并 PR
110

描述

## Context

While implementing the fix for L-14 (#3601), the audit's suggested implementation turned out not to work as written, which surfaced a question about our note-asset hashing worth a wider look.

L-14 recommends that a note-claim script compare the commitment of the assets it removed against the note's committed-assets commitment and assert equality, so a prior full/partial removal is rejected. The finding states that the kernel `remove_all_assets` "already returns a sequential hash over the assets it removed, built with the same scheme the prologue uses to validate a note's committed assets," implying a single-word compare against `get_initial_assets_info` would suffice.

## Observation

In current `next` (`a95dc00a`) that equivalence does not hold: the `ASSETS_COMMITMENT` returned by the kernel `remove_all_assets` does not equal the note's stored assets commitment (`get_initial_assets_info`) even for an untouched note, and re-hashing the committed-asset buffer with `poseidon2::hash_double_words` also did not reproduce the stored commitment. This was found empirically while wiring up the L-14 check; I have not root-caused the exact divergence (the two absorb loops look structurally similar on a static read), so this issue is to get more eyes on it and decide the intended design.

There appear to be (at least) three routines that hash "a list of note assets," and they are not interchangeable:

1. Prologue committed-assets commitment - defines the note's stored assets commitment: [`process_note_assets`](https://github.com/0xMiden/protocol/blob/a95dc00a307e24c86c0a4f38f914c3e948dcb8b3/crates/miden-protocol/asm/kernels/transaction-core/src/prologue.masm#L664) uses `init_no_padding` then [`pipe_double_words_to_memory`](https://github.com/0xMiden/protocol/blob/a95dc00a307e24c86c0a4f38f914c3e948dcb8b3/crates/miden-protocol/asm/kernels/transaction-core/src/prologue.masm#L689) then `squeeze_digest`.
2. Kernel [`remove_all_assets`](https://github.com/0xMiden/protocol/blob/a95dc00a307e24c86c0a4f38f914c3e948dcb8b3/crates/miden-protocol/asm/kernels/transaction-core/src/input_note.masm#L242) - `init_no_padding`, then a per-asset `poseidon2::permute` loop that skips already-empty slots, then [`squeeze_digest`](https://github.com/0xMiden/protocol/blob/a95dc00a307e24c86c0a4f38f914c3e948dcb8b3/crates/miden-protocol/asm/kernels/transaction-core/src/input_note.masm#L311). It also stashes the removed assets into the advice map keyed by the resulting commitment.
3. `poseidon2::hash_double_words` - used as an independent recompute over an asset buffer in memory.

## Consequence for L-14

The one-word compare the audit suggested cannot be used as written; against the stored commitment it fails closed and would reject every legitimate full claim (breaking normal P2ID / SWAP / PSWAP consumption). The fix on branch `mmagician-claude/fix-l14-note-asset-claim-commitment` therefore sidesteps the question: each claim path hashes the note's committed assets and the removed assets with the *same* `hash_double_words` routine and compares those two, which is correct by construction (identical data hashed identically) regardless of how the kernel and prologue commitments relate. The cost is that we re-materialize and re-hash assets the kernel already hashed - `remove_all_assets` already produces an `ASSETS_COMMITMENT` and already has the removed assets in the advice map.

## Questions for the team

1. Are these routines meant to produce the same digest for the same asset list? If yes, the non-equivalence is a latent inconsistency to fix; if no, what are the intended domain separations?
2. Which scheme is canonical, and can the kernel `remove_all_assets` `ASSETS_COMMITMENT` be aligned with the note's committed-assets commitment?
3. If aligned, the L-14 claim check (and any future "did I claim the whole note?" consumer) simplifies to a single word-compare against `get_initial_assets_info`, and the redundant re-hash in the claim scripts can be dropped.

Happy to root-cause the exact divergence and write a focused repro test if that would help the discussion.

---

🤖 Created with [Claude Code](https://claude.com/claude-code)

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。