0xMiden / 0xMiden/protocol

Smart Contract Diff Audit L-29: Private SWAP Payback Notes Are Deanonymized by Public SWAP Data

Offen
#3,688 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
Rust
Sterne
132
Forks
167
Ø Merge
1 T. 23 Std.
Gemergte PRs (30 T.)
110

Beschreibung

In private payback mode, [`SwapNote::create`](https://github.com/0xMiden/protocol/blob/8411bf093bde25285708faac152b6d7269009617/crates/miden-standards/src/note/swap.rs#L81-L124) builds the payback recipient as a P2ID recipient targeting the sender, with a serial number that [`payback_serial_from_swap`](https://github.com/0xMiden/protocol/blob/8411bf093bde25285708faac152b6d7269009617/crates/miden-standards/src/note/swap.rs#L397-L400) derives from the SWAP serial number by incrementing its least significant element, and embeds the resulting recipient digest into the SWAP note storage through [`SwapNoteStorage::new_private`](https://github.com/0xMiden/protocol/blob/8411bf093bde25285708faac152b6d7269009617/crates/miden-standards/src/note/swap.rs#L106-L110). That digest is produced by [`compute_recipient_digest`](https://github.com/0xMiden/protocol/blob/8411bf093bde25285708faac152b6d7269009617/crates/miden-protocol/src/note/recipient.rs#L78-L82) from the serial number, the note script root, and the storage commitment, and [`P2idNoteStorage`](https://github.com/0xMiden/protocol/blob/8411bf093bde25285708faac152b6d7269009617/crates/miden-standards/src/note/p2id.rs#L220-L222) holds nothing beyond the target account identifier. When the SWAP note itself is public, [`PublicOutputNote`](https://github.com/0xMiden/protocol/blob/8411bf093bde25285708faac152b6d7269009617/crates/miden-protocol/src/transaction/outputs/notes.rs#L550-L558) publishes the entire note, including storage and serial number, so every preimage of the stored payback digest becomes public.

Any passive observer can therefore recompute the payback recipient digest, confirm the account it targets, and derive the payback details commitment, which [`NoteDetailsCommitment`](https://github.com/0xMiden/protocol/blob/8411bf093bde25285708faac152b6d7269009617/crates/miden-protocol/src/note/note_details_commitment.rs#L36-L38) forms by merging that digest with the commitment to the requested asset, itself published in the SWAP storage. Blocks publish [`PrivateOutputNote`](https://github.com/0xMiden/protocol/blob/8411bf093bde25285708faac152b6d7269009617/crates/miden-protocol/src/transaction/outputs/notes.rs#L570-L575) headers carrying exactly that commitment, so the supposedly private payback note can be matched to the public SWAP without any privileged access or interaction. The payback [`Nullifier`](https://github.com/0xMiden/protocol/blob/8411bf093bde25285708faac152b6d7269009617/crates/miden-protocol/src/note/nullifier.rs#L46-L62) becomes computable for the same reason, since its serial number, script root, storage commitment, asset commitment, and metadata are all recoverable from public data, which removes the unlinkability between creation and consumption that a private note's secret serial number is meant to provide. No assets are exposed, because the P2ID script still restricts consumption to the target account, but the confidentiality property is not the one the code describes: [`swap.masm`](https://github.com/0xMiden/protocol/blob/8411bf093bde25285708faac152b6d7269009617/crates/miden-standards/asm/standards/notes/swap.masm#L22-L24) states that the stored digest is opaque and that the payback target cannot be learned from storage alone. The same derivation additionally allows the consumer of a private SWAP note to confirm the payback target.

Some correlation is unavoidable for a public SWAP note, since a consumer must be able to build the payback note, but the deterministic relationship between the two serial numbers is not required.

Consider drawing the payback serial number independently of the SWAP serial number in private payback mode, given that the private branch of the SWAP script consumes the precomputed recipient digest directly and never recomputes the serial number. Consider also revising the comments and documentation that present the stored payback recipient as opaque, so that the stated guarantee matches the behavior that the implementation delivers.

---

_Copied verbatim from finding [L-29](https://audits.openzeppelin.com/miden/miden-01-07-smart-contract-diff-audit-nfts/issues/private-swap-payback-notes-are-deanonymized-by-public-swap-data-9754a9a6) (low severity) of the OpenZeppelin [smart contract diff audit (NFTs)](https://audits.openzeppelin.com/miden/miden-01-07-smart-contract-diff-audit-nfts). The audit was performed against commit `8411bf093bde25285708faac152b6d7269009617`._

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.