Skip to content

feat: merge-train/barretenberg#23368

Open
AztecBot wants to merge 5 commits into
nextfrom
merge-train/barretenberg
Open

feat: merge-train/barretenberg#23368
AztecBot wants to merge 5 commits into
nextfrom
merge-train/barretenberg

Conversation

@AztecBot
Copy link
Copy Markdown
Collaborator

@AztecBot AztecBot commented May 18, 2026

BEGIN_COMMIT_OVERRIDE
chore: Add decider to benchmark components (#23170)
feat!: schnorr w/ poseidon2 (#21808)
END_COMMIT_OVERRIDE

The HypernovaDecider is not showing up in our benchmark breakdown. This
PR adds it do the components.

It also adds the BatchMerge prover/verifier
AztecBot and others added 2 commits May 18, 2026 15:40
## Summary

Switches Schnorr from `pedersen(R.x ‖ pubkey.x ‖ pubkey.y) → blake2s(… ‖
message)` to a single `Poseidon2(R.x, pubkey.x, pubkey.y, message)`
end-to-end. Affects the native signer in bbapi, the in-circuit verifier
(consumed via noir-lang/schnorr `v0.2.0` → `v0.3.0`), and the on-wire
auth witness shape for both schnorr account contracts.

## Changes

**Native (cpp)**
- `barretenberg/cpp/src/barretenberg/crypto/schnorr/*` — challenge
derivation switched to Poseidon2 over `(R.x, pubkey.x, pubkey.y,
message_field)`. Drops the `Hash` and `Fq` template parameters;
signer/verifier now take the message as a grumpkin base field element
directly.
- `barretenberg/cpp/src/barretenberg/bbapi/bbapi_schnorr.cpp` — asserts
the bbapi message buffer is exactly 32 bytes (a serialized field
element) and deserializes it into `grumpkin::fq`.
- New pinned test vectors (`pinned_test_vector_small`,
`pinned_test_vector_large`) that fix the `(private_key, nonce_k,
message) → (public_key, R, s, e)` mapping for cross-implementation
regression.

**Noir contracts**
- `schnorr_account_contract` and `schnorr_hardcoded_account_contract`:
bump pinned `noir-lang/schnorr` from `v0.2.0` to `v0.3.0`.
- Both `is_valid_impl` callsites rewritten to pass `outer_hash` as
`Field` (not `[u8; 32]`) and the signature as `(EmbeddedCurveScalar,
EmbeddedCurveScalar)` (not `[u8; 64]`).

**TS (bb.js authwit emitters)**
- New `SchnorrSignature.toLimbFields()` returning `[s.lo, s.hi, e.lo,
e.hi]` (top-16-bytes = hi, bottom-16-bytes = lo, BE).
- All four schnorr authwit producers updated: `@aztec/accounts/schnorr`,
`txe_oracle_top_level_context`,
`end-to-end/fixtures/schnorr_hardcoded_account_contract`,
`end-to-end/guides/writing_an_account_contract`.
- Foundation schnorr test now signs a 32-byte field-element message (the
freeform-string preimage was incompatible with the new bbapi 32-byte
assert).

**VKs**
- Standalone Chonk VKs shift for every flow that compiles a schnorr
account contract.
- Regenerated `example-app-ivc-inputs-out/` via `build_bench`,
re-uploaded `bb-chonk-inputs-45ff0930.tar.gz` to S3, and bumped the
pinned hash in `test_chonk_standalone_vks_havent_changed.sh`. All 11
flows pass `prove+verify` against the new inputs.

## In-circuit efficiency

Per-tx `is_valid_impl` for schnorr-account flows replaces, in-circuit,
pedersen-of-3-inputs + blake2s-of-1-block + 32 byte-range checks for the
message + 64 byte-range checks for the authwit, with one Poseidon2
permutation. Net: a few thousand gates removed from every fold step in
schnorr-account flows. ECDSA flows unaffected.

## Security review summary

Two specific concerns scrutinized:

1. **Limb range enforcement.** noir's `EmbeddedCurveScalar::new(lo, hi)`
does no checks; soundness depends on `multi_scalar_mul`
(foreign-dispatched to barretenberg's `to_grumpkin_scalar →
cycle_scalar(lo, hi)`) enforcing `lo < 2^128`, `hi < 2^126`, and `lo +
hi·2^128 < grumpkin_scalar_modulus`. Confirmed: range constraints
applied via `create_limbed_range_constraint` inside
`cycle_group::batch_mul` (both Straus and constant-infinity paths), with
`validate_scalar_is_in_field` enforcing the modulus bound. No forgery
possible. There is a benign non-uniqueness — at most two integer
representations in `[0, bb::fq_modulus)` can reduce to the same `bb::fr`
residue — but auth witness nullifiers key off `message_hash` not the
signature payload, so this is not exploitable.
2. **Test vector cross-check.** Ran cpp
`pinned_test_vector_{small,large}` and noir-lang/schnorr v0.3.0
`pinned_vector_{small,large}` against the same `(private_key, message)`
inputs. Cpp produces `s` / `e` byte-for-byte matching the noir test's
`(sig_s.hi, sig_s.lo)` / `(sig_e.hi, sig_e.lo)` limbs, and the noir
verifier accepts the signatures in-circuit.

## Breaking change

Existing schnorr accounts on testnet cannot be signed for by the new TS
code — both the challenge hash function and the authwit wire format
change. Users must migrate to a freshly-deployed schnorr account. ECDSA
accounts unaffected.
@AztecBot AztecBot added this pull request to the merge queue May 18, 2026
@AztecBot
Copy link
Copy Markdown
Collaborator Author

🤖 Auto-merge enabled after 4 hours of inactivity. This PR will be merged automatically once all checks pass.

@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants