Skip to content

Upgrade to noir v1.0.0-beta.19 and adopt official barretenberg-rs#37

Merged
moven0831 merged 7 commits into
mainfrom
upgrade-noir-beta19
Apr 16, 2026
Merged

Upgrade to noir v1.0.0-beta.19 and adopt official barretenberg-rs#37
moven0831 merged 7 commits into
mainfrom
upgrade-noir-beta19

Conversation

@moven0831
Copy link
Copy Markdown
Contributor

Summary

  • Migrates from the custom bb/ crate (hand-written C FFI + download_bb.sh pulling from the zkmopro/aztec-packages fork) to the official barretenberg-rs crate from crates.io.
  • Bumps noir-lang dependencies from v1.0.0-beta.8 (commit b331315, July 2025) to v1.0.0-beta.19 (Feb 2026).
  • Deletes ~800 lines of unsafe FFI bindings and shell-based build plumbing. Future noir upgrades become a Cargo.toml version bump.

Closes #36
Supersedes #34

What changed

Dependencies (noir/Cargo.toml)

  • acvm, bn254_blackbox_solver, nargo, acvm_blackbox_solverv1.0.0-beta.19
  • Drop separate acir dep; access via acvm::acir::*
  • Add barretenberg-rs = "=4.2.0-aztecnr-rc.2" with the ffi feature (version matches zkpassport/noir_rs)
  • Add keccak = "=0.2.0-rc.0" (workaround for a breaking-change not following semver)
  • Drop openssl dep and android-compat feature (reqwest already uses rustls-tls)
  • Drop x86_64-apple-ios target (barretenberg-rs has no prebuilt binaries for Intel iOS simulator; Apple Silicon since M1)

New abstraction layer (noir/src/backends/barretenberg/api.rs)

Thin wrapper around barretenberg_rs::BarretenbergApi<FfiBackend>:

  • circuit_prove / circuit_verify / circuit_stats / circuit_compute_vk / srs_init
  • settings_ultra_honk_poseidon2() and settings_ultra_honk_keccak(disable_zk) for ProofSystemSettings
  • configure_memory(enabled, max_storage_usage) writes BB_SLOW_LOW_MEMORY / BB_STORAGE_BUDGET env vars AND the C globals slow_low_memory / storage_budget directly — fine-grained mobile memory control beyond the old boolean flag
  • proof_fields_to_bytes / proof_bytes_to_fields helpers for the Vec<Vec<u8>> ↔ flat Vec<u8> conversion

Module ports

  • prove.rs / verify.rs: now route through api.rs. Proofs use the [4-byte BE num_pub][public_inputs][proof] format so verify_* can split fields without a side-channel num_public_inputs parameter. New _with_options variants expose max_storage_usage: Option<u64>; existing function signatures preserved for mopro compatibility.
  • srs/mod.rs: initializes SRS via api::srs_init. Applies an 8× multiplier on the dyadic gate count to account for UltraHonk's witness/permutation/lookup polynomial overhead (previously implicit in the old C backend's sizing).
  • utils.rs: uses circuit_stats() and adds get_circuit_size_dyadic(). get_circuit_size now returns num_gates_dyadic (safe lower bound for SRS allocation).
  • circuit.rs: get_acir_buffer_uncompressed() round-trips through Program::deserialize_program / serialize_program so the ACIR handed to barretenberg matches NOIR_SERIALIZATION_FORMAT (adopted from zkpassport/noir_rs).
  • witness.rs:
    • Replace bincode::serialize with WitnessStack::serialize() + gzip decompression (the format barretenberg expects in beta.19).
    • Bug fix: from_vec_str_to_witness_map previously returned FieldElement::default() (zero) for invalid hex/decimal strings via unwrap_or_default(). Now returns a descriptive Err so invalid inputs can't silently produce a proof for the wrong witness.
  • execute.rs: switches to acvm::acir:: imports. Logic unchanged.

Proof utilities (noir/src/utils/proof_utils.rs)

Updated for the new [4-byte prefix][inputs][proof] format. Cross-validates the embedded count against the caller-supplied num_public_inputs so mismatches surface immediately.

Dead code

Removed noir/src/backends/barretenberg/recursion.rs — it was commented out and already referenced the old bb_rs crate name from a stale migration attempt.

What's NOT in this PR

  • Recursive proving (already commented-out before this PR; revive in a follow-up)
  • The ProverBackend trait that would enable PipeBackend / WASM / mock backends (considered during review, deferred as a separate change)
  • mopro CLI template updates (separate repo — see zkmopro/mopro followup)

