feat: merge-train/barretenberg#23368
Open
AztecBot wants to merge 5 commits into
Open
Conversation
The HypernovaDecider is not showing up in our benchmark breakdown. This PR adds it do the components. It also adds the BatchMerge prover/verifier
federicobarbacovi
approved these changes
May 18, 2026
## 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.
Collaborator
Author
|
🤖 Auto-merge enabled after 4 hours of inactivity. This PR will be merged automatically once all checks pass. |
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.
BEGIN_COMMIT_OVERRIDE
chore: Add decider to benchmark components (#23170)
feat!: schnorr w/ poseidon2 (#21808)
END_COMMIT_OVERRIDE