chore(port): forward-port v5-next aztec-nr/contracts backlog to next - #24931
Merged
Conversation
I added a sanity check to avoid having messages implausibly far into the future, which would lead to them not getting evicted etc., but more importantly which would signal some inconsistency somewhere. (cherry picked from commit fdc2ac5)
…24665) ## Problem When encrypting a message, the ephemeral secret key comes from an unconstrained routine, so a malicious sender can substitute any value while proving. Substituting `eph_sk = 0` yields the point at infinity as the ephemeral public key, which passed the y-sign check: its y-coordinate is 0, which counts as positive. Its x-coordinate (0) is then broadcast, but 0 is not a valid x-coordinate on the curve, so the recipient can never reconstruct the key and the message is permanently undecryptable. This breaks the constrained-delivery guarantee that a note delivered by an untrusted sender remains decryptable by the recipient. ## Fix `generate_positive_ephemeral_key_pair` now asserts the ephemeral public key is not the point at infinity, alongside the existing sign check. A test emulates the substitution by mocking the randomness oracle to return 0. Fixes F-799 (cherry picked from commit 47c30a1)
## Problem Partial-note discovery has four crash points on the completion path, each reachable by a malicious sender and each firing before the pending note advances — so every subsequent sync re-hits it and permanently freezes note sync for that contract: - a matched completion log yields no note (`panic`), - a pending note resolves to more than one completion log (`assert`), - the delivered private half plus the log's public content exceed the packed-note capacity (`BoundedVec` overflow in the append), or - the completion log payload is empty, so reading the storage slot is out of bounds. The first three are reachable on the canonical token (mismatched content over the unconstrained delivery channel, completing the same partial note twice which the token does not prevent, and an over-length delivered private half); the last needs an attacker-controlled contract emitting a tag-only log. ## Fix Make each non-fatal: warn and advance the FSM rather than panicking, so one bad message cannot break sync. A completion log that cannot yield a note (empty, over-length, or matching none) is skipped; more than one completion log completes with the first. Fixes F-798 (cherry picked from commit 6489102)
## Summary - Documents the trust model of partial note completion on `PartialUintNote` and `PartialNFTNote`: - The validity commitment only proves that the contract created the partial note designating `completer`. - The storage slot and value/token id are trusted arguments, not bound by the commitment. - The completer is not authenticated by the check itself, so contracts must pass `msg_sender()` as `completer`. - Adds a WARNING that completion is not single-use: the designated completer can complete the same partial note any number of times, so contracts must make every completion independently paid for or authorized in the completing function (as the token and NFT contracts already do). - Fixes doc overclaims that said the validity commitment verifies the storage slot / state variable. (cherry picked from commit 1879ac1)
…#24844) ## Summary - AuthRegistry, MultiCallEntrypoint and PublicChecks hold no private state, but used the default `sync_state`, which performs pointless discovery RPC calls and embeds the HandshakeRegistry address in their bytecode. - Adds a shared `do_sync_state_no_op` handler to aztec-nr and wires it into those three contracts, plus SchnorrInitializerlessAccount, which previously carried its own local copy of the same no-op. - The pinned standard-contract artifacts are untouched, so shipped artifacts and addresses only change at the next intentional re-pin. (cherry picked from commit 3b4ba4a)
A contract with no notes might otherwise panic if e.g. it processed an offchain message related to one. I also made PXE skip the standard contracts that have no notes and events, both to avoid such a situation and because there's no need to do it. (cherry picked from commit dfcdea6)
With this, an L1->L2 message's `secret` need no longer be a single field but instead an array of fields. I moved the message nullifier computation from PXE into nr so that contracts can have different nullification schemes (e.g. those that don't depend exclusively on the contents of `secret`). Because the fee juice contract uses this oracle, I introduced an adaptor for it. (cherry picked from commit 9f1167e)
(cherry picked from commit 4490597)
This fixes an issue in which the note validation checks were not using the note's contract address to do the nhsk app siloing, but instead the _executing_ contract's address. This is because app siloing kernel requests can only be done for the current contract, but the helpers did not prevent usage on external contracts. They now contain an assertion preventing this, and have been renamed to reflect it. (cherry picked from commit 8b1903c)
#24689) ## Motivation The `#[note]` macro generated each `PropertySelector` from the field's position in the struct declaration, but selectors are applied to the note's packed representation. The two only agree when every field packs to one `Field`. For a note with a multi-slot field (a `Point`, an array, a nested struct), every filter on a later field silently constrained an unrelated packed slot — on the constrained read path, where these checks are what bind oracle-returned notes to the contract's criteria. A malicious PXE could satisfy a filter with a note that does not match it. No shipped contract is affected (all first-party filters target single-slot fields with single-slot predecessors); the bug was latent in the library. ## The change - Selector indices are the field's packed offset: the accumulated sum of preceding fields' `Packable::N`, mirroring `derive(Packable)`'s layout. - `PropertySelector<T>` carries the selected field's type. `select`/`sort` reject fields that pack to more than one `Field` at compile time (a one-slot criterion cannot express them), and `select`'s value is typed as the field's type. - Criterion values are compared as `value.pack()[0]` instead of `value.to_field()`, matching what the packed note slot actually contains. - `properties()` statically asserts the note's packed length equals the sum of its field packed lengths, so custom `Packable` layouts get a compile error directing to hand-written selectors instead of wrong ones. A same-length field reorder is not detectable; that residual gap is documented. - Breaking: hand-written `PropertySelector` literals need a type annotation, and every note field type must implement `Packable`. Migration notes included. All existing contracts compile to identical circuits; the PXE already applied indices to the packed layout, so no TS changes. ## Future changes The root cause is that two independent authorities describe the same layout: the note's `Packable` impl owns it, and the macro assumes it. Every assertion in this PR is a consistency check between the two, and one divergence (a custom pack that reorders fields at the same total length) cannot be checked at all and still fails silently. A potential fix (maybe there is a better one) is for the note macro to own the layout: `#[note]` derives `Packable` itself and generates the selectors from the same field list, making divergence impossible by construction, with an explicit custom-packing opt-out that generates neither and leaves both to the author. That is a larger breaking change to the macro surface and is left for a follow-up. Fixes F-800 (cherry picked from commit 10e339a)
Just a comment. (cherry picked from commit 15c7a1e)
(cherry picked from commit c3a2a85)
The v5-next pinned artifacts embed verification keys in a format this line's barretenberg no longer accepts, so the pin cannot be carried over verbatim. Regenerate it from the ported sources (forgery-protected handshake secrets, owner-bound initialization nullifiers) with this line's compiler and prover, moving all standard contracts to new canonical addresses.
Contributor
|
Cherry-picked the six outstanding commits onto this branch, plus two follow-ups their resolution required:
|
nchamo
enabled auto-merge
July 23, 2026 16:54
nchamo
approved these changes
Jul 23, 2026
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.
Forward-ports the noir / aztec-nr / contracts slice of the v5-next → next backlog (work merged to
v5-nextafter the ~2026-07-08 cut that reshapednext).Applied (clean cherry-picks, chronological)
next; not included here)Cherry-pick onto this branch and resolve:
git cherry-pick -x 9f1167e6d4— feat!: make inbox secrets be multiple fields (feat!: make inbox secrets be multiple fields #24599)git cherry-pick -x 4490597b1a— fix(aztec-nr): prevent recipient forging a colliding handshake (fix(aztec-nr): prevent recipient forging a colliding handshake #24403)git cherry-pick -x 8b1903c998— feat!: forbid external note validation checks (feat!: forbid external note validation checks #24644)git cherry-pick -x 10e339a580— fix(aztec-nr)!: compute note property selectors from the packed layout (fix(aztec-nr)!: compute note property selectors from the packed layout #24689)git cherry-pick -x 15c7a1e5a9— chore: clarify scope of packable impl detection (chore: clarify scope of packable impl detection #24820)git cherry-pick -x f66808caf0— fix: change init and single claim nullif to incl owner address, add testing utilities (fix: change init and single claim nullif to incl owner address, add testing utilities #24892)Part of the manual v5-next → next backlog sweep. Draft until conflicts are resolved and CI is green.