Test plan

  • cargo test --all-features test_prove_and_verify_ultra_honk (Ultra Honk Poseidon2 prove + verify, ~32ms on macOS arm64)
  • cargo test --all-features test_ultra_honk_keccak (Ultra Honk Keccak prove + verify, ~930ms with keccak circuit)
  • cargo test --all-features test_prove_and_verify_ultra_honk_keccak_product (proof_utils parse/combine round-trip)
  • cargo test --all-features test_acir_get_circuit_size (circuit_stats integration)
  • cargo test --all-features test_circuit_format_round_trip (ACIR format safety)
  • cargo test --all-features test_invalid_witness_input_error (witness error propagation)
  • cargo test --all-features test_compute_subgroup_size (utility sanity)
  • cargo test --all-features test_srs_setup_from_bytecode / test_srs_setup_from_circuit_size (SRS init)
  • CI: build iOS (aarch64-apple-ios, aarch64-apple-ios-sim) and Android (aarch64-linux-android, x86_64-linux-android) — will verify on PR
  • test_ultra_honk_low_memory (keccak_large, needs to run on CI hardware — local macOS arm64 OOM during proving, as expected)

Commits

  1. feat: upgrade to noir v1.0.0-beta.19 and adopt official barretenberg-rs — the actual migration (42 files, +1117/−1965)
  2. test: load product circuit at runtime and add beta.19 coverage — tests now read circuits/target/product.json instead of hardcoded bytecode; add invalid-witness and circuit-format-round-trip tests
  3. ci: update workflow for nargo v1.0.0-beta.19 and drop x86_64-apple-ios

🤖 Generated with Claude Code

moven0831 and others added 7 commits April 13, 2026 13:41
Migrates from the custom bb/ crate (hand-written C FFI bindings + custom
download_bb.sh) to the official barretenberg-rs crate from crates.io.

Key changes:
- Delete bb/ crate entirely (~800 lines of unsafe FFI + build scripts)
- Add barretenberg-rs = "=4.2.0-aztecnr-rc.2" with ffi feature
- Bump noir-lang deps to v1.0.0-beta.19 (acvm, bn254_blackbox_solver, nargo, acvm_blackbox_solver)
- Drop separate acir dep (now accessed via acvm::acir::*)
- Add keccak = "=0.2.0-rc.0" pin (beta.19 breaking-change workaround)
- Drop android-compat feature and openssl dep (not needed with rustls-tls)
- Remove x86_64-apple-ios target (no prebuilt binaries; Intel Mac obsolete)

New abstraction:
- noir/src/backends/barretenberg/api.rs wraps barretenberg-rs's FfiBackend +
  BarretenbergApi with settings helpers, proof flattening, and configure_memory()
  that writes to C globals (slow_low_memory, storage_budget) for fine-grained
  mobile memory control.

Module ports:
- prove.rs / verify.rs now route through api.rs; proofs use the
  [4-byte BE num_pub][public_inputs][proof] format so verify can split fields
  without a side-channel num_public_inputs parameter.
- srs/mod.rs initializes SRS via api::srs_init; includes UltraHonk's 8x point
  overhead for witness/permutation/lookup polynomials.
- utils.rs uses circuit_stats() and exposes get_circuit_size_dyadic().
- circuit.rs round-trips through Program::deserialize_program / serialize_program
  so the ACIR handed to barretenberg matches NOIR_SERIALIZATION_FORMAT.
- witness.rs replaces bincode::serialize with WitnessStack::serialize() + gzip
  decompression; fixes unwrap_or_default() bug so invalid hex/decimal strings
  in from_vec_str_to_witness_map now return an error instead of silently
  mapping to zero.
- execute.rs switches to acvm::acir:: imports.

Proof utilities:
- proof_utils.rs updated to the new [4-byte prefix][inputs][proof] format,
  with cross-validation between the embedded count and caller-supplied value.

Dead code cleanup:
- Remove commented-out recursion.rs (referenced the old bb_rs crate name).

Closes #36
Supersedes #34

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previous tests hardcoded a base64 bytecode constant that was compiled with
nargo 1.0.0-beta.8 and is incompatible with beta.19's ACIR format.

Changes:
- Replace the inline BYTECODE constant with load_product_bytecode() that
  reads circuits/target/product.json, so tests always use artifacts that
  match the installed nargo version.
- Update proof_utils tests to use the product circuit (same a * b == result
  shape as the old Multiplier2, with 1 public input).
- Add test_invalid_witness_input_error to cover the from_vec_str_to_witness_map
  error-propagation fix (previously silently returned zero).
- Add test_circuit_format_round_trip to cover Program::deserialize_program +
  serialize_program, catching ACIR format drift across noir versions.
- Replace acir_get_slow_low_memory assertions with get_slow_low_memory() from
  api.rs (reads the same C global the old bb crate exposed).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Bump nargo toolchain from 1.0.0-beta.8 to 1.0.0-beta.19 across all jobs
