Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ jobs:
matrix:
adapter: [circom, halo2, noir, gnark]
runs-on: ubuntu-latest
timeout-minutes: 15
timeout-minutes: 20
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
steps:
- uses: actions/checkout@v6
Expand Down Expand Up @@ -317,7 +317,7 @@ jobs:
- name: Run tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 29
api-level: 30
target: google_apis
arch: x86_64
disable-animations: true
Expand Down
3 changes: 1 addition & 2 deletions cli/src/init/noir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ serde_json = "1.0.94"

noir_rs = { package = "noir", git = "https://github.com/zkmopro/noir-rs", features = [
"barretenberg",
"android-compat",
], branch = "v1.0.0-beta.8-3" }
], tag = "v1.0.0-beta.19" }
"#;

const DEV_DEPENDENCIES: &'static str = r#"
Expand Down
5 changes: 3 additions & 2 deletions cli/src/template/init/src/noir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ mod tests {
const MULTIPLIER2_CIRCUIT_FILE: &str = "./test-vectors/noir/noir_multiplier2.json";
const SRS_FILE: &str = "./test-vectors/noir/noir_multiplier2.srs";
const VK_FILE: &str = "./test-vectors/noir/noir_multiplier2.vk";
const VK_POSEIDON_FILE: &str = "./test-vectors/noir/noir_multiplier2_poseidon.vk";

use super::*;

Expand Down Expand Up @@ -440,7 +441,7 @@ mod tests {
#[serial_test::serial]
fn test_noir_proof_with_poseidon_and_vk() {
let witness = vec!["3".to_string(), "5".to_string()];
let vk = std::fs::read(VK_FILE).unwrap();
let vk = std::fs::read(VK_POSEIDON_FILE).unwrap();
let proof = generate_noir_proof_with_poseidon(
MULTIPLIER2_CIRCUIT_FILE.to_string(),
Some(SRS_FILE.to_string()),
Expand Down Expand Up @@ -518,7 +519,7 @@ mod tests {
#[serial_test::serial]
fn test_high_level_noir_proof_poseidon_with_vk() {
let witness = vec!["3".to_string(), "5".to_string()];
let vk = std::fs::read(VK_FILE).unwrap();
let vk = std::fs::read(VK_POSEIDON_FILE).unwrap();
let proof = generate_noir_proof(
MULTIPLIER2_CIRCUIT_FILE.to_string(),
Some(SRS_FILE.to_string()),
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"noir_version":"1.0.0-beta.8+ba05d729b9753aa5ce2b076c1dd4795edb173f68","hash":"6444577228291194090","abi":{"parameters":[{"name":"a","type":{"kind":"field"},"visibility":"private"},{"name":"b","type":{"kind":"field"},"visibility":"private"},{"name":"result","type":{"kind":"field"},"visibility":"public"}],"return_type":null,"error_types":{}},"bytecode":"H4sIAAAAAAAA/62QQQqAMAwErfigpEna5OZXLLb/f4KKLZbiTQdCQg7Dsm66mc9x00O717rhG9ico5cgMOfoMxJu4C2pAEsKioqisnslysoaLVkEQ6aMRYxKFc//ZYQr29L10XfhXv4jB52E+OpMAQAA","debug_symbols":"lZDBCoMwDIbfJeceZKADX2UMqTVKIaQltoMhvvuirJsedtgpTf5+f8i/wIB9njrPY5ihvS3QiyfyU0fB2eQD63RZDZS2S4KoIzjoSkUryAlazkQGHpby/mmOlvearKhaGUAetKrh6Am312q+dPUbbQrb1B+4/p++num7dtZ5OV0LFbSXdTMTb3vCdwJjZncIJD1jUUpkUYLDIQtudrumC14=","file_map":{},"names":["main"],"brillig_names":[]}
{"noir_version":"1.0.0-beta.19+74d6be658e1ad252f87943292ba09bdd4da80bd4","hash":"5676549021197598584","abi":{"parameters":[{"name":"a","type":{"kind":"field"},"visibility":"private"},{"name":"b","type":{"kind":"field"},"visibility":"private"},{"name":"result","type":{"kind":"field"},"visibility":"public"}],"return_type":null,"error_types":{}},"bytecode":"H4sIAAAAAAAA/4XMPQ5AMBiA4aqLGNmIE4hITGIUiUHCYPCTshh7g37tYDWYHEDYXaSb0WLXE/DObx6dw7TUedVgoKvX9yUZ0pK0AsRpoO80pAE/DbuIiHRma4+DjdIkM90rHI8OfPmIW234F0JcSZgx9gL3WmBNjQAAAA==","debug_symbols":"lZDBCoMwDIbfJece3GAOfJUxpNYohZCW2A6G+O6Lsm562GGnNPn7/SH/DD12eWw9D2GC5jZDJ57Ijy0FZ5MPrNN5MVDaNgmijmCnKxWtICdoOBMZeFjK26cpWt5qsqJqZQC516qGgydcX4v50tVvtC5sffnAl9Pf9PVI37WzzsvhWqigOS+rmXjbEb4TGDK7XSDpGYtSIosSHPZZcLXbNF3wAg==","file_map":{"51":{"source":"fn main(a: Field, b: Field, result: pub Field) {\n assert(a * b == result);\n}\n\n#[test]\nfn test_main() {\n main(3, 5, 15);\n}\n","path":"/Users/moventsai/Projects/mobile-proving/zkmopro/mopro/test-vectors/noir/multiplier2/src/main.nr"}}}
Binary file modified cli/src/template/init/test-vectors/noir/noir_multiplier2.srs
Binary file not shown.
Binary file modified cli/src/template/init/test-vectors/noir/noir_multiplier2.vk
Binary file not shown.
Binary file not shown.
6 changes: 6 additions & 0 deletions docs/blog/2025-05-12-noir-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ Our current implementation draws heavily from the zkPassport team’s work, whic

Expanding support to these platforms is a significant challenge. The `barretenberg` backend, written in C++ and built with CMake, is large and complex, making cross-compilation non-trivial. While we’re evaluating the effort required to support additional architectures, we’re also hopeful that the Noir or zkPassport teams may address this gap in the future.

:::note Update (noir-rs v1.0.0-beta.19)

As of `noir-rs` `v1.0.0-beta.19`, mopro pulls Barretenberg via the official [`barretenberg-rs`](https://crates.io/crates/barretenberg-rs) crate from crates.io rather than the `publish-bb.yml` pipeline in `zkmopro/aztec-packages` referenced above. The `x86_64-apple-ios` target was also dropped in that upgrade — `barretenberg-rs` does not ship prebuilt binaries for the Intel iOS simulator. The rest of the support matrix is unchanged.

:::

## Case Study: Stealthnote Mobile App

During the NoirHack 2025 (April 14th to May 10th), the Mopro team participated by building a mobile-native Noir application. Our project was inspired by [**Stealthnote**](https://stealthnote.xyz/), originally created by Saleel. Stealthnote is a web-based app that allows users to sign in with Google OAuth and prove ownership of their organizational email address. It leverages a Noir circuit to generate a zero-knowledge proof from the JWT issued by Google OAuth. You can read more about the original project in [Saleel’s blog post](https://saleel.xyz/blog/stealthnote/).
Expand Down
10 changes: 4 additions & 6 deletions docs/docs/adapters/noir.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,16 @@ To get started, follow the [Rust Setup Guide](/setup/rust-setup.md) and ensure t
[dependencies]
noir_rs = { package = "noir", git = "https://github.com/zkmopro/noir-rs", features = [
"barretenberg",
"android-compat",
], branch = "v1.0.0-beta.8-3" }
], tag = "v1.0.0-beta.19" }
# ...
```

:::info
The Noir adapter depends on [`zkmopro/noir-rs`](https://github.com/zkmopro/noir-rs). Please checkout the usage and the version here.

**Current version**: Supports Noir `1.0.0-beta.8-3` with bb `1.0.0-nightly.20250723` with updated dependencies and enhanced functionality.
**Current version**: Supports Noir `v1.0.0-beta.19` via the official [`barretenberg-rs`](https://crates.io/crates/barretenberg-rs) crate (`=4.2.0-aztecnr-rc.2`).

**Backend**: The adapter uses the Barretenberg backend, which is automatically downloaded from the released GitHub artifacts at [zkmopro/aztec-packages](https://github.com/zkmopro/aztec-packages/releases).
**Backend**: The adapter uses the Barretenberg backend via the official [`barretenberg-rs`](https://crates.io/crates/barretenberg-rs) crate from crates.io. Prebuilt FFI binaries are fetched automatically at build time — no separate download script required.
:::

## Hash Function Selection
Expand Down Expand Up @@ -110,12 +109,11 @@ The Noir adapter supports the following target platforms with Barretenberg backe
| macOS (M Series) | `aarch64-apple-darwin` | ✅ |
| iOS Device | `aarch64-apple-ios` | ✅ |
| iOS aarch64 Simulator | `aarch64-apple-ios-sim` | ✅ |
| iOS x86_64 Simulator | `x86_64-apple-ios` | ✅ |
| Android aarch64 Device | `aarch64-linux-android` | ✅ |
| Android x86_64 Emulator | `x86_64-linux-android` | ✅ |
| Linux Desktop | `x86_64-unknown-linux-gnu` | ✅ |

All platforms use pre-compiled Barretenberg binaries automatically downloaded from [zkmopro/aztec-packages releases](https://github.com/zkmopro/aztec-packages/releases) during the build process.
All platforms use pre-compiled Barretenberg binaries fetched by the official [`barretenberg-rs`](https://crates.io/crates/barretenberg-rs) crate from crates.io during the build process.

## Using the Library

Expand Down
5 changes: 2 additions & 3 deletions docs/docs/setup/rust-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,7 @@ See [Downloading SRS](https://github.com/zkmopro/noir-rs?tab=readme-ov-file#down
[dependencies]
noir_rs = { package = "noir", git = "https://github.com/zkmopro/noir-rs", features = [
"barretenberg",
"android-compat",
], branch = "v1.0.0-beta.8-3" }
], tag = "v1.0.0-beta.19" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.94"

Expand All @@ -437,7 +436,7 @@ serial_test = "3.0.0"
```

:::warning
Noir and its dependencies are not yet published as crates on crates.io. Therefore, we can only import them directly from GitHub.
`noir-rs` is not yet published on crates.io, so it must be imported directly from GitHub. Its Barretenberg backend (`barretenberg-rs`) is published on crates.io and is pulled in transitively.
:::

You’re now ready to generate a Noir proof using mopro-ffi.
Expand Down
2 changes: 2 additions & 0 deletions mopro-ffi/src/app_config/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ fn build_for_arch(
.arg("ndk")
.arg("-t")
.arg(arch_str)
.arg("--platform")
.arg("30") // API 30 minimum
.arg("build")
.arg("--link-libcxx-shared")
.arg("--lib");
Expand Down
34 changes: 34 additions & 0 deletions scripts/regen-noir-fixtures.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Regenerate the Noir multiplier2 test fixtures (.json / .srs / .vk) used by
# the cli template tests and the iOS/Android sample apps. Run from repo root
# whenever the noir-rs pin in `cli/src/init/noir.rs` changes.
#
# Requires:
# - nargo at the version pinned in cli/src/init/noir.rs (currently v1.0.0-beta.19)
# - network access to crs.aztec.network for the SRS download
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CIRCUIT_DIR="$ROOT/test-vectors/noir/multiplier2"
TARGET_DIR="$CIRCUIT_DIR/target"
TEMPLATE_VEC="$ROOT/cli/src/template/init/test-vectors/noir"
TOPLEVEL_VEC="$ROOT/test-vectors/noir"

echo "[1/3] Compiling multiplier2 with $(nargo --version | head -1)"
( cd "$CIRCUIT_DIR" && nargo compile )

echo "[2/3] Downloading SRS and computing Keccak + Poseidon VKs"
cargo run --manifest-path "$ROOT/scripts/regen-noir-fixtures/Cargo.toml" --release -- \
"$TARGET_DIR/noir_multiplier2.json" \
"$TARGET_DIR/noir_multiplier2.srs" \
"$TARGET_DIR/noir_multiplier2.vk" \
"$TARGET_DIR/noir_multiplier2_poseidon.vk"

echo "[3/3] Copying artifacts to $TEMPLATE_VEC and $TOPLEVEL_VEC"
cp "$TARGET_DIR/noir_multiplier2.json" "$TEMPLATE_VEC/"
cp "$TARGET_DIR/noir_multiplier2.srs" "$TEMPLATE_VEC/"
cp "$TARGET_DIR/noir_multiplier2.vk" "$TEMPLATE_VEC/"
cp "$TARGET_DIR/noir_multiplier2_poseidon.vk" "$TEMPLATE_VEC/"
cp "$TARGET_DIR/noir_multiplier2.vk" "$TOPLEVEL_VEC/"

echo "Done. Verify with: cd <fresh mopro init project> && cargo test --all --all-features"
Loading
Loading