diff --git a/.github/workflows/new-arch.yml b/.github/workflows/new-arch.yml new file mode 100644 index 000000000..443d7481f --- /dev/null +++ b/.github/workflows/new-arch.yml @@ -0,0 +1,194 @@ +name: New Architecture (ffi / provers / tests) + +# Runs on the groundwork branch and on PRs targeting main that touch new-arch paths. +# Intentionally separate from build-and-test.yml to avoid interfering with +# the existing CLI / template / platform build pipeline. + +on: + push: + branches: [groundwork] + paths: + - "core/**" + - "provers/**" + - "ffi/**" + - "tests/**" + - "scripts/check-boundaries.sh" + - "Cargo.toml" + - "Cargo.lock" + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: [main] + paths: + - "core/**" + - "provers/**" + - "ffi/**" + - "tests/**" + - "scripts/check-boundaries.sh" + - "Cargo.toml" + - "Cargo.lock" + +env: + CARGO_TERM_COLOR: always + +jobs: + # ------------------------------------------------------------------ + # 1. cargo check — all new crates, including the tests build.rs + # ------------------------------------------------------------------ + check: + name: cargo check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + cache-key: new-arch-check + + - name: core + run: cargo check -p mopro-core + + - name: provers + run: cargo check -p circom-prover-adapter -p halo2-prover-adapter -p noir-prover-adapter + + - name: ffi + run: cargo check -p mopro-build-common -p mopro-uniffi-backend -p mopro-wasm-backend -p mopro-flutter-backend -p mopro-react-native-backend + + - name: test-app (the library compiled for mobile/wasm; must not appear in ffi/* deps) + run: cargo check -p test-app + + - name: tests (verifies build.rs compiles; no arch env vars set so no external tools run) + run: cargo check -p tests + + # ------------------------------------------------------------------ + # 2. cargo test — unit tests (pure Rust, no toolchain deps) + # ------------------------------------------------------------------ + test: + name: cargo test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + cache-key: new-arch-test + + - name: Run tests + run: | + cargo test \ + -p mopro-core \ + -p mopro-build-common \ + -p circom-prover-adapter \ + -p halo2-prover-adapter \ + -p noir-prover-adapter \ + -p mopro-uniffi-backend \ + -p mopro-wasm-backend \ + -p mopro-flutter-backend \ + -p mopro-react-native-backend + + # ------------------------------------------------------------------ + # 3. Dependency boundary — ffi/* must not pull in core or provers + # ------------------------------------------------------------------ + boundary: + name: dependency boundary check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + cache-key: new-arch-boundary + + - name: check ffi/* has no deps on core or provers + run: bash scripts/check-boundaries.sh + + # ------------------------------------------------------------------ + # 4. iOS bindings — build.rs triggers ios::build() via IOS_ARCHS + # Output: tests/MoproiOSBindings/MoproBindings.xcframework + # ------------------------------------------------------------------ + binding_ios: + name: iOS bindings (uniffi → xcframework + Swift) + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Rust + uses: ./.github/actions/setup-rust + with: + cache-key: new-arch-binding-ios + + - name: Add iOS simulator target + run: rustup target add aarch64-apple-ios-sim + + - name: Build bindings + working-directory: tests + run: IOS_ARCHS=aarch64-apple-ios-sim cargo build -p tests + + - name: Assert outputs exist + working-directory: test-app + run: | + set -e + test -d MoproiOSBindings/MoproBindings.xcframework \ + || { echo "::error::test-app/MoproiOSBindings/MoproBindings.xcframework not found"; exit 1; } + test -f MoproiOSBindings/mopro.swift \ + || { echo "::error::test-app/MoproiOSBindings/mopro.swift not found"; exit 1; } + echo "iOS bindings OK" + find MoproiOSBindings -type f | sort + + - name: Upload bindings (on failure) + if: failure() + uses: actions/upload-artifact@v4 + with: + name: ios-bindings-debug + path: test-app/MoproiOSBindings + if-no-files-found: ignore + + # ------------------------------------------------------------------ + # 5. Wasm bindings — build.rs triggers wasm::build() via WEB_ARCHS + # Output: tests/MoproWasmBindings/mopro_wasm_lib_bg.wasm + # ------------------------------------------------------------------ + binding_wasm: + name: Wasm bindings (wasm-pack → pkg) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Rust (nightly-2025-02-20 for wasm-pack) + uses: ./.github/actions/setup-rust + with: + toolchain: nightly-2025-02-20 + cache-key: new-arch-binding-wasm + + - name: Add rust-src component (required by wasm-pack atomics build) + run: rustup component add rust-src --toolchain nightly-2025-02-20 + + - name: Add wasm32 target + run: rustup target add wasm32-unknown-unknown --toolchain nightly-2025-02-20 + + - name: Install wasm-pack + run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + + - name: Build bindings + working-directory: tests + run: WEB_ARCHS=wasm32-unknown-unknown cargo build -p tests + + - name: Assert outputs exist + working-directory: test-app + run: | + set -e + test -d MoproWasmBindings \ + || { echo "::error::test-app/MoproWasmBindings/ not found"; exit 1; } + test -f MoproWasmBindings/mopro_wasm_lib_bg.wasm \ + || { echo "::error::test-app/MoproWasmBindings/mopro_wasm_lib_bg.wasm not found"; exit 1; } + echo "Wasm bindings OK" + find MoproWasmBindings -type f | sort + + - name: Upload bindings (on failure) + if: failure() + uses: actions/upload-artifact@v4 + with: + name: wasm-bindings-debug + path: test-app/MoproWasmBindings + if-no-files-found: ignore diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..570912832 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,146 @@ +# CLAUDE.md — mopro (root) + +This file defines architectural invariants for the mopro monorepo during and +after the `core` / `provers` / `ffi` / `cli` restructuring. It is the source +of truth for dependency boundaries that the compiler will NOT enforce for +you — read this before touching any crate under `provers/`, `ffi/`, or `cli/`. + +## Target structure + +``` +mopro/ +├── core/ # Prover trait + shared types. No FFI deps, no internal deps. +├── provers/ # "adapters" — thin wrappers that implement core::Prover +│ ├── circom-adapter/ # delegates to external circom-prover crate +│ ├── halo2-adapter/ # wraps user-supplied circuit fn pointers +│ ├── noir-adapter/ # delegates to noir-rs (barretenberg feature) +│ └── plonk-prover/ # future community slot +├── ffi/ +│ ├── common/ # Arch/Mode/PlatformBuilder traits + shared build utilities +│ ├── uniffi/ # build pipeline: runs uniffi-bindgen, emits Swift/Kotlin +│ ├── flutter/ # build pipeline: runs FRB codegen, emits Dart package +│ ├── react-native/ # build pipeline: runs uniffi-bindgen-react-native +│ └── wasm/ # build pipeline: runs wasm-pack, emits pkg/ +├── cli/ # mopro-cli — the ONLY composition root +├── templates/ # scaffold templates per (adapter × platform) +├── tests/ +├── test-vectors/ +└── docs/ +``` + +## Dependency direction + +``` +core/ ──► (nothing internal) +provers/* ──► core + external prover crate + + optional FFI runtime/annotation crates + (uniffi, wasm-bindgen, flutter_rust_bridge, serde) +ffi/* ──► (nothing internal) — build pipeline only +cli/ ──► core, provers/*, ffi/* +``` + +### `core/` — defines the contract, nothing else + +- Holds the `Prover` trait, `MoproError`, and shared types (`ProofBytes`, etc.). +- Zero FFI-tool dependencies: no `uniffi`, no `wasm-bindgen`, no `flutter_rust_bridge`. +- Does not know that `ffi/` or `cli/` exist. + +### `provers/*` — implement the contract AND own FFI compatibility + +Each adapter crate has **two responsibilities**: + +1. **Implement `core::Prover`** — a thin Rust wrapper that delegates all actual + proving/verifying logic to an external crate (circom-prover, noir-rs, etc.). + No proving code lives inside this monorepo. + +2. **Own FFI compatibility for their output types** — the `Output` type (and any + supporting structs/enums) carries the annotations that make it directly usable + by all three FFI layers via optional Cargo features: + + | Feature flag | FFI layer | What gets added | + |---------------|------------------------|----------------------------------------------------------------------| + | `uniffi` | iOS / Android (UniFFI) | `uniffi::Record` / `uniffi::Enum` derives; `setup_scaffolding!()` in `lib.rs` | + | `wasm` | Browser (wasm-bindgen) | `#[wasm_bindgen]` on wrapper functions; `serde` for `JsValue` conversion | + | `flutter` | Flutter (FRB) | FRB codegen scans public types; `String`/`Vec`/`Vec` are native — no extra annotation needed | + + `serde` (`Serialize` / `Deserialize`) is always present on output types regardless + of feature flags, because JSON serialisation is useful in every context. + + **Allowed optional dependencies in `provers/*`:** + - `uniffi` — runtime proc-macros (`Record`, `Enum`, `setup_scaffolding!`) + - `wasm-bindgen` — proc-macros + JS glue for browser exports + - `flutter_rust_bridge` — proc-macros for FRB codegen + - `serde` — always on + - The external prover crate being adapted + + **Never allowed in `provers/*`:** + - `uniffi-bindgen` — this is the Swift/Kotlin *code generator* (CLI tool), not + the runtime. It belongs in the `ffi/uniffi` build pipeline. + - Any `ffi/*` crate as a hard dependency. + +3. **Adding a new adapter must require zero changes to `ffi/*`.** + If it does require changes, the boundary has been violated — stop and re-check. + +### `ffi/*` — build pipeline only, no ZK knowledge, no Rust types + +`ffi/*` crates are **build-pipeline orchestrators**, not Rust glue-code crates: + +- `ffi/uniffi` — invokes `uniffi-bindgen` to generate Swift/Kotlin from the adapter's scaffolding; runs `cargo build` with `--features uniffi`. +- `ffi/wasm` — runs `wasm-pack build` with `--features wasm`; sets up `pkg/` output. +- `ffi/flutter` — runs FRB codegen; sets up the Dart package. +- `ffi/react-native` — runs `uniffi-bindgen-react-native`; sets up the JS package. + +Rules: +- No `ffi/*` crate's `Cargo.toml` lists `mopro-core` or any `provers/*` crate as a dependency. +- No Rust types related to proving live in `ffi/*` — those live in the adapter. +- If you find yourself writing "what a proof is" inside `ffi/*`, that logic belongs in the adapter or in `cli/`. + +### `cli/` — the only composition root + +- The only crate allowed to depend on both a specific adapter (from `provers/*`) + and a specific FFI backend (from `ffi/*`) simultaneously. +- Given a user's choice of (adapter × platform), `cli/` enables the right + feature flags on the adapter and invokes the right `ffi/*` pipeline. +- All "which adapters exist" and "which backend to use" logic lives here. + +## Verifying the boundaries + +Run before finishing any change under `ffi/`, `provers/`, or `core/`. + +```bash +# ffi/backends must NOT pull in core or any adapter (the one invariant the +# compiler won't catch for you) +cargo tree -p | grep -iE "mopro-core|circom-prover-adapter|halo2-prover-adapter|noir-prover-adapter" +# Should print nothing. +``` + +## Migration notes + +- The old `mopro-ffi` crate combined (1) FFI tooling orchestration and (2) wiring + specific provers into specific platforms. This refactor splits them: + (1) → `ffi/*`, (2) → `cli/`. +- Do not recreate a crate that re-merges these two responsibilities. +- `circom-prover` already existed as a standalone crate on crates.io and is + adapted (not rewritten) under `provers/circom-adapter`. +- `halo2-adapter` and `noir-adapter` extract logic that used to live inside + `mopro-ffi`. +- `plonk-prover` does not exist yet — it is a placeholder proving that the + architecture admits community-contributed adapters with zero changes to + `ffi/` or `cli/`. + +## Status + +> Update this section as migration proceeds. +> States: `not started` / `in progress` / `done` + +- [x] `core/` — `Prover` trait, `MoproError`, `ProofBytes` defined; no FFI deps +- [x] `provers/circom-adapter` — `Prover` impl done; `serde` + optional `uniffi` derives on output types; compiles (integration tests need zkey test-vectors) +- [x] `provers/halo2-adapter` — `Prover` impl done; `Halo2Output` with `serde` + optional `uniffi::Record` +- [x] `provers/noir-adapter` — `Prover` impl done; Input/Output are FFI-primitive (`Vec` / `Vec`); `barretenberg` feature gates noir-rs +- [x] `ffi/uniffi` — `IosPlatform`/`AndroidPlatform` defined locally; `impl PlatformBuilder` for both; compiles; no deps on core or provers +- [x] `ffi/flutter` — `FlutterPlatform` defined locally; `impl PlatformBuilder`; compiles; no deps on core or provers +- [x] `ffi/react-native` — `ReactNativePlatform` defined locally; `impl PlatformBuilder`; compiles; no deps on core or provers +- [x] `ffi/wasm` — `WebPlatform` defined locally; `impl PlatformBuilder`; compiles; no deps on core or provers +- [ ] `cli/` — updated to composition root (not started) +- [ ] old `mopro-ffi` crate removed (not started) +- [ ] `templates/` updated to reflect new (adapter × platform) structure (not started) diff --git a/Cargo.lock b/Cargo.lock index 9336b1bbd..cba0ada93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,74 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "acir" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" +dependencies = [ + "acir_field", + "base64", + "brillig", + "flate2", + "noirc_span", + "num-bigint", + "num-traits", + "num_enum", + "rmp-serde", + "serde", + "serde-big-array", + "strum", + "strum_macros", + "thiserror 1.0.69", +] + +[[package]] +name = "acir_field" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" +dependencies = [ + "ark-bn254", + "ark-ff", + "ark-std 0.5.0", + "cfg-if", + "hex", + "num-bigint", + "serde", +] + +[[package]] +name = "acvm" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" +dependencies = [ + "acir", + "acvm_blackbox_solver", + "brillig_vm", + "indexmap 2.11.0", + "rustc-hash", + "serde", + "thiserror 1.0.69", + "tracing", +] + +[[package]] +name = "acvm_blackbox_solver" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" +dependencies = [ + "acir", + "aes", + "blake2 0.11.0-rc.6", + "blake3", + "cbc", + "k256", + "keccak 0.2.0-rc.0", + "log", + "p256", + "sha2 0.11.0", + "thiserror 1.0.69", +] + [[package]] name = "addr2line" version = "0.22.0" @@ -31,7 +99,19 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", - "cpufeatures", + "cpufeatures 0.2.17", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", ] [[package]] @@ -54,6 +134,12 @@ dependencies = [ "backtrace", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android_log-sys" version = "0.3.2" @@ -71,6 +157,15 @@ dependencies = [ "log", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.18" @@ -136,6 +231,222 @@ dependencies = [ "derive_arbitrary", ] +[[package]] +name = "ark-bls12-381" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3df4dcc01ff89867cd86b0da835f23c3f02738353aaee7dde7495af71363b8d5" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std 0.5.0", +] + +[[package]] +name = "ark-bn254" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std 0.5.0", +] + +[[package]] +name = "ark-crypto-primitives" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0c292754729c8a190e50414fd1a37093c786c709899f29c9f7daccecfa855e" +dependencies = [ + "ahash", + "ark-crypto-primitives-macros", + "ark-ec", + "ark-ff", + "ark-relations", + "ark-serialize", + "ark-snark", + "ark-std 0.5.0", + "blake2 0.10.6", + "derivative", + "digest 0.10.7", + "fnv", + "merlin", + "rayon", + "sha2 0.10.9", +] + +[[package]] +name = "ark-crypto-primitives-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e89fe77d1f0f4fe5b96dfc940923d88d17b6a773808124f21e764dfb063c6a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "ark-ec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" +dependencies = [ + "ahash", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.2", + "itertools 0.13.0", + "num-bigint", + "num-integer", + "num-traits", + "rayon", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "educe", + "itertools 0.13.0", + "num-bigint", + "num-traits", + "paste", + "rayon", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.100", +] + +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "ark-groth16" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88f1d0f3a534bb54188b8dcc104307db6c56cdae574ddc3212aec0625740fc7e" +dependencies = [ + "ark-crypto-primitives", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-relations", + "ark-serialize", + "ark-std 0.5.0", + "rayon", +] + +[[package]] +name = "ark-grumpkin" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef677b59f5aff4123207c4dceb1c0ec8fdde2d4af7886f48be42ad864bfa0352" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-std 0.5.0", +] + +[[package]] +name = "ark-poly" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" +dependencies = [ + "ahash", + "ark-ff", + "ark-serialize", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.2", + "rayon", +] + +[[package]] +name = "ark-relations" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec46ddc93e7af44bcab5230937635b06fb5744464dd6a7e7b083e80ebd274384" +dependencies = [ + "ark-ff", + "ark-std 0.5.0", + "tracing", + "tracing-subscriber 0.2.25", +] + +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-serialize-derive", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "num-bigint", + "rayon", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "ark-snark" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d368e2848c2d4c129ce7679a7d0d2d612b6a274d3ea6a13bad4445d61b381b88" +dependencies = [ + "ark-ff", + "ark-relations", + "ark-serialize", + "ark-std 0.5.0", +] + [[package]] name = "ark-std" version = "0.4.0" @@ -143,7 +454,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" +dependencies = [ + "num-traits", + "rand 0.8.5", + "rayon", ] [[package]] @@ -185,7 +507,7 @@ dependencies = [ "rustc-hash", "serde", "serde_derive", - "syn", + "syn 2.0.100", ] [[package]] @@ -197,7 +519,18 @@ dependencies = [ "memchr", "serde", "serde_derive", - "winnow", + "winnow 0.7.12", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] @@ -233,12 +566,39 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "barretenberg-rs" +version = "4.2.0-aztecnr-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c244bbd116be1c35671e9285671c34b90a2af64e895c60cc622109f5f7545b30" +dependencies = [ + "hex", + "libc", + "rmp", + "rmp-serde", + "rmpv", + "serde", + "thiserror 1.0.69", +] + +[[package]] +name = "base16ct" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" + [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + [[package]] name = "basic-toml" version = "0.1.10" @@ -248,6 +608,12 @@ dependencies = [ "serde", ] +[[package]] +name = "binary-merge" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597bb81c80a54b6a4381b23faba8d7774b144c94cbd1d6fe3f1329bd776554ab" + [[package]] name = "bincode" version = "1.3.3" @@ -257,11 +623,35 @@ dependencies = [ "serde", ] +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bitflags" -version = "2.9.0" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" + +[[package]] +name = "bitmaps" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] [[package]] name = "bitvec" @@ -275,6 +665,24 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake2" +version = "0.11.0-rc.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "061f1a09225e328e1ffbb378d2d49923c0ca5fee19fb5ac1cc9c1e9d52b93690" +dependencies = [ + "digest 0.11.3", +] + [[package]] name = "blake2b_simd" version = "1.0.3" @@ -283,7 +691,21 @@ checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" dependencies = [ "arrayref", "arrayvec", - "constant_time_eq", + "constant_time_eq 0.3.1", +] + +[[package]] +name = "blake3" +version = "1.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq 0.4.2", + "cpufeatures 0.3.0", ] [[package]] @@ -292,7 +714,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", + "block-padding 0.2.1", "generic-array", ] @@ -306,11 +728,84 @@ dependencies = [ ] [[package]] -name = "block-padding" -version = "0.2.1" +name = "block-buffer" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bn254_blackbox_solver" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" +dependencies = [ + "acir", + "acvm_blackbox_solver", + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-grumpkin", + "hex", +] + +[[package]] +name = "borsh" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3f6da4992df95bbcd9af42a6c7dcb994498fc9048230405f3b36ff7cd3f145" +dependencies = [ + "bytes", + "cfg_aliases", +] + +[[package]] +name = "brillig" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" +dependencies = [ + "acir_field", + "serde", +] + +[[package]] +name = "brillig_vm" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" +dependencies = [ + "acir", + "acvm_blackbox_solver", + "num-bigint", + "num-traits", + "thiserror 1.0.69", +] + +[[package]] +name = "build-data" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e6d5ca7a4989b90a9fafea85ce3c8bc9f0e0a76edcdcb330fe0c4fda92251f" +dependencies = [ + "chrono", + "safe-regex", +] + [[package]] name = "build-target" version = "0.4.0" @@ -392,6 +887,15 @@ dependencies = [ "thiserror 2.0.12", ] +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + [[package]] name = "cc" version = "1.2.19" @@ -409,16 +913,77 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link 0.2.1", +] + [[package]] name = "cipher" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", + "crypto-common 0.1.6", "inout", ] +[[package]] +name = "circom-prover" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82cb9d752c87c707a7741ee2b1f9186780e20b8ea0ddb9fd288173ee10ba738e" +dependencies = [ + "anyhow", + "ark-bls12-381", + "ark-bn254", + "ark-crypto-primitives", + "ark-ec", + "ark-ff", + "ark-groth16", + "ark-poly", + "ark-relations", + "ark-serialize", + "ark-std 0.5.0", + "byteorder", + "hex-literal", + "num", + "num-bigint", + "num-traits", + "rand 0.8.5", + "rayon", + "rust-witness", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "circom-prover-adapter" +version = "0.1.0" +dependencies = [ + "circom-prover", + "mopro-core", + "num-bigint", + "serde", + "uniffi", +] + [[package]] name = "clap" version = "4.5.37" @@ -447,10 +1012,10 @@ version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -459,6 +1024,33 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + +[[package]] +name = "codespan" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3362992a0d9f1dd7c3d0e89e0ab2bb540b7a95fea8cd798090e758fda2899b5e" +dependencies = [ + "codespan-reporting", + "serde", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "serde", + "termcolor", + "unicode-width 0.1.14", +] + [[package]] name = "color-eyre" version = "0.6.5" @@ -501,7 +1093,7 @@ dependencies = [ "encode_unicode", "libc", "once_cell", - "unicode-width", + "unicode-width 0.2.0", "windows-sys 0.59.0", ] @@ -515,12 +1107,24 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "constant_time_eq" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +[[package]] +name = "constant_time_eq" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + [[package]] name = "core-foundation" version = "0.9.4" @@ -537,6 +1141,12 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -546,6 +1156,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc" version = "3.2.1" @@ -604,6 +1223,22 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crypto-bigint" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a0d26b245348befa0c121944541476763dcc46ede886c88f9d12e1697d27c3" +dependencies = [ + "cpubits", + "ctutils", + "getrandom 0.4.3", + "hybrid-array", + "num-traits", + "rand_core 0.10.1", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -614,6 +1249,62 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "getrandom 0.4.3", + "hybrid-array", + "rand_core 0.10.1", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", + "subtle", +] + +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.100", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.100", +] + [[package]] name = "dart-sys" version = "4.1.5" @@ -650,7 +1341,18 @@ checksum = "51aac4c99b2e6775164b412ea33ae8441b2fde2dbf05a20bc0052a63d08c475b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", +] + +[[package]] +name = "der" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", ] [[package]] @@ -660,6 +1362,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -670,7 +1384,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -701,10 +1415,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", - "crypto-common", + "crypto-common 0.1.6", "subtle", ] +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", + "ctutils", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -713,7 +1439,40 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", +] + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "ecdsa" +version = "0.17.0-rc.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcddae1289a08e614a83d155a070f54c1803196e92089b8299e2738eb74d3e4" +dependencies = [ + "der", + "digest 0.11.3", + "elliptic-curve", + "rfc6979", + "signature", + "spki", + "zeroize", +] + +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] @@ -722,6 +1481,29 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "elliptic-curve" +version = "0.14.0-rc.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a44d097c9f3e494ddc19f77af5aab89f0b3b2652cde370ec8c6064faca5bd2" +dependencies = [ + "base16ct", + "crypto-bigint", + "crypto-common 0.2.2", + "digest 0.11.3", + "ff 0.14.0", + "group 0.14.0", + "hybrid-array", + "once_cell", + "pem-rfc7468", + "pkcs8", + "rand_core 0.10.1", + "sec1", + "subtle", + "wnaf", + "zeroize", +] + [[package]] name = "encode_unicode" version = "1.0.0" @@ -737,6 +1519,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum-ordinalize" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "env_filter" version = "0.1.3" @@ -786,7 +1588,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ "bitvec", - "rand_core", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" +dependencies = [ + "rand_core 0.10.1", "subtle", ] @@ -799,11 +1611,17 @@ dependencies = [ "halo2_proofs", "itertools 0.13.0", "plonkish_backend", - "rand", + "rand 0.8.5", "serde", "thiserror 1.0.69", ] +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + [[package]] name = "flate2" version = "1.1.1" @@ -853,7 +1671,17 @@ dependencies = [ "md-5", "proc-macro2", "quote", - "syn", + "syn 2.0.100", +] + +[[package]] +name = "fm" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" +dependencies = [ + "codespan-reporting", + "iter-extended", + "serde", ] [[package]] @@ -862,6 +1690,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -963,7 +1797,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -1039,11 +1873,23 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", + "r-efi 5.2.0", "wasi 0.14.2+wasi-0.2.4", "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", +] + [[package]] name = "gimli" version = "0.29.0" @@ -1073,15 +1919,26 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff", - "rand_core", + "ff 0.13.1", + "rand_core 0.6.4", "subtle", ] [[package]] -name = "h2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "group" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" +dependencies = [ + "ff 0.14.0", + "rand_core 0.10.1", + "subtle", +] + +[[package]] +name = "h2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" dependencies = [ "atomic-waker", @@ -1090,25 +1947,34 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap", + "indexmap 2.11.0", "slab", "tokio", "tokio-util", "tracing", ] +[[package]] +name = "halo2-prover-adapter" +version = "0.1.0" +dependencies = [ + "mopro-core", + "serde", + "uniffi", +] + [[package]] name = "halo2_proofs" version = "0.2.0" source = "git+https://github.com/han0110/halo2.git?branch=feature%2Ffor-benchmark#4981b8d5bdaab04af9b56a5d2c482b6eec9f7fa4" dependencies = [ - "ark-std", + "ark-std 0.4.0", "blake2b_simd", - "ff", - "group", + "ff 0.13.1", + "group 0.13.0", "halo2curves 0.3.3", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", "rayon", "sha3 0.9.1", "tracing", @@ -1119,15 +1985,15 @@ name = "halo2curves" version = "0.3.2" source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git?tag=0.3.2#9f5c50810bbefe779ee5cf1d852b2fe85dc35d5e" dependencies = [ - "ff", - "group", + "ff 0.13.1", + "group 0.13.0", "lazy_static", "num-bigint", "num-traits", "pasta_curves", "paste", - "rand", - "rand_core", + "rand 0.8.5", + "rand_core 0.6.4", "static_assertions", "subtle", ] @@ -1137,20 +2003,26 @@ name = "halo2curves" version = "0.3.3" source = "git+https://github.com/privacy-scaling-explorations/halo2curves?tag=0.3.3#8e4cb9f0c66c864e8ca25da07f50ae95f664a5b7" dependencies = [ - "ff", - "group", + "ff 0.13.1", + "group 0.13.0", "lazy_static", "num-bigint", "num-traits", "pasta_curves", "paste", - "rand", - "rand_core", + "rand 0.8.5", + "rand_core 0.6.4", "serde", "static_assertions", "subtle", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.5" @@ -1162,6 +2034,16 @@ name = "hashbrown" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "allocator-api2", + "foldhash", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "heck" @@ -1184,6 +2066,12 @@ dependencies = [ "serde", ] +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + [[package]] name = "hmac" version = "0.12.1" @@ -1193,6 +2081,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest 0.11.3", +] + [[package]] name = "http" version = "1.3.1" @@ -1233,6 +2130,17 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "hybrid-array" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" +dependencies = [ + "subtle", + "typenum", + "zeroize", +] + [[package]] name = "hyper" version = "1.6.0" @@ -1268,6 +2176,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", + "webpki-roots 0.26.11", ] [[package]] @@ -1316,6 +2225,30 @@ dependencies = [ "plonkish_backend", ] +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "icu_collections" version = "1.5.0" @@ -1431,9 +2364,15 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "1.0.3" @@ -1455,6 +2394,21 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + [[package]] name = "include_dir" version = "0.7.4" @@ -1480,6 +2434,17 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + [[package]] name = "indexmap" version = "2.11.0" @@ -1500,7 +2465,7 @@ dependencies = [ "console", "number_prefix", "portable-atomic", - "unicode-width", + "unicode-width 0.2.0", "web-time", ] @@ -1510,9 +2475,19 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ + "block-padding 0.3.3", "generic-array", ] +[[package]] +name = "inplace-vec-builder" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf64c2edc8226891a71f127587a2861b132d2b942310843814d5001d99a1d307" +dependencies = [ + "smallvec", +] + [[package]] name = "ipnet" version = "2.11.0" @@ -1525,6 +2500,11 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "iter-extended" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" + [[package]] name = "itertools" version = "0.10.5" @@ -1569,13 +2549,75 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonrpsee" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fba77a59c4c644fd48732367624d1bcf6f409f9c9a286fbc71d2f1fc0b2ea16" +dependencies = [ + "jsonrpsee-core", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693c93cbb7db25f4108ed121304b671a36002c2db67dff2ee4391a688c738547" +dependencies = [ + "async-trait", + "futures-util", + "http", + "jsonrpsee-types", + "pin-project", + "serde", + "serde_json", + "thiserror 2.0.12", + "tokio", + "tower", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66df7256371c45621b3b7d2fb23aea923d577616b9c0e9c0b950a6ea5c2be0ca" +dependencies = [ + "http", + "serde", + "serde_json", + "thiserror 2.0.12", +] + +[[package]] +name = "k256" +version = "0.14.0-rc.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eb95d01f9d0270fc40dcb217cb25de1494383597d27b4fe832a42f5d907824a" +dependencies = [ + "cpubits", + "ecdsa", + "elliptic-curve", + "sha2 0.11.0", + "signature", +] + [[package]] name = "keccak" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", +] + +[[package]] +name = "keccak" +version = "0.2.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d546793a04a1d3049bd192856f804cfe96356e2cf36b54b4e575155babe9f41" +dependencies = [ + "cpufeatures 0.2.17", ] [[package]] @@ -1621,6 +2663,12 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "lzma-rs" version = "0.3.0" @@ -1658,6 +2706,18 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak 0.1.5", + "rand_core 0.6.4", + "zeroize", +] + [[package]] name = "mime" version = "0.3.17" @@ -1675,101 +2735,391 @@ dependencies = [ ] [[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "mopro-build-common" +version = "0.1.0" +dependencies = [ + "anyhow", + "color-eyre", + "toml 0.8.22", + "uuid", +] + +[[package]] +name = "mopro-cli" +version = "0.3.6" +dependencies = [ + "anyhow", + "clap", + "console", + "dialoguer", + "fs_extra", + "include_dir", + "indicatif", + "mopro-ffi", + "reqwest", + "serde", + "toml 0.9.2", + "walkdir", + "zip", +] + +[[package]] +name = "mopro-core" +version = "0.1.0" +dependencies = [ + "thiserror 2.0.12", +] + +[[package]] +name = "mopro-ffi" +version = "0.3.6" +dependencies = [ + "anyhow", + "camino", + "color-eyre", + "console_error_panic_hook", + "flutter_rust_bridge", + "fs_extra", + "gemini-fibonacci", + "getrandom 0.2.15", + "hyperplonk-fibonacci", + "plonk-fibonacci", + "rand 0.8.5", + "serde-wasm-bindgen", + "thiserror 2.0.12", + "toml 0.8.22", + "uniffi", + "uuid", + "wasm-bindgen", + "wasm-bindgen-console-logger", + "wasm-bindgen-futures", + "wasm-bindgen-rayon", + "wasm-bindgen-test", +] + +[[package]] +name = "mopro-flutter-backend" +version = "0.1.0" +dependencies = [ + "anyhow", + "mopro-build-common", + "toml 0.8.22", +] + +[[package]] +name = "mopro-react-native-backend" +version = "0.1.0" +dependencies = [ + "anyhow", + "fs_extra", + "mopro-build-common", +] + +[[package]] +name = "mopro-uniffi-backend" +version = "0.1.0" +dependencies = [ + "anyhow", + "camino", + "fs_extra", + "mopro-build-common", + "uniffi", +] + +[[package]] +name = "mopro-wasm-backend" +version = "0.1.0" +dependencies = [ + "anyhow", + "mopro-build-common", +] + +[[package]] +name = "nargo" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" +dependencies = [ + "acvm", + "brillig", + "fm", + "iter-extended", + "jsonrpsee", + "noir_greybox_fuzzer", + "noirc_abi", + "noirc_artifacts", + "noirc_driver", + "noirc_errors", + "noirc_frontend", + "noirc_printable_type", + "rayon", + "serde", + "serde_json", + "tempfile", + "thiserror 1.0.69", + "tracing", + "walkdir", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "noir" +version = "1.0.0-beta.19" +source = "git+https://github.com/zkmopro/noir-rs?tag=v1.0.0-beta.19#0e4fdc9fc0cb383fcada7d3864dd2424f137316b" +dependencies = [ + "acvm", + "acvm_blackbox_solver", + "barretenberg-rs", + "base64", + "bincode", + "bn254_blackbox_solver", + "clap", + "flate2", + "hex", + "keccak 0.2.0-rc.0", + "nargo", + "reqwest", + "serde", + "serde_json", + "thiserror 1.0.69", + "tracing", + "tracing-subscriber 0.3.19", +] + +[[package]] +name = "noir-prover-adapter" +version = "0.1.0" +dependencies = [ + "mopro-core", + "noir", + "serde_json", + "uniffi", +] + +[[package]] +name = "noir_greybox_fuzzer" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" +dependencies = [ + "acvm", + "build-data", + "fm", + "noirc_abi", + "noirc_artifacts", + "num-traits", + "proptest", + "rand 0.9.4", + "rand_xorshift", + "rayon", + "sha256", + "termcolor", + "walkdir", +] + +[[package]] +name = "noirc_abi" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" +dependencies = [ + "acvm", + "iter-extended", + "noirc_printable_type", + "num-bigint", + "num-traits", + "serde", + "serde_json", + "thiserror 1.0.69", + "toml 0.7.8", +] + +[[package]] +name = "noirc_arena" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" [[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +name = "noirc_artifacts" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" dependencies = [ - "adler", + "acir", + "acvm", + "base64", + "codespan-reporting", + "flate2", + "fm", + "noirc_abi", + "noirc_errors", + "noirc_printable_type", + "serde", + "serde_json", + "thiserror 1.0.69", + "tracing", ] [[package]] -name = "miniz_oxide" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +name = "noirc_driver" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" dependencies = [ - "adler2", + "acvm", + "build-data", + "clap", + "fm", + "iter-extended", + "noirc_abi", + "noirc_artifacts", + "noirc_errors", + "noirc_evaluator", + "noirc_frontend", + "rust-embed", + "rustc-hash", + "tracing", ] [[package]] -name = "mio" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +name = "noirc_errors" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" dependencies = [ - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", + "codespan-reporting", + "fm", + "noirc_span", + "rustc-hash", + "serde", ] [[package]] -name = "mopro-cli" -version = "0.3.6" +name = "noirc_evaluator" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" dependencies = [ - "anyhow", - "clap", - "console", - "dialoguer", - "fs_extra", - "include_dir", - "indicatif", - "mopro-ffi", - "reqwest", + "acvm", + "bn254_blackbox_solver", + "cfg-if", + "chrono", + "fm", + "im", + "indexmap 2.11.0", + "iter-extended", + "noirc_artifacts", + "noirc_errors", + "noirc_frontend", + "noirc_printable_type", + "num-bigint", + "num-integer", + "num-traits", + "petgraph", + "rayon", + "rustc-hash", + "rustc-stable-hash", "serde", - "toml 0.9.2", - "walkdir", - "zip", + "serde_json", + "serde_with", + "smallvec", + "thiserror 1.0.69", + "tracing", + "vec-collections", ] [[package]] -name = "mopro-ffi" -version = "0.3.6" +name = "noirc_frontend" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" dependencies = [ - "anyhow", - "camino", - "color-eyre", - "console_error_panic_hook", - "flutter_rust_bridge", - "fs_extra", - "gemini-fibonacci", - "getrandom 0.2.15", - "hyperplonk-fibonacci", - "plonk-fibonacci", - "rand", - "serde-wasm-bindgen", - "thiserror 2.0.12", - "toml 0.8.22", - "uniffi", - "uuid", - "wasm-bindgen", - "wasm-bindgen-console-logger", - "wasm-bindgen-futures", - "wasm-bindgen-rayon", - "wasm-bindgen-test", + "acvm", + "bn254_blackbox_solver", + "cfg-if", + "fm", + "im", + "iter-extended", + "noirc_arena", + "noirc_artifacts", + "noirc_errors", + "noirc_printable_type", + "num-bigint", + "num-traits", + "petgraph", + "rangemap", + "rustc-hash", + "serde", + "serde_json", + "small-ord-set", + "smol_str", + "strum", + "strum_macros", + "thiserror 1.0.69", + "tracing", ] [[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +name = "noirc_printable_type" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", + "acvm", + "iter-extended", + "serde", + "serde_json", +] + +[[package]] +name = "noirc_span" +version = "1.0.0-beta.19" +source = "git+https://github.com/noir-lang/noir.git?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" +dependencies = [ + "codespan", + "serde", ] [[package]] @@ -1782,6 +3132,30 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -1790,6 +3164,17 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", ] [[package]] @@ -1807,6 +3192,28 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1826,6 +3233,28 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "number_prefix" version = "0.4.0" @@ -1876,7 +3305,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -1908,12 +3337,31 @@ dependencies = [ "log", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "owo-colors" version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e" +[[package]] +name = "p256" +version = "0.14.0-rc.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cfbd444125de5ec2af6c4bc081d932e2ca90497cbd0300f7c862133ea6e27b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primefield", + "primeorder", + "sha2 0.11.0", +] + [[package]] name = "parking_lot_core" version = "0.9.11" @@ -1934,11 +3382,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" dependencies = [ "blake2b_simd", - "ff", - "group", + "ff 0.13.1", + "group 0.13.0", "hex", "lazy_static", - "rand", + "rand 0.8.5", "serde", "static_assertions", "subtle", @@ -1957,7 +3405,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", - "hmac", + "hmac 0.12.1", +] + +[[package]] +name = "pem-rfc7468" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9" +dependencies = [ + "base64ct", ] [[package]] @@ -1966,6 +3423,38 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "petgraph" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +dependencies = [ + "fixedbitset", + "hashbrown 0.15.2", + "indexmap 2.11.0", + "serde", +] + +[[package]] +name = "pin-project" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -1978,6 +3467,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.32" @@ -1999,7 +3498,7 @@ dependencies = [ "fibonacci-circuit", "halo2_proofs", "plonkish_backend", - "rand", + "rand 0.8.5", "serde", ] @@ -2018,7 +3517,7 @@ dependencies = [ "num-integer", "pasta_curves", "poseidon", - "rand", + "rand 0.8.5", "rayon", "serde", "sha3 0.10.8", @@ -2055,12 +3554,116 @@ dependencies = [ ] [[package]] -name = "proc-macro2" -version = "1.0.95" +name = "primefield" +version = "0.14.0-rc.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d7e42f46a29abc16fb621a3466ee453358ebaae48a9e515f287e0af052ed8f" +dependencies = [ + "crypto-bigint", + "crypto-common 0.2.2", + "ff 0.14.0", + "rand_core 0.10.1", + "subtle", + "zeroize", +] + +[[package]] +name = "primeorder" +version = "0.14.0-rc.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1576f33b3071d61b06389caf381238dd95ccd2519cd04d788cd52450462eab4" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit 0.23.2", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags", + "num-traits", + "rand 0.9.4", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax", + "unarray", +] + +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.12", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +dependencies = [ + "bytes", + "getrandom 0.3.2", + "lru-slab", + "rand 0.9.4", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.12", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ - "unicode-ident", + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.52.0", ] [[package]] @@ -2078,6 +3681,12 @@ version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "radium" version = "0.7.0" @@ -2091,8 +3700,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", ] [[package]] @@ -2102,7 +3721,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", ] [[package]] @@ -2114,6 +3743,45 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.2", +] + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.5", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rangemap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68" + [[package]] name = "rayon" version = "1.10.0" @@ -2145,6 +3813,26 @@ dependencies = [ "bitflags", ] +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "regex" version = "1.11.1" @@ -2202,7 +3890,10 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "quinn", + "rustls", "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", @@ -2210,15 +3901,27 @@ dependencies = [ "system-configuration", "tokio", "tokio-native-tls", + "tokio-rustls", "tower", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots 0.26.11", "windows-registry", ] +[[package]] +name = "rfc6979" +version = "0.6.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9935425142ac6e252364413291d96c8bc9898d0876a801824c7af4eae397b689" +dependencies = [ + "ctutils", + "hmac 0.13.0", +] + [[package]] name = "ring" version = "0.17.14" @@ -2233,6 +3936,82 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rmp" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "rmp-serde" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155" +dependencies = [ + "rmp", + "serde", +] + +[[package]] +name = "rmpv" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a4e1d4b9b938a26d2996af33229f0ca0956c652c1375067f0b45291c1df8417" +dependencies = [ + "rmp", +] + +[[package]] +name = "rust-embed" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04113cb9355a377d83f06ef1f0a45b8ab8cd7d8b1288160717d66df5c7988d27" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0902e4c7c8e997159ab384e6d0fc91c221375f6894346ae107f47dd0f3ccaa" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn 2.0.100", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" +dependencies = [ + "sha2 0.10.9", + "walkdir", +] + +[[package]] +name = "rust-witness" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b59361683f7b6b3b0d343fc77e797ee5a267b8a470b9531ed9911aeed160dea0" +dependencies = [ + "cc", + "fnv", + "num-bigint", + "num-traits", + "paste", + "walkdir", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -2245,6 +4024,12 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +[[package]] +name = "rustc-stable-hash" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "781442f29170c5c93b7185ad559492601acdc71d5bb0706f5868094f45cfcd08" + [[package]] name = "rustix" version = "1.0.5" @@ -2265,6 +4050,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" dependencies = [ "once_cell", + "ring", "rustls-pki-types", "rustls-webpki", "subtle", @@ -2285,6 +4071,9 @@ name = "rustls-pki-types" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +dependencies = [ + "web-time", +] [[package]] name = "rustls-webpki" @@ -2309,6 +4098,53 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "safe-proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "492d1a72624b0bd5b7f0193ea5834a1905534a517573a117e949e895f342906c" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "safe-quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcaa9a650f2f98ba4da0190623210c85945cb78b262709f606c57655eda173e1" +dependencies = [ + "safe-proc-macro2", +] + +[[package]] +name = "safe-regex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5194fafa3cb9da89e0cab6dffa1f3fdded586bd6396d12be11b4cae0c7ee45c2" +dependencies = [ + "safe-regex-macro", +] + +[[package]] +name = "safe-regex-compiler" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e822ae1e61251bcfd698317c237cf83f7c57161a5dc24ee609a85697f1ed15b3" +dependencies = [ + "safe-proc-macro2", + "safe-quote", +] + +[[package]] +name = "safe-regex-macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2768de7e6ef19f59c5fd3c3ac207ef12b68a49f95e3172d67e4a04cfd992ca06" +dependencies = [ + "safe-proc-macro2", + "safe-regex-compiler", +] + [[package]] name = "same-file" version = "1.0.6" @@ -2327,6 +4163,30 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -2350,7 +4210,21 @@ checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", +] + +[[package]] +name = "sec1" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" +dependencies = [ + "base16ct", + "ctutils", + "der", + "hybrid-array", + "subtle", + "zeroize", ] [[package]] @@ -2387,13 +4261,23 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + [[package]] name = "serde-wasm-bindgen" version = "0.6.5" @@ -2405,15 +4289,24 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2432,41 +4325,107 @@ dependencies = [ name = "serde_spanned" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c522100790450cf78eeac1507263d0a350d4d5b30df0c8e1fe051a10c22b376e" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.11.0", + "schemars 0.9.0", + "schemars 1.2.1", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327ada00f7d64abaac1e55a6911e90cf665aa051b9a561c7006c157f4633135e" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "serde", + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", ] [[package]] -name = "serde_spanned" -version = "1.0.0" +name = "sha2" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ - "serde", + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", ] [[package]] -name = "serde_urlencoded" -version = "0.7.1" +name = "sha2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] -name = "sha1" -version = "0.10.6" +name = "sha256" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "f880fc8562bdeb709793f00eb42a2ad0e672c4f883bbe59122b926eca935c8f6" dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", + "async-trait", + "bytes", + "hex", + "sha2 0.10.9", ] [[package]] @@ -2477,7 +4436,7 @@ checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" dependencies = [ "block-buffer 0.9.0", "digest 0.9.0", - "keccak", + "keccak 0.1.5", "opaque-debug", ] @@ -2488,7 +4447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ "digest 0.10.7", - "keccak", + "keccak 0.1.5", ] [[package]] @@ -2512,6 +4471,16 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signature" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" +dependencies = [ + "digest 0.11.3", + "rand_core 0.10.1", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -2524,6 +4493,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + [[package]] name = "slab" version = "0.4.9" @@ -2533,11 +4512,23 @@ dependencies = [ "autocfg", ] +[[package]] +name = "small-ord-set" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf7035a2b2268a5be8c1395738565b06beda836097e12021cdefc06b127a0e7e" +dependencies = [ + "smallvec", +] + [[package]] name = "smallvec" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +dependencies = [ + "serde", +] [[package]] name = "smawk" @@ -2545,6 +4536,16 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +[[package]] +name = "smol_str" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aaa7368fcf4852a4c2dd92df0cace6a71f2091ca0a23391ce7f3a31833f1523" +dependencies = [ + "borsh", + "serde_core", +] + [[package]] name = "socket2" version = "0.5.9" @@ -2555,12 +4556,28 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "sorted-iter" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bceb57dc07c92cdae60f5b27b3fa92ecaaa42fe36c55e22dbfb0b44893e0b1f7" + [[package]] name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spki" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -2579,12 +4596,42 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + [[package]] name = "subtle" version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.100" @@ -2613,7 +4660,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2657,11 +4704,29 @@ dependencies = [ ] [[package]] -name = "tests" +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "test-app" version = "0.1.0" dependencies = [ "mopro-ffi", - "thiserror 2.0.12", +] + +[[package]] +name = "tests" +version = "0.1.0" +dependencies = [ + "mopro-flutter-backend", + "mopro-react-native-backend", + "mopro-uniffi-backend", + "mopro-wasm-backend", ] [[package]] @@ -2699,7 +4764,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2710,7 +4775,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2739,10 +4804,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", + "itoa", "num-conv", "powerfmt", "serde", "time-core", + "time-macros", ] [[package]] @@ -2751,6 +4818,16 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.7.6" @@ -2761,6 +4838,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.44.2" @@ -2809,6 +4901,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned 0.6.8", + "toml_datetime 0.6.9", + "toml_edit 0.19.15", +] + [[package]] name = "toml" version = "0.8.22" @@ -2818,7 +4922,7 @@ dependencies = [ "serde", "serde_spanned 0.6.8", "toml_datetime 0.6.9", - "toml_edit", + "toml_edit 0.22.26", ] [[package]] @@ -2827,13 +4931,13 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed0aee96c12fa71097902e0bb061a5e1ebd766a6636bb605ba401c45c1650eac" dependencies = [ - "indexmap", + "indexmap 2.11.0", "serde", "serde_spanned 1.0.0", "toml_datetime 0.7.0", "toml_parser", "toml_writer", - "winnow", + "winnow 0.7.12", ] [[package]] @@ -2854,18 +4958,43 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.11.0", + "serde", + "serde_spanned 0.6.8", + "toml_datetime 0.6.9", + "winnow 0.5.40", +] + [[package]] name = "toml_edit" version = "0.22.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" dependencies = [ - "indexmap", + "indexmap 2.11.0", "serde", "serde_spanned 0.6.8", "toml_datetime 0.6.9", "toml_write", - "winnow", + "winnow 0.7.12", +] + +[[package]] +name = "toml_edit" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1dee9dc43ac2aaf7d3b774e2fba5148212bf2bd9374f4e50152ebe9afd03d42" +dependencies = [ + "indexmap 2.11.0", + "toml_datetime 0.7.0", + "toml_parser", + "winnow 0.7.12", ] [[package]] @@ -2874,7 +5003,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97200572db069e74c512a14117b296ba0a80a30123fbbb5aa1f4a348f639ca30" dependencies = [ - "winnow", + "winnow 0.7.12", ] [[package]] @@ -2935,7 +5064,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2955,7 +5084,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" dependencies = [ "tracing", - "tracing-subscriber", + "tracing-subscriber 0.3.19", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "tracing-core", ] [[package]] @@ -2964,9 +5113,12 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ + "nu-ansi-term", "sharded-slab", + "smallvec", "thread_local", "tracing-core", + "tracing-log", ] [[package]] @@ -2981,18 +5133,36 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "unicode-width" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "uniffi" version = "0.31.0" @@ -3020,8 +5190,8 @@ dependencies = [ "fs-err", "glob", "goblin", - "heck", - "indexmap", + "heck 0.5.0", + "indexmap 2.11.0", "once_cell", "serde", "tempfile", @@ -3053,10 +5223,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98f51ebca0d9a4b2aa6c644d5ede45c56f73906b96403c08a1985e75ccb64a01" dependencies = [ "anyhow", - "indexmap", + "indexmap 2.11.0", "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -3071,7 +5241,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn", + "syn 2.0.100", "toml 0.9.2", "uniffi_meta", ] @@ -3095,8 +5265,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a806dddc8208f22efd7e95a5cdf88ed43d0f3271e8f63b47e757a8bbdb43b63a" dependencies = [ "anyhow", - "heck", - "indexmap", + "heck 0.5.0", + "indexmap 2.11.0", "tempfile", "uniffi_internal_macros", ] @@ -3184,6 +5354,21 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec-collections" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9965c8f2ffed1dbcd16cafe18a009642f540fa22661c6cfd6309ddb02e4982" +dependencies = [ + "binary-merge", + "inplace-vec-builder", + "lazy_static", + "num-traits", + "serde", + "smallvec", + "sorted-iter", +] + [[package]] name = "version_check" version = "0.9.5" @@ -3248,7 +5433,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn", + "syn 2.0.100", "wasm-bindgen-shared", ] @@ -3293,7 +5478,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3340,7 +5525,7 @@ checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -3374,6 +5559,24 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.8", +] + +[[package]] +name = "webpki-roots" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "weedle2" version = "5.0.0" @@ -3383,6 +5586,22 @@ dependencies = [ "nom", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.9" @@ -3392,20 +5611,67 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "windows-link" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-registry" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ - "windows-result", - "windows-strings", + "windows-result 0.3.2", + "windows-strings 0.3.1", "windows-targets 0.53.0", ] @@ -3415,7 +5681,16 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" dependencies = [ - "windows-link", + "windows-link 0.1.1", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -3424,7 +5699,16 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" dependencies = [ - "windows-link", + "windows-link 0.1.1", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -3573,6 +5857,15 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" version = "0.7.12" @@ -3591,6 +5884,16 @@ dependencies = [ "bitflags", ] +[[package]] +name = "wnaf" +version = "0.14.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81b8f9936fa4378fbe26130d702e51a9d723b22a073105500dfd80d9bb508199" +dependencies = [ + "ff 0.14.0", + "group 0.14.0", +] + [[package]] name = "write16" version = "1.0.0" @@ -3641,7 +5944,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", "synstructure", ] @@ -3662,7 +5965,7 @@ checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -3682,7 +5985,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", "synstructure", ] @@ -3703,7 +6006,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -3725,7 +6028,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -3737,14 +6040,14 @@ dependencies = [ "aes", "arbitrary", "bzip2", - "constant_time_eq", + "constant_time_eq 0.3.1", "crc32fast", "crossbeam-utils", "deflate64", "flate2", "getrandom 0.3.2", - "hmac", - "indexmap", + "hmac 0.12.1", + "indexmap 2.11.0", "lzma-rs", "memchr", "pbkdf2", diff --git a/Cargo.toml b/Cargo.toml index bf745d402..321ebb532 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,19 @@ [workspace] -members = ["mopro-ffi", "cli", "tests"] +members = [ + "core", + "provers/circom-adapter", + "provers/halo2-adapter", + "provers/noir-adapter", + "ffi/common", + "ffi/uniffi", + "ffi/wasm", + "ffi/flutter", + "ffi/react-native", + "mopro-ffi", + "cli", + "test-app", + "tests", +] resolver = "2" [workspace.dependencies] diff --git a/core/Cargo.toml b/core/Cargo.toml new file mode 100644 index 000000000..62ef3e2f5 --- /dev/null +++ b/core/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "mopro-core" +version = "0.1.0" +edition = "2021" +description = "Core traits and shared types for mopro ZK proof backends" +license = "MIT OR Apache-2.0" +repository = "https://github.com/zkmopro/mopro" +homepage = "https://zkmopro.org/" + +[dependencies] +thiserror = "2.0" diff --git a/core/src/error.rs b/core/src/error.rs new file mode 100644 index 000000000..35b938386 --- /dev/null +++ b/core/src/error.rs @@ -0,0 +1,17 @@ +#[derive(Debug, thiserror::Error)] +pub enum MoproError { + #[error("prover error: {0}")] + ProverError(String), + + #[error("verifier error: {0}")] + VerifierError(String), + + #[error("serialization error: {0}")] + SerializationError(String), + + #[error("circuit not found: {0}")] + CircuitNotFound(String), + + #[error("invalid input: {0}")] + InvalidInput(String), +} diff --git a/core/src/lib.rs b/core/src/lib.rs new file mode 100644 index 000000000..f2a40f5be --- /dev/null +++ b/core/src/lib.rs @@ -0,0 +1,56 @@ +mod error; +mod prover; +mod types; + +pub use error::MoproError; +pub use prover::Prover; +pub use types::ProofBytes; + +#[cfg(test)] +mod tests { + use super::*; + + struct FakeProver { + secret: u8, + } + + impl Prover for FakeProver { + type Input = Vec; + type Output = ProofBytes; + + fn prove(&self, input: Self::Input) -> Result { + let proof = input.iter().map(|b| b ^ self.secret).collect(); + Ok(ProofBytes { proof, public_inputs: vec![self.secret] }) + } + + fn verify(&self, output: &ProofBytes) -> Result { + Ok(output.public_inputs.first().copied() == Some(self.secret)) + } + } + + #[test] + fn prover_trait_is_implementable() { + let p = FakeProver { secret: 42 }; + let out = p.prove(vec![1, 2, 3]).unwrap(); + assert!(p.verify(&out).unwrap()); + } + + #[test] + fn mopro_error_display() { + let e = MoproError::ProverError("bad zkey".to_string()); + assert_eq!(e.to_string(), "prover error: bad zkey"); + + let e = MoproError::CircuitNotFound("multiplier2".to_string()); + assert_eq!(e.to_string(), "circuit not found: multiplier2"); + + let e = MoproError::InvalidInput("expected JSON".to_string()); + assert_eq!(e.to_string(), "invalid input: expected JSON"); + } + + #[test] + fn proof_bytes_equality() { + let a = ProofBytes { proof: vec![1, 2], public_inputs: vec![3] }; + let b = a.clone(); + assert_eq!(a, b); + } +} diff --git a/core/src/prover.rs b/core/src/prover.rs new file mode 100644 index 000000000..838e1d65c --- /dev/null +++ b/core/src/prover.rs @@ -0,0 +1,35 @@ +use crate::MoproError; + +/// The core contract that every ZK proof backend must implement. +/// +/// The struct implementing this trait acts as the "configured prover": it holds +/// all circuit-specific state (key paths, compile options, runtime handles, +/// etc.) established at construction time. `prove` and `verify` are then +/// called without re-passing that configuration. +/// +/// Associated types let each backend own its wire format: +/// - `Input` — the witness / circuit inputs (JSON string, `HashMap`, `Vec`, …) +/// - `Output` — the proof artifact plus public outputs bundled together +/// +/// Both bounds are intentionally minimal (`Send` only). Backends may add +/// `Clone`, `Serialize`, or other traits on their concrete types as needed. +pub trait Prover: Send + Sync { + /// Witness / circuit inputs consumed during proof generation. + type Input: Send; + + /// Opaque bundle of proof bytes and public outputs. + /// The same value produced by `prove` is passed back to `verify`. + type Output: Send; + + /// Generate a ZK proof from the given inputs. + /// + /// The prover's configuration (key paths, options) was fixed at + /// construction and is accessed via `&self`. + fn prove(&self, input: Self::Input) -> Result; + + /// Verify a proof previously produced by `prove`. + /// + /// Returns `Ok(true)` if the proof is valid, `Ok(false)` if it is not, + /// and `Err(…)` only when the verification process itself fails. + fn verify(&self, output: &Self::Output) -> Result; +} diff --git a/core/src/types.rs b/core/src/types.rs new file mode 100644 index 000000000..a48afbcc1 --- /dev/null +++ b/core/src/types.rs @@ -0,0 +1,11 @@ +/// A serialized proof bundle suitable for backends that represent proofs as +/// raw bytes (e.g. Halo2, Noir). +/// +/// Backends with structured proof types (e.g. Circom's G1/G2 representation, +/// Gnark's hex-encoded serialization) define their own output types in their +/// respective crates and do not need to use this type. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ProofBytes { + pub proof: Vec, + pub public_inputs: Vec, +} diff --git a/ffi/common/Cargo.toml b/ffi/common/Cargo.toml new file mode 100644 index 000000000..984882204 --- /dev/null +++ b/ffi/common/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "mopro-build-common" +version = "0.1.0" +edition = "2021" +description = "Shared build-pipeline types and utilities for mopro FFI backends" +license = "MIT OR Apache-2.0" +repository = "https://github.com/zkmopro/mopro" + +[dependencies] +anyhow = "1.0" +color-eyre = "0.6" +uuid = { version = "1.9", features = ["v4"] } +toml = "0.8" diff --git a/ffi/common/src/constants.rs b/ffi/common/src/constants.rs new file mode 100644 index 000000000..e5f2761be --- /dev/null +++ b/ffi/common/src/constants.rs @@ -0,0 +1,240 @@ +use color_eyre::eyre::ContextCompat; + +pub const BUILD_MODE_ENV: &str = "CONFIGURATION"; +pub const IOS_ARCHS_ENV: &str = "IOS_ARCHS"; +pub const ANDROID_ARCHS_ENV: &str = "ANDROID_ARCHS"; +pub const FLUTTER_ARCHS_ENV: &str = "FLUTTER_ARCHS"; +pub const REACT_NATIVE_ARCHS_ENV: &str = "REACT_NATIVE_ARCHS"; + +pub const IOS_BINDINGS_DIR: &str = "MoproiOSBindings"; +pub const IOS_SWIFT_FILE: &str = "mopro.swift"; +pub const IOS_XCFRAMEWORKS_DIR: &str = "MoproBindings.xcframework"; + +pub const ANDROID_BINDINGS_DIR: &str = "MoproAndroidBindings"; +pub const ANDROID_JNILIBS_DIR: &str = "jniLibs"; +pub const ANDROID_UNIFFI_DIR: &str = "uniffi"; +pub const ANDROID_PACKAGE_NAME: &str = "mopro"; +pub const ANDROID_KT_FILE: &str = "mopro.kt"; + +pub const WEB_BINDINGS_DIR: &str = "MoproWasmBindings"; + +pub const ARCH_X86_64: &str = "x86_64"; +pub const ARCH_ARM_64: &str = "aarch64"; +pub const ARCH_I686: &str = "x86"; +pub const ARCH_ARM_V7_ABI: &str = "armeabi-v7a"; +pub const ARCH_ARM_64_V8: &str = "arm64-v8a"; + +pub const FLUTTER_BINDINGS_DIR: &str = "mopro_flutter_bindings"; +pub const REACT_NATIVE_BINDINGS_DIR: &str = "MoproReactNativeBindings"; + +// --------------------------------------------------------------------------- +// Mode +// --------------------------------------------------------------------------- + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum Mode { + Debug, + Release, +} + +struct ModeInfo { mode: Mode, str: &'static str } +const MODES: [ModeInfo; 2] = [ + ModeInfo { mode: Mode::Debug, str: "debug" }, + ModeInfo { mode: Mode::Release, str: "release" }, +]; + +impl Mode { + pub fn as_str(&self) -> &'static str { + MODES.iter().find(|i| i.mode == *self).map(|i| i.str) + .expect("Unsupported Mode") + } + pub fn parse_from_str(s: &str) -> Self { + MODES.iter().find(|i| i.str.to_lowercase() == s.to_lowercase()) + .map(|i| i.mode) + .expect("Unsupported Mode string — only 'release' and 'debug'") + } + pub fn from_idx(idx: usize) -> Self { MODES[idx].mode } + pub fn idx(s: &str) -> Option { + MODES.iter().enumerate().find(|(_, m)| m.str == s).map(|(i, _)| i) + } + pub fn all_strings() -> Vec<&'static str> { MODES.iter().map(|i| i.str).collect() } +} + +// --------------------------------------------------------------------------- +// Arch trait + PlatformBuilder trait +// +// Platform structs (IosPlatform, WebPlatform, etc.) are NOT defined here — +// each ffi/backends/* crate defines its own so that `impl PlatformBuilder for +// ` satisfies the Rust orphan rule. +// --------------------------------------------------------------------------- + +pub trait Arch { + fn as_str(&self) -> &'static str; + fn parse_from_str>(s: S) -> Self; + fn all_strings() -> Vec<&'static str>; + fn all_display_strings() -> Vec<(String, String)>; + fn env_var_name() -> &'static str; +} + +pub trait PlatformBuilder { + type Arch: Arch; + type Params: Default; + + fn identifier() -> &'static str; + fn build( + mode: Mode, + project_dir: &std::path::Path, + target_arch: Vec, + params: Self::Params, + ) -> anyhow::Result; +} + +// --------------------------------------------------------------------------- +// iOS arch +// --------------------------------------------------------------------------- + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum IosArch { Aarch64Apple, Aarch64AppleSim, X8664Apple } + +struct IosArchInfo { arch: IosArch, str: &'static str, description: &'static str } +const IOS_ARCHS: [IosArchInfo; 3] = [ + IosArchInfo { arch: IosArch::Aarch64Apple, str: "aarch64-apple-ios", description: "64-bit iOS devices" }, + IosArchInfo { arch: IosArch::Aarch64AppleSim, str: "aarch64-apple-ios-sim", description: "ARM64 iOS simulator" }, + IosArchInfo { arch: IosArch::X8664Apple, str: "x86_64-apple-ios", description: "x86_64 iOS simulator" }, +]; + +impl Arch for IosArch { + fn as_str(&self) -> &'static str { + IOS_ARCHS.iter().find(|i| i.arch == *self).map(|i| i.str).expect("Unsupported iOS Arch") + } + fn parse_from_str>(s: S) -> Self { + IOS_ARCHS.iter().find(|i| i.str.to_lowercase() == s.as_ref().to_lowercase()) + .map(|i| i.arch) + .context(format!("Unsupported iOS Arch '{}'", s.as_ref())).unwrap() + } + fn all_strings() -> Vec<&'static str> { IOS_ARCHS.iter().map(|i| i.str).collect() } + fn all_display_strings() -> Vec<(String, String)> { + IOS_ARCHS.iter().map(|i| (i.str.to_string(), i.description.to_string())).collect() + } + fn env_var_name() -> &'static str { IOS_ARCHS_ENV } +} + +// --------------------------------------------------------------------------- +// Android arch +// --------------------------------------------------------------------------- + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum AndroidArch { X8664Linux, I686Linux, Armv7LinuxAbi, Aarch64Linux } + +struct AndroidArchInfo { arch: AndroidArch, str: &'static str, description: &'static str } +const ANDROID_ARCHS: [AndroidArchInfo; 4] = [ + AndroidArchInfo { arch: AndroidArch::X8664Linux, str: "x86_64-linux-android", description: "64-bit Android emulators" }, + AndroidArchInfo { arch: AndroidArch::I686Linux, str: "i686-linux-android", description: "32-bit Android emulators" }, + AndroidArchInfo { arch: AndroidArch::Armv7LinuxAbi, str: "armv7-linux-androideabi", description: "32-bit ARM devices" }, + AndroidArchInfo { arch: AndroidArch::Aarch64Linux, str: "aarch64-linux-android", description: "64-bit ARM devices" }, +]; + +impl Arch for AndroidArch { + fn as_str(&self) -> &'static str { + ANDROID_ARCHS.iter().find(|i| i.arch == *self).map(|i| i.str).expect("Unsupported Android Arch") + } + fn parse_from_str>(s: S) -> Self { + ANDROID_ARCHS.iter().find(|i| i.str.to_lowercase() == s.as_ref().to_lowercase()) + .map(|i| i.arch) + .context(format!("Unsupported Android Arch '{}'", s.as_ref())).unwrap() + } + fn all_strings() -> Vec<&'static str> { ANDROID_ARCHS.iter().map(|i| i.str).collect() } + fn all_display_strings() -> Vec<(String, String)> { + ANDROID_ARCHS.iter().map(|i| (i.str.to_string(), i.description.to_string())).collect() + } + fn env_var_name() -> &'static str { ANDROID_ARCHS_ENV } +} + +// --------------------------------------------------------------------------- +// Web arch +// --------------------------------------------------------------------------- + +pub struct WebArch; +impl Arch for WebArch { + fn as_str(&self) -> &'static str { "wasm32-unknown-unknown" } + fn parse_from_str>(_s: S) -> Self { WebArch } + fn all_strings() -> Vec<&'static str> { vec!["wasm32-unknown-unknown"] } + fn all_display_strings() -> Vec<(String, String)> { + vec![("wasm32-unknown-unknown".to_string(), "WebAssembly".to_string())] + } + fn env_var_name() -> &'static str { "WEB_ARCHS" } +} + +// --------------------------------------------------------------------------- +// Flutter arch +// --------------------------------------------------------------------------- + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum FlutterArch { + Aarch64Apple, Aarch64AppleSim, X8664Apple, + X8664Linux, I686Linux, Armv7LinuxAbi, Aarch64Linux, +} + +struct FlutterArchInfo { arch: FlutterArch, str: &'static str, description: &'static str } +const FLUTTER_ARCHS: [FlutterArchInfo; 7] = [ + FlutterArchInfo { arch: FlutterArch::Aarch64Apple, str: "aarch64-apple-ios", description: "64-bit iOS devices" }, + FlutterArchInfo { arch: FlutterArch::Aarch64AppleSim, str: "aarch64-apple-ios-sim", description: "ARM64 iOS simulator" }, + FlutterArchInfo { arch: FlutterArch::X8664Apple, str: "x86_64-apple-ios", description: "x86_64 iOS simulator" }, + FlutterArchInfo { arch: FlutterArch::X8664Linux, str: "x86_64-linux-android", description: "64-bit Android emulators" }, + FlutterArchInfo { arch: FlutterArch::I686Linux, str: "i686-linux-android", description: "32-bit Android emulators" }, + FlutterArchInfo { arch: FlutterArch::Armv7LinuxAbi, str: "armv7-linux-androideabi",description: "32-bit ARM devices" }, + FlutterArchInfo { arch: FlutterArch::Aarch64Linux, str: "aarch64-linux-android", description: "64-bit ARM devices" }, +]; + +impl Arch for FlutterArch { + fn as_str(&self) -> &'static str { + FLUTTER_ARCHS.iter().find(|i| i.arch == *self).map(|i| i.str).expect("Unsupported Flutter Arch") + } + fn parse_from_str>(s: S) -> Self { + FLUTTER_ARCHS.iter().find(|i| i.str.to_lowercase() == s.as_ref().to_lowercase()) + .map(|i| i.arch) + .context(format!("Unsupported Flutter Arch '{}'", s.as_ref())).unwrap() + } + fn all_strings() -> Vec<&'static str> { FLUTTER_ARCHS.iter().map(|i| i.str).collect() } + fn all_display_strings() -> Vec<(String, String)> { + FLUTTER_ARCHS.iter().map(|i| (i.str.to_string(), i.description.to_string())).collect() + } + fn env_var_name() -> &'static str { FLUTTER_ARCHS_ENV } +} + +// --------------------------------------------------------------------------- +// React Native arch +// --------------------------------------------------------------------------- + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ReactNativeArch { + Aarch64Apple, Aarch64AppleSim, X8664Apple, + X8664Linux, I686Linux, Armv7LinuxAbi, Aarch64Linux, +} + +struct ReactNativeArchInfo { arch: ReactNativeArch, str: &'static str, description: &'static str } +const REACT_NATIVE_ARCHS: [ReactNativeArchInfo; 7] = [ + ReactNativeArchInfo { arch: ReactNativeArch::Aarch64Apple, str: "aarch64-apple-ios", description: "64-bit iOS devices" }, + ReactNativeArchInfo { arch: ReactNativeArch::Aarch64AppleSim, str: "aarch64-apple-ios-sim", description: "ARM64 iOS simulator" }, + ReactNativeArchInfo { arch: ReactNativeArch::X8664Apple, str: "x86_64-apple-ios", description: "x86_64 iOS simulator" }, + ReactNativeArchInfo { arch: ReactNativeArch::X8664Linux, str: "x86_64-linux-android", description: "64-bit Android emulators" }, + ReactNativeArchInfo { arch: ReactNativeArch::I686Linux, str: "i686-linux-android", description: "32-bit Android emulators" }, + ReactNativeArchInfo { arch: ReactNativeArch::Armv7LinuxAbi, str: "armv7-linux-androideabi",description: "32-bit ARM devices" }, + ReactNativeArchInfo { arch: ReactNativeArch::Aarch64Linux, str: "aarch64-linux-android", description: "64-bit ARM devices" }, +]; + +impl Arch for ReactNativeArch { + fn as_str(&self) -> &'static str { + REACT_NATIVE_ARCHS.iter().find(|i| i.arch == *self).map(|i| i.str).expect("Unsupported RN Arch") + } + fn parse_from_str>(s: S) -> Self { + REACT_NATIVE_ARCHS.iter().find(|i| i.str.to_lowercase() == s.as_ref().to_lowercase()) + .map(|i| i.arch) + .context(format!("Unsupported React Native Arch '{}'", s.as_ref())).unwrap() + } + fn all_strings() -> Vec<&'static str> { REACT_NATIVE_ARCHS.iter().map(|i| i.str).collect() } + fn all_display_strings() -> Vec<(String, String)> { + REACT_NATIVE_ARCHS.iter().map(|i| (i.str.to_string(), i.description.to_string())).collect() + } + fn env_var_name() -> &'static str { REACT_NATIVE_ARCHS_ENV } +} diff --git a/ffi/common/src/lib.rs b/ffi/common/src/lib.rs new file mode 100644 index 000000000..ec65805d7 --- /dev/null +++ b/ffi/common/src/lib.rs @@ -0,0 +1,5 @@ +pub mod constants; +pub mod utils; + +pub use constants::*; +pub use utils::*; diff --git a/ffi/common/src/utils.rs b/ffi/common/src/utils.rs new file mode 100644 index 000000000..89fd24f70 --- /dev/null +++ b/ffi/common/src/utils.rs @@ -0,0 +1,142 @@ +use anyhow::Context; +use std::fs; +use std::path::{Path, PathBuf}; +use std::process::Command; +use toml::Value; +use uuid::Uuid; + +use crate::constants::{Arch, PlatformBuilder, BUILD_MODE_ENV}; +use crate::Mode; + +// --------------------------------------------------------------------------- +// Temp-dir helpers +// --------------------------------------------------------------------------- + +pub fn mktemp() -> PathBuf { + let dir = std::env::temp_dir().join(Uuid::new_v4().to_string()); + fs::create_dir(&dir).expect("Failed to create tmpdir"); + dir +} + +fn tmp_local(build_path: &Path) -> PathBuf { + let tmp_path = build_path.join("tmp"); + if let Ok(metadata) = fs::metadata(&tmp_path) { + if !metadata.is_dir() { panic!("non-directory tmp"); } + } else { + fs::create_dir_all(&tmp_path).expect("Failed to create local tmpdir"); + } + tmp_path +} + +pub fn mktemp_local(build_path: &Path) -> PathBuf { + let dir = tmp_local(build_path).join(Uuid::new_v4().to_string()); + fs::create_dir(&dir).expect("Failed to create tmpdir"); + dir +} + +pub fn cleanup_tmp_local(build_path: &Path) { + fs::remove_dir_all(tmp_local(build_path)).expect("Failed to remove tmpdir"); +} + +// --------------------------------------------------------------------------- +// Tool installers +// --------------------------------------------------------------------------- + +pub fn install_ndk() { + Command::new("cargo") + .args(["install", "cargo-ndk"]) + .spawn().expect("Failed to spawn cargo") + .wait().expect("Failed to install cargo-ndk"); +} + +pub fn install_arch(arch: String) { + Command::new("rustup") + .args(["target", "add", &arch]) + .spawn().expect("Failed to spawn rustup") + .wait().unwrap_or_else(|_| panic!("Failed to install target {arch}")); +} + +// --------------------------------------------------------------------------- +// Cargo.toml helpers +// --------------------------------------------------------------------------- + +pub fn project_name_from_toml(project_dir: &Path) -> anyhow::Result { + let cargo_toml_path = project_dir.join("Cargo.toml"); + let content = fs::read_to_string(cargo_toml_path).context("Failed to read Cargo.toml")?; + let cargo_toml: Value = content.parse::().context("Failed to parse Cargo.toml")?; + + let project_name = cargo_toml + .get("lib").and_then(|l| l.get("name")).and_then(|n| n.as_str()).map(str::to_string) + .or_else(|| { + cargo_toml.get("package").and_then(|p| p.get("name")) + .and_then(|n| n.as_str().map(|s| s.replace('-', "_"))) + }); + + project_name.ok_or(anyhow::anyhow!("Failed to find project name in Cargo.toml")) +} + +pub fn raw_project_name_from_toml(project_dir: &Path) -> anyhow::Result { + let cargo_toml_path = project_dir.join("Cargo.toml"); + let content = fs::read_to_string(cargo_toml_path).context("Failed to read Cargo.toml")?; + let cargo_toml: Value = content.parse::().context("Failed to parse Cargo.toml")?; + + let project_name = cargo_toml + .get("package").and_then(|p| p.get("name")) + .and_then(|n| n.as_str().map(str::to_string)); + + project_name.ok_or(anyhow::anyhow!("Failed to find project name in Cargo.toml")) +} + +// --------------------------------------------------------------------------- +// Build drivers (called by each backend's top-level entry point) +// --------------------------------------------------------------------------- + +pub fn build_from_env() { + let project_dir = get_project_dir(); + build_from_env_at::(&project_dir); +} + +pub fn build_from_env_at(project_dir: &Path) { + let mode = get_build_mode(); + let target_archs: Vec = get_target_archs(); + let params = Builder::Params::default(); + + if target_archs.is_empty() { return; } + + Builder::build(mode, project_dir, target_archs, params) + .context(format!("Failed to build {} bindings", Builder::identifier())) + .unwrap(); +} + +pub fn build_from_str_arch( + mode: Mode, + project_dir: &Path, + target_archs: Vec<&String>, + params: Builder::Params, +) -> anyhow::Result { + if target_archs.is_empty() { + anyhow::bail!("No target architectures specified for {} bindings", Builder::identifier()); + } + let target_archs: Vec = target_archs.iter().map(Builder::Arch::parse_from_str).collect(); + Builder::build(mode, project_dir, target_archs, params) + .context(format!("Failed to build {} bindings", Builder::identifier())) +} + +fn get_project_dir() -> PathBuf { + std::env::var("CARGO_MANIFEST_DIR").map(PathBuf::from).unwrap_or_else(|_| PathBuf::from(".")) +} + +fn get_build_mode() -> Mode { + Mode::parse_from_str( + std::env::var(BUILD_MODE_ENV).unwrap_or_else(|_| "debug".to_string()).as_str(), + ) +} + +fn get_target_archs() -> Vec { + if let Ok(archs_str) = std::env::var(A::env_var_name()) { + if archs_str.is_empty() { return vec![]; } + archs_str.split(',').map(A::parse_from_str).collect() + } else { + A::all_strings().iter().map(|s| A::parse_from_str(s)).collect() + } +} diff --git a/ffi/flutter/Cargo.toml b/ffi/flutter/Cargo.toml new file mode 100644 index 000000000..11fbcc2d5 --- /dev/null +++ b/ffi/flutter/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "mopro-flutter-backend" +version = "0.1.0" +edition = "2021" +description = "mopro build-pipeline backend: Flutter bindings via flutter_rust_bridge codegen" +license = "MIT OR Apache-2.0" +repository = "https://github.com/zkmopro/mopro" + +[dependencies] +mopro-build-common = { path = "../common" } +anyhow = "1.0" +toml = "0.8" diff --git a/ffi/flutter/src/lib.rs b/ffi/flutter/src/lib.rs new file mode 100644 index 000000000..f368638a1 --- /dev/null +++ b/ffi/flutter/src/lib.rs @@ -0,0 +1,198 @@ +use anyhow::Context; +use std::fs; +use std::path::{Path, PathBuf}; +use std::process::Command; +use toml::Value; + +use mopro_build_common::{ + build_from_env, raw_project_name_from_toml, + PlatformBuilder, FLUTTER_BINDINGS_DIR, +}; +pub use mopro_build_common::{FlutterArch, Mode}; + +pub struct FlutterPlatform; + +pub fn build() { + build_from_env::() +} + +pub fn build_at(project_dir: &std::path::Path) { + mopro_build_common::build_from_env_at::(project_dir) +} + +impl PlatformBuilder for FlutterPlatform { + type Arch = FlutterArch; + type Params = (); + + fn identifier() -> &'static str { "flutter" } + + fn build( + _mode: Mode, + project_dir: &Path, + _target_archs: Vec, + _params: Self::Params, + ) -> anyhow::Result { + init_flutter_bindings(project_dir)?; + + let cargo_toml_path = project_dir.join(FLUTTER_BINDINGS_DIR).join("rust/Cargo.toml"); + ensure_workspace_toml(cargo_toml_path.to_string_lossy().as_ref()); + + let third_party_crate_name = raw_project_name_from_toml(project_dir)?; + let cargo_add_status = Command::new("cargo") + .args([ + "add", &third_party_crate_name, + "--path", project_dir.to_string_lossy().as_ref(), + "--no-default-features", "--features", "flutter", + ]) + .current_dir(project_dir.join(FLUTTER_BINDINGS_DIR).join("rust")) + .status().expect("failed to run cargo add"); + if !cargo_add_status.success() { + return Err(anyhow::anyhow!("Failed to add third party crate")); + } + + replace_relative_path_with_absolute(&cargo_toml_path, &third_party_crate_name, project_dir)?; + patch_cargokit_build_script(project_dir)?; + add_cpp_flag_to_ios_podspec(project_dir)?; + disable_android_architecture_support(project_dir)?; + copy_libcxx_shared_so_to_jni_libs(project_dir)?; + + let rust_root = project_dir.join(FLUTTER_BINDINGS_DIR).join("rust"); + let dart_output = project_dir.join(FLUTTER_BINDINGS_DIR).join("lib/src/rust"); + let generate_status = Command::new("flutter_rust_bridge_codegen") + .args([ + "generate", + "--rust-root", &rust_root.to_string_lossy(), + "--rust-input", &third_party_crate_name, + "--dart-output", &dart_output.to_string_lossy(), + ]) + .current_dir(project_dir) + .status().expect("failed to run flutter_rust_bridge_codegen"); + if !generate_status.success() { + return Err(anyhow::anyhow!("Failed to generate FRB bindings")); + } + + Ok(PathBuf::from(FLUTTER_BINDINGS_DIR)) + } +} + +fn install_flutter_rust_bridge_codegen() -> anyhow::Result<()> { + match Command::new("flutter_rust_bridge_codegen").output() { + Ok(_) => Ok(()), + Err(e) if e.kind() == std::io::ErrorKind::NotFound => { + let status = Command::new("cargo") + .args(["install", "flutter_rust_bridge_codegen@=2.11.1"]) + .status().expect("failed to install flutter_rust_bridge_codegen"); + if !status.success() { + Err(anyhow::anyhow!("Failed to install flutter_rust_bridge_codegen")) + } else { Ok(()) } + } + Err(e) => Err(anyhow::anyhow!("Failed to check for flutter_rust_bridge_codegen: {}", e)), + } +} + +fn init_flutter_bindings(project_dir: &Path) -> anyhow::Result<()> { + let flutter_bindings_dir = project_dir.join(FLUTTER_BINDINGS_DIR); + install_flutter_rust_bridge_codegen()?; + if !flutter_bindings_dir.exists() { + let status = Command::new("flutter_rust_bridge_codegen") + .args(["create", FLUTTER_BINDINGS_DIR, "--template", "plugin"]) + .status().expect("failed to run flutter_rust_bridge_codegen"); + if !status.success() { + return Err(anyhow::anyhow!("flutter_rust_bridge_codegen failed")); + } + } + Ok(()) +} + +fn ensure_workspace_toml(cargo_toml_path: &str) { + let content = fs::read_to_string(cargo_toml_path).expect("Failed to read Cargo.toml"); + if !content.contains("[workspace]") { + let new_content = format!("{content}\n\n[workspace]\n"); + fs::write(cargo_toml_path, new_content).expect("Failed to write updated Cargo.toml"); + } +} + +fn replace_relative_path_with_absolute( + cargo_toml_path: &Path, + crate_name: &str, + abs_path: &Path, +) -> anyhow::Result<()> { + let content = fs::read_to_string(cargo_toml_path).context("Failed to read Cargo.toml")?; + let mut cargo_toml: Value = content.parse::().context("Failed to parse Cargo.toml")?; + + if let Some(Value::Table(table)) = cargo_toml.get_mut("dependencies").and_then(|d| d.get_mut(crate_name)) { + table.insert("path".to_string(), Value::String(abs_path.to_string_lossy().to_string())); + } + + let updated = toml::to_string_pretty(&cargo_toml).context("Failed to serialize Cargo.toml")?; + fs::write(cargo_toml_path, updated).context("Failed to write updated Cargo.toml") +} + +fn patch_cargokit_build_script(project_dir: &Path) -> anyhow::Result<()> { + let path = project_dir.join(FLUTTER_BINDINGS_DIR).join("cargokit/gradle/plugin.gradle"); + let content = fs::read_to_string(path.clone()).context("Failed to read plugin.gradle")?; + if !content.contains("if (plugin.class.name == \"com.flutter.gradle.FlutterPlugin\" || plugin.class.name == \"FlutterPlugin\")") { + let updated = content + .replace( + "if (plugin.class.name == \"com.flutter.gradle.FlutterPlugin\")", + "if (plugin.class.name == \"com.flutter.gradle.FlutterPlugin\" || plugin.class.name == \"FlutterPlugin\")" + ) + .replace( + " def platforms = com.flutter.gradle.FlutterPluginUtils.getTargetPlatforms(project).collect()", + " def List platforms\n try {\n platforms = com.flutter.gradle.FlutterPluginUtils.getTargetPlatforms(project).collect()\n } catch (Exception ignored) {\n platforms = plugin.getTargetPlatforms().collect()\n }" + ); + fs::write(&path, updated).context("Failed to write updated plugin.gradle")?; + } + Ok(()) +} + +fn add_cpp_flag_to_ios_podspec(project_dir: &Path) -> anyhow::Result<()> { + let path = project_dir.join(FLUTTER_BINDINGS_DIR).join("ios") + .join(format!("{FLUTTER_BINDINGS_DIR}.podspec")); + let content = fs::read_to_string(path.clone()).context("Failed to read podspec")?; + if !content.contains("-lc++") { + let updated = content.replace( + "'OTHER_LDFLAGS' => '-force_load ${BUILT_PRODUCTS_DIR}/libmopro_flutter_bindings.a'", + "'OTHER_LDFLAGS' => '-force_load ${BUILT_PRODUCTS_DIR}/libmopro_flutter_bindings.a -lc++'", + ); + fs::write(&path, updated).context("Failed to write updated podspec")?; + } + Ok(()) +} + +fn disable_android_architecture_support(project_dir: &Path) -> anyhow::Result<()> { + let path = project_dir.join(FLUTTER_BINDINGS_DIR).join("cargokit/gradle/plugin.gradle"); + let content = fs::read_to_string(path.clone()).context("Failed to read plugin.gradle")?; + let updated = content + .replace(" platforms.add(\"android-x86\")", "") + .replace(" platforms.add(\"android-x64\")", ""); + fs::write(&path, updated).context("Failed to write updated plugin.gradle") +} + +fn copy_libcxx_shared_so_to_jni_libs(project_dir: &Path) -> anyhow::Result<()> { + let path = project_dir.join(FLUTTER_BINDINGS_DIR).join("cargokit/gradle/plugin.gradle"); + let content = fs::read_to_string(path.clone()).context("Failed to read plugin.gradle")?; + if !content.contains("// After cargo build in CargoKitBuildTask.build()") { + let updated = content.replace( + "project.tasks.whenTaskAdded onTask", + "project.tasks.whenTaskAdded onTask\n + // After cargo build in CargoKitBuildTask.build() + def outputDir = new File(cargoOutputDir) + def ndkDir = plugin.project.android.ndkDirectory + def abiMap = [ + \"arm64-v8a\" : \"aarch64-linux-android\", + \"armeabi-v7a\" : \"arm-linux-androideabi\", + \"x86\" : \"i686-linux-android\", + \"x86_64\" : \"x86_64-linux-android\" + ] + abiMap.each { abi, triple -> + def srcLibcxx = new File(\"${ndkDir}/toolchains/llvm/prebuilt/${Os.isFamily(Os.FAMILY_MAC) ? \"darwin-x86_64\" : \"linux-x86_64\"}/sysroot/usr/lib/${triple}/libc++_shared.so\") + def destDir = new File(\"${outputDir}/${abi}\") + destDir.mkdirs() + project.copy { from srcLibcxx; into destDir } + }" + ); + fs::write(&path, updated).context("Failed to write updated plugin.gradle")?; + } + Ok(()) +} diff --git a/ffi/react-native/Cargo.toml b/ffi/react-native/Cargo.toml new file mode 100644 index 000000000..80388bc11 --- /dev/null +++ b/ffi/react-native/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "mopro-react-native-backend" +version = "0.1.0" +edition = "2021" +description = "mopro build-pipeline backend: React Native bindings via uniffi-bindgen-react-native" +license = "MIT OR Apache-2.0" +repository = "https://github.com/zkmopro/mopro" + +[dependencies] +mopro-build-common = { path = "../common" } +anyhow = "1.0" +fs_extra = "1.2" diff --git a/ffi/react-native/src/lib.rs b/ffi/react-native/src/lib.rs new file mode 100644 index 000000000..49c071bdf --- /dev/null +++ b/ffi/react-native/src/lib.rs @@ -0,0 +1,136 @@ +use anyhow::Context; +use std::fs; +use std::path::{Path, PathBuf}; +use std::process::Command; + +use mopro_build_common::{ + build_from_env, Arch, PlatformBuilder, + REACT_NATIVE_BINDINGS_DIR, +}; +pub use mopro_build_common::{ReactNativeArch, Mode}; + +pub struct ReactNativePlatform; + +pub fn build() { + build_from_env::() +} + +pub fn build_at(project_dir: &std::path::Path) { + mopro_build_common::build_from_env_at::(project_dir) +} + +impl PlatformBuilder for ReactNativePlatform { + type Arch = ReactNativeArch; + type Params = (); + + fn identifier() -> &'static str { "react-native" } + + fn build( + mode: Mode, + project_dir: &Path, + target_archs: Vec, + _params: Self::Params, + ) -> anyhow::Result { + install_uniffi_bindgen_react_native()?; + + fs::create_dir_all(project_dir.join(REACT_NATIVE_BINDINGS_DIR)) + .expect("failed to create bindings directory"); + + let template_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("template"); + let mut copy_options = fs_extra::dir::CopyOptions::new(); + copy_options.overwrite = true; + copy_options.content_only = true; + fs_extra::dir::copy( + &template_dir, + project_dir.join(REACT_NATIVE_BINDINGS_DIR), + ©_options, + ).with_context(|| format!("Failed to copy react_native template from {:?}", template_dir))?; + + let target_file = project_dir.join(REACT_NATIVE_BINDINGS_DIR).join("ubrn.config.yaml"); + let contents = fs::read_to_string(&target_file) + .with_context(|| format!("Failed to read ubrn.config.yaml from {:?}", target_file))? + .replace("<%PATH_TO_PROJECT%>", &project_dir.to_string_lossy()); + fs::write(&target_file, contents) + .with_context(|| format!("Failed to write ubrn.config.yaml to {:?}", target_file))?; + + generate_react_native_bindings(project_dir, target_archs, mode)?; + Ok(PathBuf::from(REACT_NATIVE_BINDINGS_DIR)) + } +} + +fn install_uniffi_bindgen_react_native() -> anyhow::Result<()> { + match Command::new("uniffi-bindgen-react-native").output() { + Ok(_) => Ok(()), + Err(e) if e.kind() == std::io::ErrorKind::NotFound => { + let current_path: PathBuf = std::env::current_dir()?; + let status = Command::new("git") + .args(["clone", "https://github.com/jhugman/uniffi-bindgen-react-native.git"]) + .current_dir(current_path.clone()) + .status().expect("failed to download uniffi-bindgen-react-native"); + if !status.success() { + return Err(anyhow::anyhow!("Failed to download uniffi-bindgen-react-native")); + } + let status = Command::new("cargo") + .args(["install", "--path", "."]) + .current_dir(current_path.join("uniffi-bindgen-react-native/crates/ubrn_cli")) + .status().expect("failed to install uniffi-bindgen-react-native"); + if !status.success() { + return Err(anyhow::anyhow!("Failed to install uniffi-bindgen-react-native")); + } + fs::remove_dir_all(current_path.join("uniffi-bindgen-react-native")) + .expect("failed to remove uniffi-bindgen-react-native"); + Ok(()) + } + Err(e) => Err(anyhow::anyhow!("Failed to check for uniffi-bindgen-react-native: {}", e)), + } +} + +fn generate_react_native_bindings( + project_dir: &Path, + target_archs: Vec, + mode: Mode, +) -> anyhow::Result<()> { + let bindings_dir = project_dir.join(REACT_NATIVE_BINDINGS_DIR); + let status = Command::new("uniffi-bindgen-react-native") + .args(["generate", "jsi", "turbo-module"]) + .current_dir(bindings_dir.clone()) + .status().expect("failed to generate react native bindings"); + if !status.success() { + return Err(anyhow::anyhow!("Failed to generate react native bindings")); + } + + let ios_targets = target_archs.iter() + .filter(|a| a.as_str().contains("ios")).map(|a| a.as_str()).collect::>().join(","); + let android_targets = target_archs.iter() + .filter(|a| a.as_str().contains("android")).map(|a| a.as_str()).collect::>().join(","); + + if !ios_targets.is_empty() { + build_for_arch("ios", mode, &ios_targets, &bindings_dir)?; + } else if !android_targets.is_empty() { + build_for_arch("android", mode, &android_targets, &bindings_dir)?; + } + + let npm_status = Command::new("npm") + .args(["pkg", "set", "files[]=*.xcframework/**"]) + .current_dir(bindings_dir) + .status().expect("failed to set files in package.json"); + if !npm_status.success() { + return Err(anyhow::anyhow!("Failed to set files in package.json")); + } + Ok(()) +} + +fn build_for_arch(platform: &str, mode: Mode, target_string: &str, bindings_dir: &Path) -> anyhow::Result<()> { + let mut args = vec!["build".to_string(), platform.to_string(), "--and-generate".to_string()]; + if mode == Mode::Release { args.push("--release".to_string()); } + args.push("--targets".to_string()); + args.push(target_string.to_string()); + + let status = Command::new("uniffi-bindgen-react-native") + .args(&args).current_dir(bindings_dir) + .status().expect("failed to build react native bindings"); + if !status.success() { + return Err(anyhow::anyhow!("Failed to build react native bindings")); + } + Ok(()) +} diff --git a/ffi/react-native/template/android/cpp-adapter.cpp b/ffi/react-native/template/android/cpp-adapter.cpp new file mode 100644 index 000000000..de65ac4cf --- /dev/null +++ b/ffi/react-native/template/android/cpp-adapter.cpp @@ -0,0 +1,43 @@ +// Generated by uniffi-bindgen-react-native +#include +#include +#include +#include "mopro-ffi.h" + +namespace jsi = facebook::jsi; +namespace react = facebook::react; + +// Automated testing checks Java_com_moproffi_MoproFfiModule and moproffi +// by comparing the whole line here. +/* +Java_com_moproffi_MoproFfiModule_nativeMultiply(JNIEnv *env, jclass type, jdouble a, jdouble b) { + return moproffi::multiply(a, b); +} +*/ + +// Installer coming from MoproFfiModule +extern "C" +JNIEXPORT jboolean JNICALL +Java_com_moproffi_MoproFfiModule_nativeInstallRustCrate( + JNIEnv *env, + jclass type, + jlong rtPtr, + jobject callInvokerHolderJavaObj +) { + using JCallInvokerHolder = facebook::react::CallInvokerHolder; + + auto holderLocal = facebook::jni::make_local(callInvokerHolderJavaObj); + auto holderRef = facebook::jni::static_ref_cast(holderLocal); + auto* holderCxx = holderRef->cthis(); + auto jsCallInvoker = holderCxx->getCallInvoker(); + auto runtime = reinterpret_cast(rtPtr); + + return moproffi::installRustCrate(*runtime, jsCallInvoker); +} + +extern "C" +JNIEXPORT jboolean JNICALL +Java_com_moproffi_MoproFfiModule_nativeCleanupRustCrate(JNIEnv *env, jclass type, jlong rtPtr) { + auto runtime = reinterpret_cast(rtPtr); + return moproffi::cleanupRustCrate(*runtime); +} \ No newline at end of file diff --git a/ffi/react-native/template/babel.config.js b/ffi/react-native/template/babel.config.js new file mode 100644 index 000000000..0c05fd696 --- /dev/null +++ b/ffi/react-native/template/babel.config.js @@ -0,0 +1,12 @@ +module.exports = { + overrides: [ + { + exclude: /\/node_modules\//, + presets: ['module:react-native-builder-bob/babel-preset'], + }, + { + include: /\/node_modules\//, + presets: ['module:@react-native/babel-preset'], + }, + ], +}; diff --git a/ffi/react-native/template/package.json b/ffi/react-native/template/package.json new file mode 100644 index 000000000..a3f87e92b --- /dev/null +++ b/ffi/react-native/template/package.json @@ -0,0 +1,169 @@ +{ + "name": "mopro-ffi", + "version": "0.1.0", + "description": "Mopro FFI bindings for React Native", + "main": "./lib/module/index.js", + "types": "./lib/typescript/src/index.d.ts", + "exports": { + ".": { + "source": "./src/index.tsx", + "types": "./lib/typescript/src/index.d.ts", + "default": "./lib/module/index.js" + }, + "./package.json": "./package.json" + }, + "files": [ + "src", + "lib", + "android", + "ios", + "cpp", + "*.podspec", + "react-native.config.js", + "!ios/build", + "!android/build", + "!android/gradle", + "!android/gradlew", + "!android/gradlew.bat", + "!android/local.properties", + "!**/__tests__", + "!**/__fixtures__", + "!**/__mocks__", + "!**/.*" + ], + "scripts": { + "ubrn:ios": "ubrn build ios --and-generate --release && (cd example/ios && pod install)", + "ubrn:android": "ubrn build android --and-generate --release --targets aarch64-linux-android", + "test": "jest", + "typecheck": "tsc", + "lint": "eslint \"**/*.{js,ts,tsx}\"", + "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib", + "prepare": "bob build", + "release": "release-it --only-version" + }, + "keywords": [ + "react-native", + "ios", + "android" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/zkmopro/react-native-app.git" + }, + "author": "ZK Mopro Team (https://zkmopro.com)", + "license": "MIT", + "bugs": { + "url": "https://github.com/zkmopro/react-native-app/issues" + }, + "homepage": "https://github.com/zkmopro/react-native-app#readme", + "publishConfig": { + "registry": "https://registry.npmjs.org/" + }, + "devDependencies": { + "@commitlint/config-conventional": "^19.8.1", + "@eslint/compat": "^1.3.2", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "^9.35.0", + "@evilmartians/lefthook": "^1.12.3", + "@react-native-community/cli": "20.0.1", + "@react-native/babel-preset": "0.81.4", + "@react-native/eslint-config": "^0.81.1", + "@release-it/conventional-changelog": "^10.0.1", + "@types/jest": "^29.5.14", + "@types/react": "^19.1.0", + "commitlint": "^19.8.1", + "del-cli": "^6.0.0", + "eslint": "^9.35.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.4", + "jest": "^29.7.0", + "prettier": "^3.6.2", + "react": "19.1.0", + "react-native": "0.81.4", + "react-native-builder-bob": "^0.40.13", + "release-it": "^19.0.4", + "turbo": "^2.5.6", + "typescript": "^5.9.2" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + }, + "workspaces": [ + "example" + ], + "packageManager": "yarn@3.6.1", + "jest": { + "preset": "react-native", + "modulePathIgnorePatterns": [ + "/example/node_modules", + "/lib/" + ] + }, + "commitlint": { + "extends": [ + "@commitlint/config-conventional" + ] + }, + "release-it": { + "git": { + "commitMessage": "chore: release ${version}", + "tagName": "v${version}" + }, + "npm": { + "publish": true + }, + "github": { + "release": true + }, + "plugins": { + "@release-it/conventional-changelog": { + "preset": { + "name": "angular" + } + } + } + }, + "prettier": { + "quoteProps": "consistent", + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5", + "useTabs": false + }, + "react-native-builder-bob": { + "source": "src", + "output": "lib", + "targets": [ + [ + "module", + { + "esm": true + } + ], + [ + "typescript", + { + "project": "tsconfig.build.json" + } + ] + ] + }, + "codegenConfig": { + "name": "MoproFFISpec", + "type": "modules", + "jsSrcsDir": "src", + "android": { + "javaPackageName": "com.moproffi" + } + }, + "create-react-native-library": { + "languages": "kotlin-objc", + "type": "turbo-module", + "version": "0.54.5" + }, + "dependencies": { + "uniffi-bindgen-react-native": "^0.29.3-1" + } + } + \ No newline at end of file diff --git a/ffi/react-native/template/tsconfig.build.json b/ffi/react-native/template/tsconfig.build.json new file mode 100644 index 000000000..346994411 --- /dev/null +++ b/ffi/react-native/template/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig", + "exclude": ["lib"] +} diff --git a/ffi/react-native/template/tsconfig.json b/ffi/react-native/template/tsconfig.json new file mode 100644 index 000000000..6ae7b53b4 --- /dev/null +++ b/ffi/react-native/template/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "rootDir": ".", + "paths": { + "mopro-ffi": ["./src/index"] + }, + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "customConditions": ["react-native-strict-api"], + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "noImplicitUseStrict": false, + "noStrictGenericChecks": false, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "target": "ESNext", + "verbatimModuleSyntax": true + } +} diff --git a/ffi/react-native/template/turbo.json b/ffi/react-native/template/turbo.json new file mode 100644 index 000000000..c4d78c496 --- /dev/null +++ b/ffi/react-native/template/turbo.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://turbo.build/schema.json", + "globalDependencies": [".nvmrc", ".yarnrc.yml"], + "globalEnv": ["NODE_ENV"], + "tasks": { + "build:android": { + "env": ["ANDROID_HOME", "ORG_GRADLE_PROJECT_newArchEnabled"], + "inputs": [ + "package.json", + "android", + "!android/build", + "src/*.ts", + "src/*.tsx", + "example/package.json", + "example/android", + "!example/android/.gradle", + "!example/android/build", + "!example/android/app/build" + ], + "outputs": [] + }, + "build:ios": { + "env": [ + "RCT_NEW_ARCH_ENABLED", + "RCT_USE_RN_DEP", + "RCT_USE_PREBUILT_RNCORE" + ], + "inputs": [ + "package.json", + "*.podspec", + "ios", + "src/*.ts", + "src/*.tsx", + "example/package.json", + "example/ios", + "!example/ios/build", + "!example/ios/Pods" + ], + "outputs": [] + } + } +} diff --git a/ffi/react-native/template/ubrn.config.yaml b/ffi/react-native/template/ubrn.config.yaml new file mode 100644 index 000000000..3ca82ab65 --- /dev/null +++ b/ffi/react-native/template/ubrn.config.yaml @@ -0,0 +1,7 @@ +rust: + directory: <%PATH_TO_PROJECT%> + manifestPath: Cargo.toml + +android: + apiLevel: 28 + useSharedLibrary: true \ No newline at end of file diff --git a/ffi/uniffi/Cargo.toml b/ffi/uniffi/Cargo.toml new file mode 100644 index 000000000..765201321 --- /dev/null +++ b/ffi/uniffi/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "mopro-uniffi-backend" +version = "0.1.0" +edition = "2021" +description = "mopro build-pipeline backend: iOS and Android bindings via uniffi-bindgen" +license = "MIT OR Apache-2.0" +repository = "https://github.com/zkmopro/mopro" + +[features] +# Set when the project being built uses witnesscalc native libs. +witnesscalc = [] + +[dependencies] +mopro-build-common = { path = "../common" } +uniffi = { version = "=0.31.0", features = ["bindgen"] } +anyhow = "1.0" +camino = "1.1" +fs_extra = "1.2" diff --git a/ffi/uniffi/src/android.rs b/ffi/uniffi/src/android.rs new file mode 100644 index 000000000..1e3965cf0 --- /dev/null +++ b/ffi/uniffi/src/android.rs @@ -0,0 +1,244 @@ +use anyhow::Context; +use camino::Utf8Path; +use std::collections::HashMap; +use std::fs; +use std::io::{Error, ErrorKind}; +use std::path::{Path, PathBuf}; +use std::process::Command; +use uniffi::{generate, GenerateOptions, TargetLanguage}; + +use mopro_build_common::{ + build_from_env, cleanup_tmp_local, install_arch, install_ndk, mktemp_local, + project_name_from_toml, + Arch, AndroidArch, Mode, PlatformBuilder, + ANDROID_BINDINGS_DIR, ANDROID_KT_FILE, ANDROID_PACKAGE_NAME, + ARCH_ARM_64_V8, ARCH_ARM_V7_ABI, ARCH_I686, ARCH_X86_64, +}; + +pub struct AndroidPlatform; + +pub fn build() { + build_from_env::() +} + +pub fn build_at(project_dir: &std::path::Path) { + mopro_build_common::build_from_env_at::(project_dir) +} + +#[derive(Default, Clone)] +pub struct ArchBuildConfig { + pub extra_env: Vec<(String, String)>, + pub extra_rustflags: Vec, +} + +#[derive(Default)] +pub struct AndroidBindingsParams { + pub arch_overrides: HashMap, + pub min_sdk_version: Option, + pub relink_with_ndk_for_bindgen: bool, +} + +impl PlatformBuilder for AndroidPlatform { + type Arch = AndroidArch; + type Params = AndroidBindingsParams; + + fn identifier() -> &'static str { "android" } + + fn build( + mode: Mode, + project_dir: &Path, + target_archs: Vec, + params: Self::Params, + ) -> anyhow::Result { + let uniffi_style_identifier = project_name_from_toml(project_dir) + .expect("Failed to get project name from Cargo.toml"); + + let lib_name = format!("lib{}.so", &uniffi_style_identifier); + let gen_kt_file = format!("{}.kt", &uniffi_style_identifier); + + #[cfg(feature = "witnesscalc")] + let _ = std::env::var("ANDROID_NDK").context("ANDROID_NDK is not set")?; + + let build_dir = project_dir.join("build"); + let work_dir = mktemp_local(&build_dir); + let bindings_out = work_dir.join(ANDROID_BINDINGS_DIR); + let bindings_dest = project_dir.join(ANDROID_BINDINGS_DIR); + + install_ndk(); + let mut latest_out_lib_path = PathBuf::new(); + let mut bindgen_arch: Option = None; + for arch in target_archs { + latest_out_lib_path = build_for_arch(arch, &lib_name, &build_dir, &bindings_out, mode, ¶ms) + .context(format!("Failed to build for architecture: {}", arch.as_str()))?; + bindgen_arch.get_or_insert(arch); + } + + let bindgen_lib_path = if params.relink_with_ndk_for_bindgen { + let arch = bindgen_arch.context("No target architectures provided")?; + build_bindgen_lib(arch, &lib_name, &build_dir, ¶ms) + .context("Failed to build NDK lib for bindgen")? + } else { + latest_out_lib_path + }; + + generate_android_bindings(&bindgen_lib_path, &bindings_out) + .expect("Failed to generate bindings"); + + reformat_kotlin_package( + &uniffi_style_identifier, &gen_kt_file, + ANDROID_PACKAGE_NAME, &ANDROID_KT_FILE, + &bindings_out, + ).expect("Failed to reformat Kotlin package"); + + move_bindings(&bindings_out, &bindings_dest); + cleanup_tmp_local(&build_dir); + + Ok(bindings_out) + } +} + +fn build_for_arch( + arch: AndroidArch, + lib_name: &str, + build_dir: &Path, + bindings_out: &Path, + mode: Mode, + params: &AndroidBindingsParams, +) -> anyhow::Result { + let arch_str = arch.as_str(); + install_arch(arch_str.to_string()); + let cpp_lib_dest = bindings_out.join("jniLibs"); + + let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string()); + let mut build_cmd = Command::new(&cargo); + build_cmd.arg("ndk").arg("-t").arg(arch_str); + if let Some(min_sdk) = params.min_sdk_version { + build_cmd.arg("--platform").arg(min_sdk.to_string()); + } + build_cmd.arg("build").arg("--link-libcxx-shared").arg("--lib"); + if mode == Mode::Release { build_cmd.arg("--release"); } + + apply_arch_config(&mut build_cmd, params.arch_overrides.get(arch_str)); + + let status = build_cmd + .env("CARGO_BUILD_TARGET_DIR", build_dir) + .env("CARGO_BUILD_TARGET", arch_str) + .env("CARGO_NDK_OUTPUT_PATH", cpp_lib_dest) + .spawn().expect("Failed to spawn cargo build") + .wait().expect("cargo build errored"); + if !status.success() { anyhow::bail!("cargo ndk build failed for {arch_str}"); } + + let folder = match arch { + AndroidArch::X8664Linux => ARCH_X86_64, + AndroidArch::I686Linux => ARCH_I686, + AndroidArch::Armv7LinuxAbi => ARCH_ARM_V7_ABI, + AndroidArch::Aarch64Linux => ARCH_ARM_64_V8, + }; + + let out_lib_path = build_dir.join(arch_str).join(mode.as_str()).join(lib_name); + let out_lib_dest = bindings_out.join(format!("jniLibs/{folder}/{lib_name}")); + let parent_dir = out_lib_dest.parent().context("Failed to get parent dir")?; + fs::create_dir_all(parent_dir).context("Failed to create jniLibs directory")?; + fs::copy(&out_lib_path, &out_lib_dest).context("Failed to copy .so")?; + + Ok(out_lib_path) +} + +fn apply_arch_config(build_cmd: &mut Command, config: Option<&ArchBuildConfig>) { + let Some(config) = config else { return; }; + for (key, value) in &config.extra_env { build_cmd.env(key, value); } + if !config.extra_rustflags.is_empty() { + let extra = config.extra_rustflags.join(" "); + let rustflags = match std::env::var("RUSTFLAGS") { + Ok(existing) if !existing.trim().is_empty() => format!("{existing} {extra}"), + _ => extra, + }; + build_cmd.env("RUSTFLAGS", rustflags); + } +} + +fn build_bindgen_lib( + arch: AndroidArch, + lib_name: &str, + build_dir: &Path, + params: &AndroidBindingsParams, +) -> anyhow::Result { + let arch_str = arch.as_str(); + let bindgen_target = build_dir.join("bindgen"); + + let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string()); + let mut build_cmd = Command::new(&cargo); + build_cmd.arg("ndk").arg("-t").arg(arch_str); + if let Some(min_sdk) = params.min_sdk_version { + build_cmd.arg("--platform").arg(min_sdk.to_string()); + } + build_cmd.arg("build").arg("--link-libcxx-shared").arg("--lib"); + + if let Some(config) = params.arch_overrides.get(arch_str) { + for (key, value) in &config.extra_env { build_cmd.env(key, value); } + } + + let status = build_cmd + .env("CARGO_BUILD_TARGET_DIR", &bindgen_target) + .env("CARGO_BUILD_TARGET", arch_str) + .env("CARGO_NDK_OUTPUT_PATH", bindgen_target.join("jniLibs")) + .spawn().expect("Failed to spawn cargo build for bindgen lib") + .wait().expect("cargo build (bindgen lib) errored"); + if !status.success() { anyhow::bail!("cargo ndk build (bindgen lib) failed for {arch_str}"); } + + let out_lib_path = bindgen_target.join(arch_str).join("debug").join(lib_name); + if !out_lib_path.exists() { + anyhow::bail!("NDK bindgen lib missing at {} (needed for uniffi metadata)", out_lib_path.display()); + } + Ok(out_lib_path) +} + +fn move_bindings(bindings_out: &Path, bindings_dest: &Path) { + if let Ok(info) = fs::metadata(bindings_dest) { + if !info.is_dir() { panic!("bindings directory exists and is not a directory"); } + fs::remove_dir_all(bindings_dest).expect("Failed to remove bindings directory"); + } + fs::rename(bindings_out, bindings_dest).expect("Failed to move bindings into place"); +} + +fn generate_android_bindings(dylib_path: &Path, binding_dir: &Path) -> anyhow::Result<()> { + let content = "[bindings.kotlin]\nandroid = true"; + let parent_dir = binding_dir.parent().context("Failed to get parent directory")?; + let config_path = parent_dir.join("uniffi_config.toml"); + fs::write(&config_path, content).expect("Failed to write uniffi_config.toml"); + + generate(GenerateOptions { + languages: vec![TargetLanguage::Kotlin], + source: Utf8Path::from_path(dylib_path) + .ok_or(Error::new(ErrorKind::InvalidInput, "Invalid dylib path"))?.to_path_buf(), + out_dir: Utf8Path::from_path(binding_dir) + .ok_or(Error::new(ErrorKind::InvalidInput, "Invalid kotlin files directory"))?.to_path_buf(), + crate_filter: None, + ..GenerateOptions::default() + }).map_err(|e| Error::other(e.to_string()))?; + Ok(()) +} + +fn reformat_kotlin_package( + gen_module: &str, gen_kt_file: &str, + out_module: &str, out_kt_file: &&str, + bindings_out: &Path, +) -> anyhow::Result<()> { + let gen_path = bindings_out.join("uniffi").join(gen_module).join(gen_kt_file); + let out_path = bindings_out.join("uniffi").join(out_module).join(out_kt_file); + + if gen_path == out_path { return Ok(()); } + + fs::create_dir(bindings_out.join("uniffi").join(out_module)) + .context("Failed to create new package directory")?; + fs::rename(&gen_path, &out_path).context("Failed to move kotlin file")?; + fs::remove_dir(bindings_out.join("uniffi").join(gen_module)) + .context("Failed to remove gen kotlin package dir")?; + + let content = fs::read_to_string(&out_path).context("Failed to read generated Kotlin file")?; + let modified = content.replace( + &format!("package uniffi.{gen_module}"), + &format!("package uniffi.{out_module}"), + ); + fs::write(&out_path, modified).context("Failed to write modified Kotlin file") +} diff --git a/ffi/uniffi/src/ios.rs b/ffi/uniffi/src/ios.rs new file mode 100644 index 000000000..fa6d654b2 --- /dev/null +++ b/ffi/uniffi/src/ios.rs @@ -0,0 +1,199 @@ +use anyhow::Context; +use camino::Utf8Path; +use std::fs; +use std::io::{Error, ErrorKind}; +use std::path::{Path, PathBuf}; +use std::process::Command; +use uniffi::{generate, GenerateOptions, TargetLanguage}; + +use mopro_build_common::{ + build_from_env, cleanup_tmp_local, install_arch, mktemp_local, project_name_from_toml, + Arch, IosArch, Mode, PlatformBuilder, + ARCH_ARM_64, ARCH_X86_64, IOS_BINDINGS_DIR, IOS_SWIFT_FILE, IOS_XCFRAMEWORKS_DIR, +}; + +pub struct IosPlatform; + +pub fn build() { + build_from_env::() +} + +pub fn build_at(project_dir: &std::path::Path) { + mopro_build_common::build_from_env_at::(project_dir) +} + +#[derive(Default)] +pub struct IosBindingsParams { + pub using_noir: bool, +} + +impl PlatformBuilder for IosPlatform { + type Arch = IosArch; + type Params = IosBindingsParams; + + fn identifier() -> &'static str { "ios" } + + fn build( + mode: Mode, + project_dir: &Path, + target_archs: Vec, + params: Self::Params, + ) -> anyhow::Result { + let uniffi_style_identifier = project_name_from_toml(project_dir) + .expect("Failed to get project name from Cargo.toml"); + + let gen_swift_file_name = format!("{uniffi_style_identifier}.swift"); + let lib_name = format!("lib{uniffi_style_identifier}.a"); + let header_name = format!("{uniffi_style_identifier}FFI.h"); + let modulemap_name = format!("{uniffi_style_identifier}FFI.modulemap"); + + let build_dir_path = project_dir.join("build"); + let work_dir = mktemp_local(&build_dir_path); + let swift_bindings_dir = work_dir.join("SwiftBindings"); + let bindings_out = work_dir.join(IOS_BINDINGS_DIR); + fs::create_dir(&bindings_out).expect("Failed to create bindings out directory"); + let bindings_dest = project_dir.join(IOS_BINDINGS_DIR); + let framework_out = bindings_out.join(IOS_XCFRAMEWORKS_DIR); + + let build_combined_archs = |archs: &[IosArch]| -> PathBuf { + let out_lib_paths: Vec = archs.iter().map(|arch| { + build_dir_path.join(format!("{}/{}/{}", arch.as_str(), mode.as_str(), lib_name)) + }).collect(); + for arch in archs { + install_arch(arch.as_str().to_string()); + let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string()); + let mut build_cmd = Command::new(&cargo); + build_cmd.arg("build"); + if mode == Mode::Release { build_cmd.arg("--release"); } + if params.using_noir { build_cmd.env("IPHONEOS_DEPLOYMENT_TARGET", "15.0"); } + build_cmd + .arg("--lib") + .env("CARGO_BUILD_TARGET_DIR", &build_dir_path) + .env("CARGO_BUILD_TARGET", arch.as_str()) + .current_dir(project_dir) + .spawn().expect("Failed to spawn cargo build") + .wait().expect("cargo build errored"); + } + let mut lipo_cmd = Command::new("lipo"); + let lib_out = mktemp_local(&build_dir_path).join(&lib_name); + lipo_cmd.arg("-create").arg("-output").arg(lib_out.to_str().unwrap()); + for p in out_lib_paths { lipo_cmd.arg(p.to_str().unwrap()); } + lipo_cmd.spawn().expect("Failed to spawn lipo").wait().expect("lipo failed"); + lib_out + }; + + let out_lib_paths: Vec = group_target_archs(&target_archs) + .iter().map(|v| build_combined_archs(v)).collect(); + + let out_dylib_path = build_dir_path.join(format!( + "{}/{}/{}", + target_archs[0].as_str(), mode.as_str(), + lib_name.replace(".a", ".dylib") + )); + + generate_ios_bindings(&out_dylib_path, &swift_bindings_dir) + .expect("Failed to generate bindings for iOS"); + + fs::rename( + swift_bindings_dir.join(&gen_swift_file_name), + bindings_out.join(IOS_SWIFT_FILE), + ).context(format!( + "Failed to rename bindings from {}/{gen_swift_file_name}", + swift_bindings_dir.display() + ))?; + + let mut xcbuild_cmd = Command::new("xcodebuild"); + if params.using_noir { xcbuild_cmd.env("IPHONEOS_DEPLOYMENT_TARGET", "15.0"); } + xcbuild_cmd.arg("-create-xcframework"); + for lib_path in out_lib_paths { + xcbuild_cmd + .arg("-library").arg(lib_path.to_str().unwrap()) + .arg("-headers").arg(swift_bindings_dir.to_str().unwrap()); + } + xcbuild_cmd + .arg("-output").arg(framework_out.to_str().unwrap()) + .spawn().context("Failed to spawn xcodebuild")? + .wait().context("xcodebuild failed")?; + + regroup_header_artifacts(&framework_out, &header_name, &modulemap_name, &uniffi_style_identifier) + .expect("Failed to regroup header artifacts"); + + if let Ok(info) = fs::metadata(&bindings_dest) { + if !info.is_dir() { panic!("framework directory exists and is not a directory"); } + fs::remove_dir_all(&bindings_dest).expect("Failed to remove framework directory"); + } + fs::rename(&bindings_out, &bindings_dest).expect("Failed to move framework into place"); + cleanup_tmp_local(&build_dir_path); + + Ok(bindings_dest) + } +} + +fn group_target_archs(target_archs: &[IosArch]) -> Vec> { + let current_arch = std::env::consts::ARCH; + let device_prefix = match current_arch { + arch if arch.starts_with(ARCH_X86_64) => ARCH_X86_64, + arch if arch.starts_with(ARCH_ARM_64) => ARCH_ARM_64, + _ => panic!("Unsupported host architecture: {current_arch}"), + }; + + let mut device_archs = Vec::new(); + let mut simulator_archs = Vec::new(); + target_archs.iter().for_each(|&arch| { + let arch_str = arch.as_str(); + if arch_str.ends_with("sim") { simulator_archs.push(arch); } + else if arch_str.starts_with(device_prefix) { device_archs.push(arch); } + else { simulator_archs.push(arch); } + }); + + let mut grouped = Vec::new(); + if !device_archs.is_empty() { grouped.push(device_archs); } + if !simulator_archs.is_empty() { grouped.push(simulator_archs); } + grouped +} + +pub fn regroup_header_artifacts( + framework_out: &Path, + header_name: &str, + modulemap_name: &str, + project_name: &str, +) -> anyhow::Result<()> { + for entry in fs::read_dir(framework_out).with_context(|| format!("reading {framework_out:?}"))? { + let entry = entry?; + let arch_path = entry.path(); + if !arch_path.is_dir() { continue; } + + let headers_dir = arch_path.join("Headers"); + if !headers_dir.is_dir() { continue; } + + let modmap_src = headers_dir.join(modulemap_name); + let header_src = headers_dir.join(header_name); + let target_dir = headers_dir.join(project_name); + fs::create_dir_all(&target_dir).with_context(|| format!("creating {target_dir:?}"))?; + + if modmap_src.exists() { + fs::rename(&modmap_src, target_dir.join("module.modulemap")) + .with_context(|| format!("moving {modmap_src:?}"))?; + } + if header_src.exists() { + fs::rename(&header_src, target_dir.join(header_name)) + .with_context(|| format!("moving {header_src:?}"))?; + } + } + Ok(()) +} + +fn generate_ios_bindings(dylib_path: &Path, binding_dir: &Path) -> anyhow::Result<()> { + if binding_dir.exists() { fs::remove_dir_all(binding_dir)?; } + + generate(GenerateOptions { + languages: vec![TargetLanguage::Swift], + source: Utf8Path::from_path(dylib_path) + .ok_or(Error::new(ErrorKind::InvalidInput, "Invalid dylib path"))?.to_path_buf(), + out_dir: Utf8Path::from_path(binding_dir) + .ok_or(Error::new(ErrorKind::InvalidInput, "Invalid swift files directory"))?.to_path_buf(), + crate_filter: None, + ..GenerateOptions::default() + }).map_err(|e| Error::other(e.to_string()))?; + Ok(()) +} diff --git a/ffi/uniffi/src/lib.rs b/ffi/uniffi/src/lib.rs new file mode 100644 index 000000000..1db3dbdbe --- /dev/null +++ b/ffi/uniffi/src/lib.rs @@ -0,0 +1,11 @@ +pub mod android; +pub mod ios; + +pub use android::{AndroidBindingsParams, AndroidPlatform, ArchBuildConfig}; +pub use ios::{IosPlatform, IosBindingsParams}; + +pub use mopro_build_common::{ + build_from_env, build_from_str_arch, + AndroidArch, IosArch, + Mode, +}; diff --git a/ffi/wasm/Cargo.toml b/ffi/wasm/Cargo.toml new file mode 100644 index 000000000..84ea51780 --- /dev/null +++ b/ffi/wasm/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "mopro-wasm-backend" +version = "0.1.0" +edition = "2021" +description = "mopro build-pipeline backend: WASM bindings via wasm-pack" +license = "MIT OR Apache-2.0" +repository = "https://github.com/zkmopro/mopro" + +[dependencies] +mopro-build-common = { path = "../common" } +anyhow = "1.0" diff --git a/ffi/wasm/src/lib.rs b/ffi/wasm/src/lib.rs new file mode 100644 index 000000000..1bd7c83cf --- /dev/null +++ b/ffi/wasm/src/lib.rs @@ -0,0 +1,81 @@ +use std::fs; +use std::path::{Path, PathBuf}; +use std::process::Command; + +use mopro_build_common::{ + build_from_env, cleanup_tmp_local, mktemp_local, + PlatformBuilder, WEB_BINDINGS_DIR, +}; +pub use mopro_build_common::{build_from_str_arch as wasm_build_from_str_arch, Mode, WebArch}; + +pub struct WebPlatform; + +pub fn build() { + build_from_env::() +} + +pub fn build_at(project_dir: &Path) { + mopro_build_common::build_from_env_at::(project_dir) +} + +impl PlatformBuilder for WebPlatform { + type Arch = WebArch; + type Params = (); + + fn identifier() -> &'static str { "wasm" } + + fn build( + mode: Mode, + project_dir: &Path, + _target_archs: Vec, + _params: Self::Params, + ) -> anyhow::Result { + if !project_dir.join("Cargo.toml").exists() { + panic!("No Cargo.toml found in {:?}", project_dir); + } + let build_dir_path = project_dir.join("build"); + let work_dir = mktemp_local(&build_dir_path); + let bindings_out = work_dir.join(WEB_BINDINGS_DIR); + fs::create_dir(&bindings_out).expect("Failed to create bindings out directory"); + let bindings_dest = project_dir.join(WEB_BINDINGS_DIR); + + let mode_cmd = match mode { + Mode::Release => "--release", + Mode::Debug => "--dev", + }; + + let mut cmd = Command::new("rustup"); + cmd.args([ + "run", "nightly-2025-02-20", + "wasm-pack", "build", + "--target", "web", + mode_cmd, + "--out-dir", bindings_out.to_str().unwrap(), + "--out-name", "mopro_wasm_lib", + "--no-default-features", + "--features", "wasm", + ]); + cmd.env( + "RUSTFLAGS", + "-C target-feature=+atomics,+bulk-memory -C link-arg=--max-memory=4294967296", + ); + cmd.current_dir(project_dir); + + let status = cmd.status().expect("Failed to run wasm-pack"); + if status.success() { + println!("mopro wasm package build completed successfully."); + } else { + eprintln!("mopro wasm package build failed."); + std::process::exit(1); + } + + if let Ok(info) = fs::metadata(&bindings_dest) { + if !info.is_dir() { panic!("bindings directory exists and is not a directory"); } + fs::remove_dir_all(&bindings_dest).expect("Failed to remove bindings directory"); + } + fs::rename(&bindings_out, &bindings_dest).expect("Failed to move bindings into place"); + cleanup_tmp_local(&build_dir_path); + + Ok(bindings_dest) + } +} diff --git a/provers/circom-adapter/Cargo.toml b/provers/circom-adapter/Cargo.toml new file mode 100644 index 000000000..6ada4d503 --- /dev/null +++ b/provers/circom-adapter/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "circom-prover-adapter" +version = "0.1.0" +edition = "2021" +description = "mopro adapter that wires the circom-prover crate into the mopro-core::Prover trait" +license = "MIT OR Apache-2.0" +repository = "https://github.com/zkmopro/mopro" + +[features] +# Adds uniffi::Record / uniffi::Enum derives to output types. +uniffi = ["dep:uniffi"] + +[dependencies] +mopro-core = { path = "../../core" } +circom-prover = "0.1" +num-bigint = "0.4" + +# serde: needed by wasm-bindgen (serde_wasm_bindgen) and generally useful +# for JSON serialisation of proof results. +serde = { version = "1.0", features = ["derive"] } + +# uniffi: optional — only pulled in when the `uniffi` feature is enabled. +# ffi/backends/uniffi enables this when building iOS/Android bindings. +uniffi = { version = "=0.31.0", optional = true } diff --git a/provers/circom-adapter/src/adapter.rs b/provers/circom-adapter/src/adapter.rs new file mode 100644 index 000000000..b27935fb9 --- /dev/null +++ b/provers/circom-adapter/src/adapter.rs @@ -0,0 +1,219 @@ +use std::path::PathBuf; + +use circom_prover::{ + prover::{ + circom::{CURVE_BLS12_381, CURVE_BN254}, + CircomProof as UpstreamCircomProof, + ProofLib as UpstreamProofLib, + }, + witness::WitnessFn, + CircomProver, +}; +use mopro_core::{MoproError, Prover}; + +// --------------------------------------------------------------------------- +// FFI-ready output types +// +// All fields use String / Vec so every FFI layer can consume them: +// • UniFFI — #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] +// • wasm-bindgen — serialised via serde + serde_wasm_bindgen (no extra +// annotation needed; the ffi/backends/wasm layer handles it) +// • flutter_rust_bridge — FRB codegen supports String/Vec natively +// --------------------------------------------------------------------------- + +#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Record))] +pub struct G1 { + pub x: String, + pub y: String, + pub z: String, +} + +#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Record))] +pub struct G2 { + pub x: Vec, + pub y: Vec, + pub z: Vec, +} + +#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Record))] +pub struct CircomProof { + pub a: G1, + pub b: G2, + pub c: G1, + pub protocol: String, + pub curve: String, +} + +/// Proof bundle returned by [`CircomProverAdapter::prove`]. +/// +/// All fields are String / Vec — safe to pass across any FFI boundary. +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Record))] +pub struct CircomOutput { + pub proof: CircomProof, + pub public_inputs: Vec, +} + +/// Which backend to use for proving / verifying. +/// +/// Defined here (not re-exported from circom-prover) so we can attach +/// FFI derives. +#[derive(Debug, Clone, Copy, Default, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] +pub enum ProofLib { + #[default] + Arkworks, + Rapidsnark, +} + +impl From for UpstreamProofLib { + fn from(lib: ProofLib) -> Self { + match lib { + ProofLib::Arkworks => UpstreamProofLib::Arkworks, + ProofLib::Rapidsnark => UpstreamProofLib::Rapidsnark, + } + } +} + +// --------------------------------------------------------------------------- +// Type conversions: upstream BigUint ↔ our String types +// --------------------------------------------------------------------------- + +impl From for G1 { + fn from(g: circom_prover::prover::circom::G1) -> Self { + G1 { x: g.x.to_string(), y: g.y.to_string(), z: g.z.to_string() } + } +} + +impl From for G2 { + fn from(g: circom_prover::prover::circom::G2) -> Self { + G2 { + x: vec![g.x[0].to_string(), g.x[1].to_string()], + y: vec![g.y[0].to_string(), g.y[1].to_string()], + z: vec![g.z[0].to_string(), g.z[1].to_string()], + } + } +} + +impl From for CircomProof { + fn from(p: circom_prover::prover::circom::Proof) -> Self { + CircomProof { + a: p.a.into(), + b: p.b.into(), + c: p.c.into(), + protocol: p.protocol, + curve: p.curve, + } + } +} + +impl From for circom_prover::prover::circom::G1 { + fn from(g: G1) -> Self { + use num_bigint::BigUint; + use std::str::FromStr; + circom_prover::prover::circom::G1 { + x: BigUint::from_str(&g.x).unwrap(), + y: BigUint::from_str(&g.y).unwrap(), + z: BigUint::from_str(&g.z).unwrap(), + } + } +} + +impl From for circom_prover::prover::circom::G2 { + fn from(g: G2) -> Self { + use num_bigint::BigUint; + use std::str::FromStr; + circom_prover::prover::circom::G2 { + x: [BigUint::from_str(&g.x[0]).unwrap(), BigUint::from_str(&g.x[1]).unwrap()], + y: [BigUint::from_str(&g.y[0]).unwrap(), BigUint::from_str(&g.y[1]).unwrap()], + z: [BigUint::from_str(&g.z[0]).unwrap(), BigUint::from_str(&g.z[1]).unwrap()], + } + } +} + +impl From for circom_prover::prover::circom::Proof { + fn from(p: CircomProof) -> Self { + circom_prover::prover::circom::Proof { + a: p.a.into(), + b: p.b.into(), + c: p.c.into(), + protocol: p.protocol, + curve: p.curve, + } + } +} + +// --------------------------------------------------------------------------- +// Adapter +// --------------------------------------------------------------------------- + +/// Thin adapter that wires the external `circom-prover` crate into +/// [`mopro_core::Prover`]. +/// +/// All circuit-level config (zkey path, backend, witness function) is fixed +/// at construction time; only the JSON witness input varies per call. +/// +/// # FFI compatibility +/// Enable the `uniffi` feature to get `uniffi::Record` / `uniffi::Enum` +/// derives on all output types. For wasm-bindgen, serialise `CircomOutput` +/// via `serde_wasm_bindgen` (the `serde` derives are always present). +/// flutter_rust_bridge handles `String` / `Vec` fields natively. +pub struct CircomProverAdapter { + zkey_path: PathBuf, + proof_lib: ProofLib, + witness_fn: WitnessFn, +} + +impl CircomProverAdapter { + pub fn new( + zkey_path: impl Into, + proof_lib: ProofLib, + witness_fn: WitnessFn, + ) -> Self { + Self { zkey_path: zkey_path.into(), proof_lib, witness_fn } + } +} + +impl Prover for CircomProverAdapter { + /// JSON-encoded witness inputs, e.g. `{"a": "2", "b": "3"}`. + type Input = String; + + /// String-based Groth16 proof + public inputs — FFI-safe. + type Output = CircomOutput; + + fn prove(&self, input: Self::Input) -> Result { + let ret = CircomProver::prove( + self.proof_lib.into(), + self.witness_fn, + input, + self.zkey_path.to_string_lossy().into_owned(), + ) + .map_err(|e| MoproError::ProverError(e.to_string()))?; + + match ret.proof.curve.as_str() { + CURVE_BN254 | CURVE_BLS12_381 => {} + other => { + return Err(MoproError::ProverError(format!("unsupported curve: {other}"))) + } + } + + let public_inputs: Vec = ret.pub_inputs.into(); + Ok(CircomOutput { proof: ret.proof.into(), public_inputs }) + } + + fn verify(&self, output: &Self::Output) -> Result { + let upstream = UpstreamCircomProof { + proof: output.proof.clone().into(), + pub_inputs: output.public_inputs.clone().into(), + }; + CircomProver::verify( + self.proof_lib.into(), + upstream, + self.zkey_path.to_string_lossy().into_owned(), + ) + .map_err(|e| MoproError::VerifierError(e.to_string())) + } +} diff --git a/provers/circom-adapter/src/lib.rs b/provers/circom-adapter/src/lib.rs new file mode 100644 index 000000000..5ab629140 --- /dev/null +++ b/provers/circom-adapter/src/lib.rs @@ -0,0 +1,10 @@ +mod adapter; + +pub use adapter::{CircomOutput, CircomProof, CircomProverAdapter, ProofLib, G1, G2}; + +// WitnessFn is a function pointer type — no FFI derives needed, re-export as-is. +pub use circom_prover::witness::WitnessFn; + +// uniffi::Record / Enum derives require UniFfiTag, which setup_scaffolding! generates. +#[cfg(feature = "uniffi")] +uniffi::setup_scaffolding!(); diff --git a/provers/halo2-adapter/Cargo.toml b/provers/halo2-adapter/Cargo.toml new file mode 100644 index 000000000..ae68aa36f --- /dev/null +++ b/provers/halo2-adapter/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "halo2-prover-adapter" +version = "0.1.0" +edition = "2021" +description = "mopro adapter that wires user-supplied Halo2 circuit functions into the mopro-core::Prover trait" +license = "MIT OR Apache-2.0" +repository = "https://github.com/zkmopro/mopro" + +[features] +# Adds uniffi::Record derive to Halo2Output. +uniffi = ["dep:uniffi"] + +[dependencies] +mopro-core = { path = "../../core" } + +# serde: needed by wasm-bindgen (serde_wasm_bindgen) and JSON serialisation. +serde = { version = "1.0", features = ["derive"] } + +# uniffi: optional — enabled by ffi/backends/uniffi when building iOS/Android bindings. +uniffi = { version = "=0.31.0", optional = true } diff --git a/provers/halo2-adapter/src/adapter.rs b/provers/halo2-adapter/src/adapter.rs new file mode 100644 index 000000000..07ea51b5f --- /dev/null +++ b/provers/halo2-adapter/src/adapter.rs @@ -0,0 +1,132 @@ +use std::collections::HashMap; +use std::error::Error; +use std::path::PathBuf; + +use mopro_core::{MoproError, Prover}; + +// --------------------------------------------------------------------------- +// FFI-ready output type +// +// Fields are Vec — natively handled by every FFI layer: +// • UniFFI — Data (Swift) / ByteArray (Kotlin) via uniffi::Record +// • wasm-bindgen — Uint8Array via serde_wasm_bindgen +// • flutter_rust_bridge — Uint8List natively +// +// Input type HashMap> is also FFI-compatible: +// • UniFFI — [String: [String]] (Swift) / Map> (Kotlin) +// • wasm-bindgen — serialised via serde_wasm_bindgen +// • flutter_rust_bridge — Map> via FRB codegen +// --------------------------------------------------------------------------- + +/// Proof bundle returned by [`Halo2ProverAdapter::prove`]. +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "uniffi", derive(uniffi::Record))] +pub struct Halo2Output { + pub proof: Vec, + pub public_inputs: Vec, +} + +// --------------------------------------------------------------------------- +// Function pointer types +// +// These are Rust-internal — function pointers cannot cross FFI boundaries, +// so Halo2ProverAdapter is always constructed on the Rust side (in cli/ or +// an ffi/backends/* glue module). Only the *output* crosses the FFI boundary. +// --------------------------------------------------------------------------- + +/// Function pointer type for Halo2 proof generation. +/// +/// Arguments: `(srs_path, pk_path, circuit_inputs) → (proof_bytes, public_input_bytes)` +pub type Halo2ProveFn = fn( + &str, + &str, + HashMap>, +) -> Result<(Vec, Vec), Box>; + +/// Function pointer type for Halo2 proof verification. +/// +/// Arguments: `(srs_path, vk_path, proof_bytes, public_input_bytes) → bool` +pub type Halo2VerifyFn = + fn(&str, &str, Vec, Vec) -> Result>; + +// --------------------------------------------------------------------------- +// Adapter +// --------------------------------------------------------------------------- + +/// Thin adapter that wires a user-supplied Halo2 circuit into [`mopro_core::Prover`]. +/// +/// Halo2 has no single universal prover crate — each circuit ships its own +/// `prove` / `verify` functions. This adapter holds those function pointers +/// alongside the key-file paths, keeping the per-call API to inputs-only. +/// +/// # Example +/// +/// ```ignore +/// use halo2_prover_adapter::{Halo2ProverAdapter, Halo2Output}; +/// use std::collections::HashMap; +/// +/// let prover = Halo2ProverAdapter::new( +/// "./test-vectors/halo2/plonk_fibonacci_srs.bin", +/// "./test-vectors/halo2/plonk_fibonacci_pk.bin", +/// "./test-vectors/halo2/plonk_fibonacci_vk.bin", +/// plonk_fibonacci::prove, +/// plonk_fibonacci::verify, +/// ); +/// +/// let mut inputs = HashMap::new(); +/// inputs.insert("out".to_string(), vec!["55".to_string()]); +/// +/// let output: Halo2Output = prover.prove(inputs).unwrap(); +/// assert!(prover.verify(&output).unwrap()); +/// ``` +pub struct Halo2ProverAdapter { + srs_path: PathBuf, + pk_path: PathBuf, + vk_path: PathBuf, + prove_fn: Halo2ProveFn, + verify_fn: Halo2VerifyFn, +} + +impl Halo2ProverAdapter { + pub fn new( + srs_path: impl Into, + pk_path: impl Into, + vk_path: impl Into, + prove_fn: Halo2ProveFn, + verify_fn: Halo2VerifyFn, + ) -> Self { + Self { + srs_path: srs_path.into(), + pk_path: pk_path.into(), + vk_path: vk_path.into(), + prove_fn, + verify_fn, + } + } +} + +impl Prover for Halo2ProverAdapter { + /// Named circuit inputs, e.g. `{"out": ["55"]}`. + type Input = HashMap>; + + /// Raw proof bytes bundled with public inputs — FFI-safe. + type Output = Halo2Output; + + fn prove(&self, input: Self::Input) -> Result { + let srs = self.srs_path.to_string_lossy(); + let pk = self.pk_path.to_string_lossy(); + + let (proof, public_inputs) = (self.prove_fn)(&srs, &pk, input) + .map_err(|e| MoproError::ProverError(e.to_string()))?; + + Ok(Halo2Output { proof, public_inputs }) + } + + fn verify(&self, output: &Self::Output) -> Result { + let srs = self.srs_path.to_string_lossy(); + let vk = self.vk_path.to_string_lossy(); + + (self.verify_fn)(&srs, &vk, output.proof.clone(), output.public_inputs.clone()) + .map_err(|e| MoproError::VerifierError(e.to_string())) + } +} diff --git a/provers/halo2-adapter/src/lib.rs b/provers/halo2-adapter/src/lib.rs new file mode 100644 index 000000000..1bd769691 --- /dev/null +++ b/provers/halo2-adapter/src/lib.rs @@ -0,0 +1,6 @@ +mod adapter; + +pub use adapter::{Halo2Output, Halo2ProveFn, Halo2ProverAdapter, Halo2VerifyFn}; + +#[cfg(feature = "uniffi")] +uniffi::setup_scaffolding!(); diff --git a/provers/noir-adapter/Cargo.toml b/provers/noir-adapter/Cargo.toml new file mode 100644 index 000000000..357d7d19a --- /dev/null +++ b/provers/noir-adapter/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "noir-prover-adapter" +version = "0.1.0" +edition = "2021" +description = "mopro adapter that wires noir-rs into the mopro-core::Prover trait" +license = "MIT OR Apache-2.0" +repository = "https://github.com/zkmopro/mopro" + +[features] +# Enable this feature to pull in the actual noir-rs engine. +# Requires a compatible nightly toolchain (see noir-rs v1.0.0-beta.19 release notes). +barretenberg = ["dep:noir_rs"] +# Needed only if the adapter itself exports uniffi scaffolding (uncommon — usually the +# ffi/backends/uniffi crate handles this). Input/Output types are already FFI-primitive +# (Vec / Vec), so no Record/Enum derives are required. +uniffi = ["dep:uniffi"] + +[dependencies] +mopro-core = { path = "../../core" } +serde_json = "1.0" +uniffi = { version = "=0.31.0", optional = true } + +noir_rs = { package = "noir", git = "https://github.com/zkmopro/noir-rs", features = [ + "barretenberg", +], tag = "v1.0.0-beta.19", optional = true } diff --git a/provers/noir-adapter/src/adapter.rs b/provers/noir-adapter/src/adapter.rs new file mode 100644 index 000000000..58176364f --- /dev/null +++ b/provers/noir-adapter/src/adapter.rs @@ -0,0 +1,173 @@ +use std::path::PathBuf; + +use mopro_core::{MoproError, Prover}; + +/// Thin adapter that wires `noir-rs` (Barretenberg backend) into +/// [`mopro_core::Prover`]. +/// +/// All circuit-level config is fixed at construction; only the ordered +/// witness inputs vary per call. +/// +/// Enable the `barretenberg` Cargo feature to compile this with the +/// actual `noir-rs` engine. Without that feature the struct exists but +/// both `prove` and `verify` return `MoproError::ProverError`. +/// +/// # Hash function selection +/// - `on_chain = false` → Poseidon (better performance, off-chain verification) +/// - `on_chain = true` → Keccak256 (Solidity verifier compatible, on-chain) +#[allow(dead_code)] +pub struct NoirProverAdapter { + circuit_path: PathBuf, + srs_path: Option, + vk: Vec, + on_chain: bool, + low_memory_mode: bool, +} + +impl NoirProverAdapter { + pub fn new( + circuit_path: impl Into, + srs_path: Option>, + vk: Vec, + on_chain: bool, + low_memory_mode: bool, + ) -> Self { + Self { + circuit_path: circuit_path.into(), + srs_path: srs_path.map(Into::into), + vk, + on_chain, + low_memory_mode, + } + } + + /// Derive the verification key from the circuit. + /// Call once before constructing the adapter. + /// + /// Requires the `barretenberg` feature. + pub fn compute_vk( + circuit_path: impl Into, + srs_path: Option>, + on_chain: bool, + low_memory_mode: bool, + ) -> Result, MoproError> { + #[cfg(feature = "barretenberg")] + { + use noir_rs::barretenberg::{ + srs::setup_srs_from_bytecode, + verify::{ + get_ultra_honk_keccak_verification_key, get_ultra_honk_verification_key, + }, + }; + + let path: PathBuf = circuit_path.into(); + let srs_str = srs_path.map(|p| p.into().to_string_lossy().into_owned()); + let bytecode = read_bytecode(&path)?; + + setup_srs_from_bytecode(&bytecode, srs_str.as_deref(), false) + .map_err(|e| MoproError::ProverError(format!("SRS setup failed: {e}")))?; + + if on_chain { + get_ultra_honk_keccak_verification_key(&bytecode, false, low_memory_mode) + } else { + get_ultra_honk_verification_key(&bytecode, low_memory_mode) + } + .map_err(|e| MoproError::ProverError(format!("VK derivation failed: {e}"))) + } + + #[cfg(not(feature = "barretenberg"))] + { + let _ = (circuit_path, srs_path, on_chain, low_memory_mode); + Err(MoproError::ProverError( + "noir-adapter: compile with --features barretenberg to enable".into(), + )) + } + } +} + +impl Prover for NoirProverAdapter { + /// Ordered public witness inputs as decimal strings, e.g. `["3", "5"]`. + type Input = Vec; + + /// Raw proof bytes produced by Barretenberg. + type Output = Vec; + + fn prove(&self, input: Self::Input) -> Result { + #[cfg(feature = "barretenberg")] + { + use noir_rs::barretenberg::{ + prove::{prove_ultra_honk, prove_ultra_honk_keccak}, + srs::setup_srs_from_bytecode, + }; + use noir_rs::witness::from_vec_str_to_witness_map; + + let bytecode = read_bytecode(&self.circuit_path)?; + let srs_str = self + .srs_path + .as_deref() + .map(|p| p.to_string_lossy().into_owned()); + + setup_srs_from_bytecode(&bytecode, srs_str.as_deref(), false) + .map_err(|e| MoproError::ProverError(format!("SRS setup failed: {e}")))?; + + let witness = + from_vec_str_to_witness_map(input.iter().map(|s| s.as_str()).collect()) + .map_err(|e| MoproError::InvalidInput(e.to_string()))?; + + if self.on_chain { + prove_ultra_honk_keccak( + &bytecode, + witness, + self.vk.clone(), + false, + self.low_memory_mode, + ) + } else { + prove_ultra_honk(&bytecode, witness, self.vk.clone(), self.low_memory_mode) + } + .map_err(|e| MoproError::ProverError(e.to_string())) + } + + #[cfg(not(feature = "barretenberg"))] + { + let _ = input; + Err(MoproError::ProverError( + "noir-adapter: compile with --features barretenberg to enable".into(), + )) + } + } + + fn verify(&self, output: &Self::Output) -> Result { + #[cfg(feature = "barretenberg")] + { + use noir_rs::barretenberg::verify::{verify_ultra_honk, verify_ultra_honk_keccak}; + + if self.on_chain { + verify_ultra_honk_keccak(output.clone(), self.vk.clone(), false) + } else { + verify_ultra_honk(output.clone(), self.vk.clone()) + } + .map_err(|e| MoproError::VerifierError(e.to_string())) + } + + #[cfg(not(feature = "barretenberg"))] + { + let _ = output; + Err(MoproError::VerifierError( + "noir-adapter: compile with --features barretenberg to enable".into(), + )) + } + } +} + +#[cfg(feature = "barretenberg")] +fn read_bytecode(circuit_path: &PathBuf) -> Result { + let text = std::fs::read_to_string(circuit_path) + .map_err(|e| MoproError::CircuitNotFound(e.to_string()))?; + let json: serde_json::Value = serde_json::from_str(&text) + .map_err(|e| MoproError::SerializationError(e.to_string()))?; + json["bytecode"] + .as_str() + .map(str::to_owned) + .ok_or_else(|| MoproError::SerializationError("missing `bytecode` field".into())) +} diff --git a/provers/noir-adapter/src/lib.rs b/provers/noir-adapter/src/lib.rs new file mode 100644 index 000000000..ac1e00328 --- /dev/null +++ b/provers/noir-adapter/src/lib.rs @@ -0,0 +1,9 @@ +mod adapter; + +pub use adapter::NoirProverAdapter; + +// Input = Vec — UniFFI: [String]/List; wasm: JsValue via serde; FRB: List +// Output = Vec — UniFFI: Data/ByteArray; wasm: Uint8Array; FRB: Uint8List +// No custom Record/Enum types needed — primitives are FFI-native in all three layers. +#[cfg(feature = "uniffi")] +uniffi::setup_scaffolding!(); diff --git a/scripts/check-boundaries.sh b/scripts/check-boundaries.sh new file mode 100755 index 000000000..1ee3ee4f0 --- /dev/null +++ b/scripts/check-boundaries.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Verify that no ffi/backends/* crate pulls in mopro-core or any prover adapter. +# Run from the workspace root: ./scripts/check-boundaries.sh + +set -euo pipefail + +CARGO=${CARGO:-cargo} +FORBIDDEN="mopro-core|circom-prover-adapter|halo2-prover-adapter|noir-prover-adapter" + +FFI_BACKEND_CRATES=( + mopro-build-common + mopro-uniffi-backend + mopro-wasm-backend + mopro-flutter-backend + mopro-react-native-backend +) + +VIOLATIONS=0 + +for crate in "${FFI_BACKEND_CRATES[@]}"; do + result=$("$CARGO" tree -p "$crate" 2>/dev/null | grep -iE "$FORBIDDEN" || true) + if [ -n "$result" ]; then + echo "VIOLATION $crate → $result" + VIOLATIONS=$((VIOLATIONS + 1)) + else + echo "OK $crate" + fi +done + +echo "" +if [ "$VIOLATIONS" -gt 0 ]; then + echo "FAILED: $VIOLATIONS boundary violation(s). ffi/backends/* must not depend on core or provers." + exit 1 +else + echo "PASSED: all ffi/backends/* crates respect the dependency boundary." +fi diff --git a/test-app/Cargo.toml b/test-app/Cargo.toml new file mode 100644 index 000000000..d8e6b9901 --- /dev/null +++ b/test-app/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "test-app" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["lib", "cdylib", "staticlib"] + +[features] +default = ["uniffi"] +uniffi = ["mopro-ffi/uniffi"] +flutter = ["mopro-ffi/flutter"] +wasm = ["mopro-ffi/wasm"] + +[dependencies] +mopro-ffi = { path = "../mopro-ffi" } + +[target.wasm32-unknown-unknown.dependencies] +mopro-ffi = { path = "../mopro-ffi", features = ["wasm"] } diff --git a/test-app/src/lib.rs b/test-app/src/lib.rs new file mode 100644 index 000000000..2fff98b72 --- /dev/null +++ b/test-app/src/lib.rs @@ -0,0 +1,17 @@ +#[cfg(any(feature = "uniffi", feature = "wasm"))] +mopro_ffi::app!(); + +#[cfg(all(feature = "wasm", target_arch = "wasm32"))] +use mopro_ffi::prelude::wasm_bindgen; + +fn mopro_hello_world() -> String { + "Hello, World!".to_string() +} + +#[cfg_attr( + all(feature = "wasm", target_arch = "wasm32"), + wasm_bindgen(js_name = "moproWasmHelloWorld") +)] +pub fn mopro_wasm_hello_world() -> String { + mopro_hello_world() +} diff --git a/tests/Cargo.toml b/tests/Cargo.toml index fd16e44bc..c33a496d0 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -3,21 +3,8 @@ name = "tests" version = "0.1.0" edition = "2021" -[lib] -crate-type = ["lib", "cdylib", "staticlib"] - -[features] -default = ["uniffi"] -uniffi = ["mopro-ffi/uniffi"] -flutter = ["mopro-ffi/flutter"] -wasm = ["mopro-ffi/wasm"] - -[dependencies] -mopro-ffi = { path = "../mopro-ffi" } -thiserror = "2.0.12" - -[target.wasm32-unknown-unknown.dependencies] -mopro-ffi = { path = "../mopro-ffi", features = ["wasm"] } - -[target.wasm32-unknown-unknown.dev-dependencies] -mopro-ffi = { path = "../mopro-ffi", features = ["wasm"] } +[build-dependencies] +mopro-wasm-backend = { path = "../ffi/wasm" } +mopro-uniffi-backend = { path = "../ffi/uniffi" } +mopro-flutter-backend = { path = "../ffi/flutter" } +mopro-react-native-backend = { path = "../ffi/react-native" } diff --git a/tests/build.rs b/tests/build.rs new file mode 100644 index 000000000..33f810d35 --- /dev/null +++ b/tests/build.rs @@ -0,0 +1,32 @@ +// Build-pipeline driver for the mopro test project. +// +// Each backend only runs if the corresponding arch env var is set. +// The library being compiled lives in test-app/ (which carries the mopro-ffi +// dependency); this crate only orchestrates the build pipeline. +// +// iOS: IOS_ARCHS=aarch64-apple-ios,aarch64-apple-ios-sim cargo build +// Android: ANDROID_ARCHS=aarch64-linux-android cargo build +// Wasm: WEB_ARCHS=wasm32-unknown-unknown cargo build +// Flutter: FLUTTER_ARCHS=aarch64-apple-ios,aarch64-linux-android cargo build +// React Native: REACT_NATIVE_ARCHS=aarch64-apple-ios cargo build + +fn main() { + let manifest_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let app_dir = manifest_dir.parent().unwrap().join("test-app"); + + if std::env::var("IOS_ARCHS").is_ok() { + mopro_uniffi_backend::ios::build_at(&app_dir); + } + if std::env::var("ANDROID_ARCHS").is_ok() { + mopro_uniffi_backend::android::build_at(&app_dir); + } + if std::env::var("WEB_ARCHS").is_ok() { + mopro_wasm_backend::build_at(&app_dir); + } + if std::env::var("FLUTTER_ARCHS").is_ok() { + mopro_flutter_backend::build_at(&app_dir); + } + if std::env::var("REACT_NATIVE_ARCHS").is_ok() { + mopro_react_native_backend::build_at(&app_dir); + } +} diff --git a/tests/src/bin/android.rs b/tests/src/bin/android.rs deleted file mode 100644 index 72ad27442..000000000 --- a/tests/src/bin/android.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - mopro_ffi::app_config::android::build(); -} diff --git a/tests/src/bin/flutter.rs b/tests/src/bin/flutter.rs deleted file mode 100644 index 6eff5feb5..000000000 --- a/tests/src/bin/flutter.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - mopro_ffi::app_config::flutter::build(); -} diff --git a/tests/src/bin/ios.rs b/tests/src/bin/ios.rs deleted file mode 100644 index 4a504e903..000000000 --- a/tests/src/bin/ios.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - mopro_ffi::app_config::ios::build(); -} diff --git a/tests/src/bin/react_native.rs b/tests/src/bin/react_native.rs deleted file mode 100644 index faf0c8358..000000000 --- a/tests/src/bin/react_native.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - mopro_ffi::app_config::react_native::build(); -} diff --git a/tests/src/bin/web.rs b/tests/src/bin/web.rs deleted file mode 100644 index 87ad379f1..000000000 --- a/tests/src/bin/web.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - mopro_ffi::app_config::web::build(); -} diff --git a/tests/src/lib.rs b/tests/src/lib.rs index da80a8596..0ff898121 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -1,32 +1 @@ -#[cfg(any(feature = "uniffi", feature = "wasm"))] -mopro_ffi::app!(); - -#[cfg(all(feature = "wasm", target_arch = "wasm32"))] -use mopro_ffi::prelude::wasm_bindgen; - -fn mopro_hello_world() -> String { - "Hello, World!".to_string() -} - -// #[cfg_attr(feature = "uniffi", uniffi::export)] -// fn mopro_uniffi_hello_world() -> String { -// mopro_hello_world() -// } - -// #[cfg(feature = "flutter")] -// pub fn mopro_flutter_hello_world() -> String { -// mopro_hello_world() -// } - -// #[cfg_attr(feature = "uniffi", uniffi::export)] -// pub fn mopro_react_native_hello_world() -> String { -// mopro_hello_world() -// } - -#[cfg_attr( - all(feature = "wasm", target_arch = "wasm32"), - wasm_bindgen(js_name = "moproWasmHelloWorld") -)] -pub fn mopro_wasm_hello_world() -> String { - mopro_hello_world() -} +// build-driver crate — no library code here; see test-app/ for the actual library.