- Drop x86_64-apple-ios target and its build step (barretenberg-rs has no
  prebuilt binaries for Intel iOS simulator; Apple Silicon only since M1)
- Remove bb/target/ from cargo build cache paths (crate no longer exists)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… gates

Previously setup_srs() applied the 8x UltraHonk overhead multiplier on every
caller, which broke test_srs_setup_from_circuit_size (expected 33 points,
got 257) and any consumer that computes their own SRS size.

Move the multiplier into setup_srs_from_bytecode() where we actually derive
size from the raw dyadic gate count. setup_srs() now treats its argument as
the final desired subgroup size (no scaling).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… on Linux

- Add the product circuit to the circuit build step. Tests load it at runtime
  via circuits/target/product.json, so CI has to compile it alongside keccak
  and keccak_large.
- Remove the test-x86_64 job entirely. The macos-13 runner is no longer
  supported ("configuration 'macos-13-us-default' is not supported"), and
  Intel Macs are EOL (Apple Silicon only since M1 in 2020).
- Move the x86_64-linux-android cross-compile build to the test-linux job so
  we still verify that Android target on every PR.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The default reqwest blocking client has no overall timeout and relies on
TCP keepalive settings. On CI runners with slow/flaky network paths to
crs.aztec.network this was flaking the keccak_large low-memory test with
reqwest::Error { kind: Decode, source: TimedOut }.

Add an explicit 5 minute timeout to the blocking Client. That covers
legitimate large SRS downloads (tens of MB for >262k points) while still
failing fast on genuine outages. Also swap `.unwrap()` for `.expect()` with
descriptive messages so future failures are easier to diagnose.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously jobs were named inconsistently ("test-aarch64" named an
architecture, "test-linux" named an OS). Reorganize into four jobs, each
scoped to one target platform. This makes the matrix match the README's
supported-targets section and surfaces per-platform failures independently.

- test-macos (macos-latest runner): runs cargo test natively, builds
  aarch64-apple-darwin and x86_64-apple-darwin (the latter cross-compiled
  from the arm64 runner, restoring coverage lost with the deprecated
  macos-13 runner).
- test-ios (macos-latest runner): cross-compiles aarch64-apple-ios and
  aarch64-apple-ios-sim. Does not run tests (no simulator in CI).
- test-linux (ubuntu-latest runner): runs cargo test natively, builds
  x86_64-unknown-linux-gnu.
- test-android (ubuntu-latest runner): cross-compiles aarch64-linux-android
  and x86_64-linux-android via cargo-ndk. Linux runner for cost; Android
  builds do not need macOS. Does not run tests (no emulator in CI).

Also switch the feature flag on macOS and Linux build steps from the legacy
`ios-build` alias to `barretenberg` directly. iOS and Android retain their
platform-specific feature flags for clarity.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@moven0831 moven0831 force-pushed the upgrade-noir-beta19 branch from 6d6d3f1 to 6041729 Compare April 15, 2026 07:11
@moven0831 moven0831 merged commit 0e4fdc9 into main Apr 16, 2026
8 checks passed
heeckhau added a commit to tlsnotary/tlsn that referenced this pull request Apr 22, 2026
zkmopro/noir-rs#37 migrated off the custom bb/ FFI crate to the official
barretenberg-rs crate from crates.io, and bumped the noir-lang deps from
v1.0.0-beta.8 to v1.0.0-beta.19.

* crates/examples/Cargo.toml: bump noir-rs tag.
* basic_zk/noir/Nargo.toml: bump sha256 to v0.3.0 and noir-date to v0.5.6
  for nargo v1.0.0-beta.19 compatibility.
* basic_zk/noir/src/main.nr: drop deprecated `dep::` import prefix.
* basic_zk/noir/target/noir.json: recompile with nargo v1.0.0-beta.19
  (ACIR serialization format changed).
* basic_zk/verifier.rs: adjust public-input extraction for the new proof
  layout. noir-rs beta.19 prefixes proof bytes with a 4-byte BE
  num_public_inputs, so the date and hash offsets now start from
  proof[4..]. Also validates num_pub == 35.
* basic_zk/README.md: update noirup version and simplify bbup invocation.
@ytanaka6174
Copy link
Copy Markdown

Thank you for this! This resolves some custom workarounds I needed for circuit/verifier compatibility.

Just wanted to mention it would be good to update the doc page here.
Screenshot 2026-04-29 at 12 56 30 PM

@moven0831
Copy link
Copy Markdown
Contributor Author

Thanks for the nudge, @ytanaka6174! Both follow-ups have landed:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade to Noir v1.0.0-beta.19

2 participants