diff --git a/docs/docs/intro.md b/docs/docs/intro.md index e7db2f3e..837f149b 100644 --- a/docs/docs/intro.md +++ b/docs/docs/intro.md @@ -12,7 +12,7 @@ How? Mopro connects different adapters with different platforms. You can think o Note that above is a work in progress, and the dashed lines indicate things that are still experimental and/or in an an early stage. -If you just want to get started using mopro, see [getting started](/docs/getting-started). +If you just want to get started using mopro, see [getting started](getting-started/rust-setup). ## Overview diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 64f2087d..f9034d6b 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -25,7 +25,7 @@ const config: Config = { editUrl: 'https://github.com/zkmopro/mopro/tree/main/docs', includeCurrentVersion: true, - lastVersion: '0.0.1', + lastVersion: '0.1.0', }, theme: { customCss: './src/css/custom.css', diff --git a/docs/versioned_docs/version-0.0.1/getting-started.md b/docs/versioned_docs/version-0.0.1/getting-started.md index 8e8e216d..e3967b38 100644 --- a/docs/versioned_docs/version-0.0.1/getting-started.md +++ b/docs/versioned_docs/version-0.0.1/getting-started.md @@ -4,13 +4,13 @@ sidebar_position: 3 # Getting Started -We recommend you use [mopro-cli](/docs/mopro-cli) to create and maintain your application. Here's how you can get started with your example app in a few minutes. +We recommend you use [mopro-cli](mopro-cli) to create and maintain your application. Here's how you can get started with your example app in a few minutes. You can also watch this short (~5m) [tutorial](https://www.loom.com/share/6ff382b0497c47aea9d0ef8b6e790dd8). ## Install dependencies -First, make sure you've installed the [prerequisites](/docs/prerequisites). +First, make sure you've installed the [prerequisites](prerequisites). Then, run the following commands: @@ -121,5 +121,5 @@ Depending on what platforms you are targetting, you can run the following comman Use `^R` (`control`+`R`) to execute a simulator. -> See [mopro-cli](/docs/mopro-cli) for more details on usage. -> Edit [mopro configuration](/docs/circom/configuration) to build for device or build for other circuits. +> See [mopro-cli](mopro-cli) for more details on usage. +> Edit [mopro configuration](circom/configuration) to build for device or build for other circuits. diff --git a/docs/versioned_docs/version-0.0.1/intro.md b/docs/versioned_docs/version-0.0.1/intro.md index 784de4d2..5b6c0517 100644 --- a/docs/versioned_docs/version-0.0.1/intro.md +++ b/docs/versioned_docs/version-0.0.1/intro.md @@ -12,7 +12,7 @@ How? Mopro connects different adapters with different platforms. You can think o Note that above is a work in progress, and the dashed lines indicate things that are still experimental and/or in an an early stage. -If you just want to get started using mopro, see [getting started](/docs/getting-started). +If you just want to get started using mopro, see [getting started](getting-started). ## Overview diff --git a/docs/versioned_docs/version-0.1.0/FAQ.md b/docs/versioned_docs/version-0.1.0/FAQ.md new file mode 100644 index 00000000..3f1230ba --- /dev/null +++ b/docs/versioned_docs/version-0.1.0/FAQ.md @@ -0,0 +1,40 @@ +--- +sidebar_position: 7 +--- + +# FAQ + +## What are the design goals of Mopro? + +1. Modularity +2. Developer-friendly +3. Performance +4. Multi-platform + +See one of the recent [talks](/docs/community) for more details. + +## What proof systems does Mopro support? + +Currently Circom/Groth16, but due to its modular architecture it is easy to add support for new proof systems. + +There's experimental support for Kimchi, a Plonkish proof system, that was done during a hackathon in this [PR](https://github.com/zkmopro/mopro/pull/34). + +There's a grantee working on adding Halo2 support. Please see the [Telegram group](https://t.me/zkmopro) for more information. + +We welcome people to contribute support for [more proof systems](https://github.com/zkmopro/mopro/issues/15). + +## What platforms does Mopro support? + +Mopro is multi-platform and aims to support as many platforms as possible. iOS, Android and Desktop (through Rust/CLI) are the main platforms supported. + +There's also very experimental React Native support [here](https://github.com/anon-aadhaar/anon-aadhaar-react-native/commit/d6443316200cd3e1f17ad2679458cc6e6e9fe1f2). We aim to make this easier to consume. + +We welcome people to contribute support for [more platforms](https://github.com/zkmopro/mopro/issues/16). + +## Is Mopro just for verifying proofs on mobile? + +Mopro is for both proving and verifying ZKPs on mobile. + +## Does Mopro run natively on a phone? + +Yes. Witness and proof generation happens natively in app. \ No newline at end of file diff --git a/docs/versioned_docs/version-0.1.0/adapters/circom.md b/docs/versioned_docs/version-0.1.0/adapters/circom.md new file mode 100644 index 00000000..1d0607b8 --- /dev/null +++ b/docs/versioned_docs/version-0.1.0/adapters/circom.md @@ -0,0 +1,176 @@ +# Circom Adapter + +Mopro supports the integration of Circom circuits. For this, you need to have pre-built `zkey` and `wasm` files for your circuits. You can find more information on how to generate these files in the [Circom documentation](https://docs.circom.io). + +## Samples + +Explore how the Circom adapter is implemented by checking out this sample project [mopro-app](https://github.com/vimwitch/mopro-app) or the [test-e2e](https://github.com/zkmopro/mopro/tree/main/test-e2e) where we maintain (and test) each adapter. + +## Setup the rust project + +You can follow the instructions in the [Rust Setup](/getting-started/rust-setup.md) guide to create a new Rust project that builds this library with Circom proofs. + +In your `Cargo.toml` file, ensure the `circom` feature is activated for `mopro-ffi`: + +```toml +[features] +default = ["mopro-ffi/circom"] +``` + +## Witness Generation Functions + +In order for the Mopro to be able to generate proofs for your chosen circom circuits, you need to provide a witness generation function for each of the circuits you plan to use to generate proofs for. This function handles the witness generation for your circuit. You can read more about witnesses for circom circuits [here](https://docs.circom.io/background/background/#witness). + +The function signature should be: + +```rust +pub type WtnsFn = fn(HashMap>) -> Vec; +``` + +## Implementing the Witness Function + +For simplicity, you can use the `witness!` macro provided by the `rust-witness` crate. This macro generates a witness function for you given the circuit name. You can read more about the `witness!` macro [here](https://github.com/vimwitch/rust-witness). + +#### Adding the `rust-witness` Crate Dependency + +To use it, you must first add the `rust-witness` crate to your `Cargo.toml` regular and build dependencies: + +```toml +[dependencies] +# ... +rust-witness = { git = "https://github.com/vimwitch/rust-witness.git" } + +[build-dependencies] +# ... +rust-witness = { git = "https://github.com/vimwitch/rust-witness.git" } +``` + +#### Configuring the path to the `.wasm` circuit files in the `build.rs` + +Then you need to add to the `build.rs` the call to `rust_witness::transpile::transpile_wasm` macro and pass it the path to the folder containing the `.wasm` files for the circom circuits. The path can be absolute or a relative to the location of the `build.rs` file. Note that the `.wasm` files can be recursively in subfolders of the specified folder, as in the example below. + +For example, for the following project structure: + +```text +your-rust-project +├── build.rs +... +test-vectors +├── circom +│ ├── multiplier +│ │ ├── multiplier2.wasm +│ │ └── multiplier3.wasm +│ └── keccak256_256_test.wasm +... +``` + +You will need to add the following to the `build.rs` file: + +```rust +fn main() { + // ... + rust_witness::transpile::transpile_wasm("../test-vectors/circom".to_string()); + // ... +} +``` + +#### Automatically Generating Witness Functions + +Then you can automatically generate the witness functions for all the circuits in the specified folder. + +To do so, in the `lib.rs` file, you can add the following: + +```rust +rust_witness::witness!(multiplier2); +rust_witness::witness!(multiplier3); +rust_witness::witness!(keccak256256test); +``` + +This will generate the witness function for the specified circuit following [the naming convention here](https://github.com/vimwitch/rust-witness?tab=readme-ov-file#rust-witness). + +## Setting the Circom Circuits + +To set Circom circuits you want to use on other platforms, you need to use the `set_circom_circuits!` macro provided by the `mopro-ffi` crate. This macro should be called in the `lib.rs` file of your project, after the `mopro_ffi::app()` macro call. You should pass it a list of tuples (pairs), where the first element is the name of the `zkey` file and the second element is the witness generation function. + +For example: + +```rust +mopro_ffi::set_circom_circuits! { + ("multiplier2_final.zkey", multiplier2_witness), + ("multiplier3_final.zkey", multiplier3_witness), + ("keccak256_256_test_final.zkey", keccak256256test_witness), +} +``` + +Under the hood, the `set_circom_circuits!` macro will generate a `get_circom_wtns_fn` function that will be used to get the witness generation function for a given circuit `zkey` file. + +### Manual Configuration + +For advanced users, you can manually define the `get_circom_wtns_fn` function in the `lib.rs` file: + +```rust +fn get_circom_wtns_fn(circuit: &str) -> Result { + match circuit { + "your_circuit.zkey" => Ok(your_circuit_wtns_gen_fn), + _ => Err(mopro_ffi::MoproError::CircomError(format!("Unknown ZKEY: {}", circuit).to_string())) + } +} +``` + +This might be useful if you want to have more control over the proving functions for each circuit. + +## Using the Library + +After you have specified the circuits you want to use, you can follow the usual steps to build the library and use it in your project. + +### iOS API + +The Circom adapter exposes the following functions to be used in the iOS project: + +```swift +// Generate a proof for a given circuit zkey, as well as the circuit inputs +// Make sure that the name of the zkey file matches the one you set in the `set_circom_circuits!` macro +generateCircomProof(zkeyPath: zkeyPath, circuitInputs: inputs) -> GenerateProofResult + +// Verify a proof for a given circuit zkey +// This works for arbitrary circuits, as long as the zkey file is valid +verifyCircomProof( + zkeyPath: zkeyPath, proof: generateProofResult.proof, publicInput: generateProofResult.inputs) -> Bool + +// Convert a Circom proof to an Ethereum compatible proof +toEthereumProof(proof: generateProofResult.proof) -> ProofCalldata + +// Convert a Circom public input to an Ethereum compatible public input +toEthereumInputs(inputs: generateProofResult.inputs) -> [String] +``` + +As well as the following types: + +```swift +public struct G1 { + public var x: String + public var y: String +} + +public struct G2 { + public var x: [String] + public var y: [String] +} + +public struct ProofCalldata { + public var a: G1 + public var b: G2 + public var c: G1 +} + +public struct GenerateProofResult { + public var proof: Data + public var inputs: Data +} +``` + +### Android API + +The Circom adapter exposes the equivalent functions and types to be used in the Android project. + + diff --git a/docs/versioned_docs/version-0.1.0/adapters/halo2.md b/docs/versioned_docs/version-0.1.0/adapters/halo2.md new file mode 100644 index 00000000..00568642 --- /dev/null +++ b/docs/versioned_docs/version-0.1.0/adapters/halo2.md @@ -0,0 +1,129 @@ +# Halo2 Adapter + +Mopro supports the use of Halo2 circuits, allowing for both the Halo2 library from Zcash and the PSE's Halo2 fork. To effectively work with Halo2 circuits in Mopro, you will need to understand how to generate proving and verifying keys as well as how Halo2 circuits work, and have some experience in Rust. For more details, please refer to the [Halo2 documentation](https://zcash.github.io/halo2/). + +## Samples + +Explore how the Halo2 adapter is implemented by checking out this [Sample Mopro Halo2-Adapter Project](https://github.com/zkmopro/halo2-app) or the [test-e2e](https://github.com/zkmopro/mopro/tree/main/test-e2e) where we maintain (and test) each adapter. + +## Setting Up the Rust Project + +You can start by following the general instructions in the [Rust Setup Guide](/getting-started/rust-setup.md) to create a new Rust project for building libraries with Circom proofs. However, you will need to perform these specific adjustments for Halo2: + +In your `Cargo.toml` file, ensure the `halo2` feature is activated for `mopro-ffi`: + +```toml +[features] +default = ["mopro-ffi/halo2"] +``` + +Then, remove the `rust-witness` dependency from `[dependencies]` and `[build-dependencies]` as it is unnecessary for Halo2 circuits. +Likewise, remove the `rust_witness::transpile::transpile_wasm!` macro call from the `build.rs` file and any `rust_witness::witness!` and `mopro_ffi::set_circom_circuits!` calls from the `lib.rs`. + +## Implementing the Halo2 Circuit + +The design of the Halo2 adapter minimizes restrictions, allowing flexibility in how you implement your circuits while following a few conventions to ensure compatibility with Mopro. + +### Proving Function + +When generating a proof for a Halo2 circuit, the Mopro will do a call to the proving function that you provide. This function should have the following signature: + +```rust +pub type Halo2ProveFn = fn(&str, &str, HashMap>) -> Result>; +``` + +The first two arguments are the path to the `srs` and `proving` key files, and the third argument is a map of the inputs for the circuit. + +It is then your responsibility to load the keys from the path and set up the circuit, as well as to deserialize the inputs and generate the proof. You can use any serialization method you want, as long as you can serialize and deserialize the inputs on the target platform. + +The result of the function should be a `GenerateProofResult` struct, which contains the proof and the public inputs in the form of `Vec`. It is up to you to serialize the proof and the public inputs in a way that you can deserialize. + +You can find an example of a proving function in the [Halo2 Fibonacci circuit sample](https://github.com/ElusAegis/halo2-fibonacci-sample/blob/main/src/lib.rs). + +### Verifying Function + +When verifying a proof for a Halo2 circuit, the Mopro will do a call to the verifying function that you provide. This function should have the following signature: + +```rust +pub type Halo2VerifyFn = fn(&str, &str, Vec, Vec) -> Result>; +``` + +The first two arguments are the path to the `srs` and `verifying` key files, and the last two arguments are the serialised proof and the public inputs. + +It is then your responsibility to load the keys from the path and set up the circuit, as well as to deserialize the proof and the public inputs and verify the proof. +Make sure that your deserialization method is compatible with the serialization method you used in the proving function. + +The result of the function should be a `bool`, which indicates whether the proof is valid or not. + +You can find an example of a verifying function in the [Halo2 Fibonacci sample project](https://github.com/ElusAegis/halo2-fibonacci-sample/blob/main/src/lib.rs). + +### Setting the Halo2 Circuits + +To set the Halo2 circuits in your project, you need to use the `set_halo2_circuits!` macro. This macro should be called in the `lib.rs` file of your project, after the `mopro_ffi::app()` macro, and it should contain a list of tuples, where each tuple contains the name to the proving key file, the proving function, the name to the verifying key file, and the verifying function. + +For example: + +```rust +mopro_ffi::set_halo2_circuits! { + ("fibonacci_pk.bin", halo2_fibonacci::prove, "fibonacci_vk.bin", halo2_fibonacci::verify), +} +``` + +Under the hood, the `set_halo2_circuits!` macro will generate two functions called `get_halo2_proving_circuit` and `get_halo2_verifying_circuit` that will be used by the Mopro to select and call the proving and verifying functions respectively for each circuit based on the provided proving or verifying key files. + +### Manual Configuration + +You can optionally set only the proving or verifying function for a circuit by manually setting the `get_halo2_proving_circuit` and `get_halo2_verifying_circuit` functions in the `lib.rs` file. However, this is exclusive with the `set_halo2_circuits!` macro, so you can't use both in the same project. Also, you must implement both functions, even if you only want to use one of them. + +For example: + +```rust +fn get_halo2_proving_circuit(circuit: &str) -> Result { + match circuit { + "fibonacci_pk.bin" => Ok(halo2_fibonacci::prove), + _ => Err(MoproError::CircuitNotFound), + } +} + +fn get_halo2_verifying_circuit(circuit: &str) -> Result { + match circuit { + "fibonacci_vk.bin" => Ok(halo2_fibonacci::verify), + _ => Err(MoproError::CircuitNotFound), + } +} +``` + +This might be useful if you want to have more control over the proving and verifying functions for each circuit or if you want to only add the proving or verifying function for a circuit. + +## Using the Library + +After you have specified the circuits you want to use, you can follow the usual steps to build the library and use it in your project. + +### iOS API + +The Halo2 adapter exposes the following functions to be used in the iOS project: + +```swift +// Generate a proof for a Halo2 circuit given the srs and proving key files, as well as the circuit inputs +// Make sure that the key was set in the Rust library +generateHalo2Proof(srsPath: srsPath, pkPath: pkPath, circuitInputs: inputs) -> GenerateProofResult + +// Verify a proof for a Halo2 circuit given the srs and verifying key files, as well as the proof and public inputs +// Make sure that the key was set in the Rust library +verifyHalo2Proof(srsPath: srsPath, vkPath: vkPath, proof: generateProofResult.proof, publicInput: generateProofResult.inputs) -> Bool +``` + +As well as the following types: + +```swift +public struct GenerateProofResult { + public var proof: Data + public var inputs: Data +} +``` + +### Android API + +The Halo2 adapter exposes the equivalent functions and types to be used in the Android project. + + diff --git a/docs/versioned_docs/version-0.1.0/adapters/overview.md b/docs/versioned_docs/version-0.1.0/adapters/overview.md new file mode 100644 index 00000000..089fe5f6 --- /dev/null +++ b/docs/versioned_docs/version-0.1.0/adapters/overview.md @@ -0,0 +1,65 @@ +# Adapters + +The objective of Mopro is to support a wide range of circuits and platforms. To achieve this, Mopro provides adapters that allow you to build proofs for your circuits and do other cryptographic operations on different platforms. The adapters are designed to be modular and easy to use. + +## Overview + +Mopro's modular architecture allows you to combine different adapters in your project, such as mixing Halo2 and Circom circuits in the same project. The adapters are designed to be easy to use and to provide a consistent interface across different platforms. + +## Enabling Adapters + +To activate a specific adapter, you must enable it in your Rust project's `Cargo.toml` file using the `mopro-ffi` feature mechanism. Each adapter has its own feature name, along with a list of dependencies that need to be included in your project. + +For example, to enable the Circom adapter, ensure that the `mopro-ffi/circom` feature is enabled in your `Cargo.toml` file: + +```toml +[features] +default = ["mopro-ffi/circom"] +``` + +To mix different adapters, you can enable multiple features: + +```toml +[features] +default = ["mopro-ffi/circom", "mopro-ffi/halo2"] +``` + +For adapter specific dependencies, please refer to each adapter's documentation. + +## Supported Adapters + +- [Circom](/adapters/circom.md) - `["mopro-ffi/circom"]` +- [Halo2](/adapters/halo2.md) - `["mopro-ffi/halo2"]` + +## Using Adapters + +Each adapter provides its functionality to set it up for the project as well as exports its own functions to be used on the target platform. Detailed information can be found on each adapter’s documentation page. + +## Using Multiple Adapters + +The adapters are independent of each other, so they can be used simultaneously in the same project. For example, you can use both Circom and Halo adapters in the same project: + +```rust +mopro_ffi::app!(); + +// Circom adapter +rust_witness::witness!(multiplier2); + +mopro_ffi::set_circom_circuits! { + ("multiplier2_final.zkey", multiplier2_witness), +} + +// Halo2 adapter +mopro_ffi::set_halo2_circuits! { + ("fibonacci_pk.bin", halo2_fibonacci::prove, "fibonacci_vk.bin", halo2_fibonacci::verify), +} +``` + +In the iOS project, you can utilize both adapters: + +```swift +let generateProofResult = try generateCircomProof(zkeyPath: zkeyPath, circuitInputs: inputs) + +let generateProofResult = try generateHalo2Proof(srsPath: srsPath, pkPath: pkPath, circuitInputs: inputs) +``` + diff --git a/docs/versioned_docs/version-0.1.0/community.md b/docs/versioned_docs/version-0.1.0/community.md new file mode 100644 index 00000000..bc66a14b --- /dev/null +++ b/docs/versioned_docs/version-0.1.0/community.md @@ -0,0 +1,27 @@ +--- +sidebar_position: 6 +--- + +# Community and Talks + +Join the Telegram group [here](https://t.me/zkmopro). This is the main place where coordination around development takes places. + +## Talks + +- Talk by @vivianjeng at [IC3 Camp 2024](https://www.initc3.org/events/2024-06-10-ic3-blockchain-camp-2024) (New York City, June 2024): [Slides](https://docs.google.com/presentation/d/1UoHA2C-SB7qmmIcKBA8if5pCtzU4AbdnH0EX59TQcoE/edit?usp=sharing) (no video) +- Talk by @vivianjeng at [Signature Singularity Residency](https://sigsing.com/) (Osaka, May 2024): [Video](https://www.youtube.com/live/rT7zLiOYX8s?si=Hy3cxL1Kg8xxX7Ti&t=5260), [Slides](https://docs.google.com/presentation/d/1r4hqV7jPTYf2WjtAzah-w9r5LKbf_-Se9t0HPWCLAs4/edit?usp=sharing) +- Talk by @oskarth at [ZK Summit 11](https://www.zksummit.com/) (Athens, April 2024): [Video](https://www.youtube.com/watch?v=06CLMAuEXE4), [Slides](https://hackmd.io/TNZCDbu-T9e6lx8_Wft5ww?view). +- Workshop by @oskarth and @vivianjeng at ZK Day (Taipei, March 2024): [Video](https://www.youtube.com/watch?v=K-h7blwnXbQ). +- Talk by @oskarth at [ETHTaipei](https://ethtaipei.org/) (Taipei, March 2024): [Slides](https://hackmd.io/@oskarth/S1yGjF8C6#), [Video](https://www.youtube.com/live/JB6zP9enkbc?si=04xz9XRLkChNiupw&t=14708) +- Talk by @oskarth at [ProgCrypto/Devconnect](https://progcrypto.org/) (Istanbul, November 2023): [Slides](https://docs.google.com/presentation/d/1afIEgm8oYRvteWxUd04CcMOxChAiHaD55d5AKd0RkvY/edit#slide=id.g284ac8f47d5_2_24) (no video) + + +## Contribute + +Contributions of all kinds welcome! Please see [open GH issues](https://github.com/zkmopro/mopro/issues). Also feel free to join the Telegram chat. + +You can also check out [good first issues](https://github.com/zkmopro/mopro/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). + +## Acknowledgements + +This work was initially sponsored by a joint grant from [PSE](https://pse.dev/) and [0xPARC](https://0xparc.org/). It is currently incubated by PSE. \ No newline at end of file diff --git a/docs/versioned_docs/version-0.1.0/getting-started/android-setup.md b/docs/versioned_docs/version-0.1.0/getting-started/android-setup.md new file mode 100644 index 00000000..a8261696 --- /dev/null +++ b/docs/versioned_docs/version-0.1.0/getting-started/android-setup.md @@ -0,0 +1,241 @@ +# Android Setup + +After you've completed the [Rust setup](docs/getting-started/rust-setup.md) you should be able to run `cargo run --bin android`. This will create a new folder called `MoproAndroidBindings`. It should look like the structure + +```sh +MoproAndroidBindings +├── jniLibs +│ ├── arm64-v8a +│ │ └── libuniffi_mopro.so +│ ├── armeabi-v7a +│ │ └── libuniffi_mopro.so +│ ├── x86 +│ │ └── libuniffi_mopro.so +│ └── x86_64 +│ └── libuniffi_mopro.so +└── uniffi + └── mopro + └── mopro.kt +``` + +First we will create an android app through Android Studio. If you already have an app project, you can skip this step. We'll do **File -> New -> New Project** and create an Empty Activity. + +![create an android app project](/img/android-example-1.png) + +Your android project should be opened now. + +:::info +Please make sure you choose the **Android** view like this. +![android directory view](/img/android-example-5.png) +::: + +Then add jna to `app/build.gradle.kts` + +```kts +dependencies { + ... + implementation("net.java.dev.jna:jna:5.13.0@aar") + ... +} +``` + +![add jna dependency](/img/android-example-2.png) + +Sync gradle with **File -> Sync Project with Gradle Files**, or press + +![android sync gradle](/img/android-example-4.png) + +Open Finder and drag folders: + +1. Move the `MoproAndroidBindings/jniLibs/` folder into `app/src/main/jniLibs/`. +2. Move the `MoproAndroidBindings/uniffi/mopro/mopro.kts` file into `app/src/main/java/uniffi/mopro/mopro.kt` + +![android bindings](/img/android-bindings.png) + +Create an asset folder: **File -> New -> Folder -> Assets Folder**.
+Paste the zkey in the assets folder. + +![android paste zkey](/img/android-example-3.png) + +## Proving from the app + +In your project, there should be a file named `MainActivity.kt` + +> It should be under `app/src/main/java/com/example/YOUR_APP/MainActivity.kt` + +Import the following functions: + +```kotlin +import android.content.Context +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.ui.unit.dp +import androidx.compose.material3.Button +import kotlinx.coroutines.launch +import uniffi.mopro.generateCircomProof +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +``` + +This will make the proving functions `generateCircomProof` available in this module and also help to load zkey. + +In the `MainActivity.kt`, make your `setContent` function look like this: + +```kotlin + setContent { + // A surface container using the 'background' color from the theme + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + MainScreen(this) + } + } +``` + +Add a private function to load zkey. It is used to copy a file from the app's assets directory to the app's internal storage so that we can read the path of the zkey file. + + + +```kotlin +private fun copyAssetToInternalStorage(context: Context, assetFileName: String): String? { + val file = File(context.filesDir, assetFileName) + return try { + context.assets.open(assetFileName).use { inputStream -> + FileOutputStream(file).use { outputStream -> + val buffer = ByteArray(1024) + var length: Int + while (inputStream.read(buffer).also { length = it } > 0) { + outputStream.write(buffer, 0, length) + } + outputStream.flush() + } + } + file.absolutePath + } catch (e: IOException) { + e.printStackTrace() + null + } +} +``` + +At the bottom of this file we'll create a view with a function to generate a proof. In this example we're going to prove a simple circuit that accepts two inputs named `a` and `b` and generates an output `c`. + +```kotlin +@Composable +fun MainScreen(context: Context) { + val coroutineScope = rememberCoroutineScope() + + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp) + ) { + Button(onClick = { + coroutineScope.launch { + val assetFilePath = copyAssetToInternalStorage(context, "multiplier2_final.zkey") + assetFilePath?.let { path -> + val inputs = mutableMapOf>() + inputs["a"] = listOf("3") + inputs["b"] = listOf("5") + val res = generateCircomProof(path, inputs) + println(res) + } + } + }) { + Text(text = "Generate Proof") + } + } +} +``` + +
+ Full `MainActivity.kt` (simplified) + +```kotlin +package com.example.moproandroidapp // Your application ID + +import android.content.Context +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import kotlinx.coroutines.launch +import uniffi.mopro.generateCircomProof + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + // A surface container using the 'background' color from the theme + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { MainScreen(this) } + } + } +} + +@Composable +fun MainScreen(context: Context) { + val coroutineScope = rememberCoroutineScope() + + Column(modifier = Modifier.fillMaxSize().padding(16.dp)) { + Button( + onClick = { + coroutineScope.launch { + val assetFilePath = + copyAssetToInternalStorage(context, "multiplier2_final.zkey") + assetFilePath?.let { path -> + val inputs = mutableMapOf>() + inputs["a"] = listOf("3") + inputs["b"] = listOf("5") + val res = generateCircomProof(path, inputs) + println(res) + } + } + } + ) { Text(text = "Generate Proof") } + } +} + +private fun copyAssetToInternalStorage(context: Context, assetFileName: String): String? { + val file = File(context.filesDir, assetFileName) + return try { + context.assets.open(assetFileName).use { inputStream -> + FileOutputStream(file).use { outputStream -> + val buffer = ByteArray(1024) + var length: Int + while (inputStream.read(buffer).also { length = it } > 0) { + outputStream.write(buffer, 0, length) + } + outputStream.flush() + } + } + file.absolutePath + } catch (e: IOException) { + e.printStackTrace() + null + } +} + +``` + +
+ +You should now be able to run the Android app (`^`+`R` or `ctrl`+`R`) on the simulator or a device and build a proof. The app should log the proof. diff --git a/docs/versioned_docs/version-0.1.0/getting-started/ios-setup.md b/docs/versioned_docs/version-0.1.0/getting-started/ios-setup.md new file mode 100644 index 00000000..627d753f --- /dev/null +++ b/docs/versioned_docs/version-0.1.0/getting-started/ios-setup.md @@ -0,0 +1,85 @@ + +# iOS Setup + +Once you've completed the [Rust setup](docs/getting-started/rust-setup.md) you should be able to run `cargo run --bin ios`. This will create a new folder called `MoproiOSBindings`. Inside this folder there should be a file named `mopro.swift` and a folder named `MoproBindings.xcframework`. + +First let's make a new iOS app Xcode project. If you already have an app project you can skip this step. We'll do File -> New -> Project and create a iOS App. Make sure the language is Swift. We suggest putting this iOS project inside the rust project folder created above. + +![create an ios app project](/img/ios-example-1.png) + +Your Xcode project should be open now. Open Finder and drag the `MoproiOSBindings` folder into the project folder structure. + +![add mopro ios bindings to project](/img/ios-example-2.png) + +Next drag in any zkeys you plan to prove with. Go to the project "Build Phases" and add each zkey to the "Copy Bundle Resources" step. + +![copy zkeys as bundle resources](/img/ios-example-3.png) + +Now you're ready to write the proving code in your app! + +## Proving from the app + +In your project there should be a file named `ContentView`. At the top of this file add the following: + +```swift +import moproFFI +``` + +This will make the proving functions `generateCircomProof` and `verifyCircomProof` available in this module. + +In the `ContentView` itself add a private variable and a button like this: +```swift +struct ContentView: View { + private let zkeyPath = Bundle.main.path(forResource: "multiplier2_final", ofType: "zkey")! + + var body: some View { + VStack { + Button("Prove", action: runProveAction) + } + .padding() + } +} +``` + +We use the `Bundle` api to retrieve the full path to our zkey. Change `multiplier2_final` to the name of your zkey. + +At the bottom of this file we'll add an extension with a function to generate a proof. In this example we're going to prove a simple circuit that accepts two inputs named `a` and `b` and generates an output `c`. + +```swift +extension ContentView { + func runProveAction() { + // Prepare inputs + // + // The generateCircomProof function accepts an absolute path + // to the zkey, and a map of strings to arrays of strings + // + // This is a mapping of input names to values. Note that if + // the input is not an array, it will still be specified as + // and array of length 1. + var inputs = [String: [String]]() + let a = 3 // First input + let b = 5 // Second input + inputs["a"] = [String(a)] // Numbers should be passed as strings + inputs["b"] = [String(b)] + + // Begin timing our proof generation + let start = CFAbsoluteTimeGetCurrent() + + // Call into the compiled static library + do { + let generateProofResult = try generateCircomProof(zkeyPath: zkeyPath, circuitInputs: inputs) + } catch { + print("Error generate a proof: \(error)") + } + + // Make some assertions about the resulting proof + assert(!generateProofResult.proof.isEmpty, "Proof should not be empty") + + let end = CFAbsoluteTimeGetCurrent() + let timeTaken = end - start + print("built proof in \(String(format: "%.3f", timeTaken))s") + } +} +``` + +You should now be able to run the iOS app on the simulator or a device and build a proof. The app should log the time taken to generate the proof. For a more complete example including serialization and verification check [here](https://github.com/vimwitch/mopro-app/blob/main/ios/mopro-test/ContentView.swift). \ No newline at end of file diff --git a/docs/versioned_docs/version-0.1.0/getting-started/rust-setup.md b/docs/versioned_docs/version-0.1.0/getting-started/rust-setup.md new file mode 100644 index 00000000..22cf27c6 --- /dev/null +++ b/docs/versioned_docs/version-0.1.0/getting-started/rust-setup.md @@ -0,0 +1,124 @@ +# Rust Setup + +This tutorial will show you how to build static library with Circom adapter for Android and iOS. Later pages show how to integrate into an existing iOS or Android app. + +Make sure you've installed the [prerequisites](/docs/prerequisites). + +## Setup the rust project + +Mopro works by providing a static library and an interface for your app to build proofs. Before you start this tutorial you should have a zkey and wasm file generated by circom. + +To get started we'll make a new rust project that builds this library. Run the following commands in your terminal: + +```sh +mkdir mopro-example +cd mopro-example +cargo init --lib +``` + +This will create a new rust project in the current directory. Now we'll add some dependencies to this project. Edit your `Cargo.toml` so that it looks like the following: + +```toml +[package] +name = "mopro-example" +version = "0.1.0" +edition = "2021" + +# We're going to build a static library named mopro_bindings +# This library name should not be changed +[lib] +crate-type = ["lib", "cdylib", "staticlib"] +name = "mopro_bindings" + +# We're going to build support for circom proofs only for this example +[features] +default = ["mopro-ffi/circom"] + +[dependencies] +mopro-ffi = { git = "https://github.com/zkmopro/mopro.git" } +rust-witness = { git = "https://github.com/vimwitch/rust-witness.git" } +uniffi = { version = "0.28", features = ["cli"] } +num-bigint = "0.4.0" + +[build-dependencies] +mopro-ffi = { git = "https://github.com/zkmopro/mopro.git" } +rust-witness = { git = "https://github.com/vimwitch/rust-witness.git" } +uniffi = { version = "0.28", features = ["build"] } +``` + +Now you should copy your wasm and zkey files somewhere in the project folder. For this tutorial we'll assume you placed them in `test-vectors/circom`. + +:::info +Download example multiplier2 wasm and zkey here: + +- [multiplier2.wasm](https://github.com/zkmopro/mopro/raw/ae88356e680ac4d785183267d6147167fabe071c/test-vectors/circom/multiplier2.wasm) +- [multiplier2_final.zkey](https://github.com/zkmopro/mopro/raw/ae88356e680ac4d785183267d6147167fabe071c/test-vectors/circom/multiplier2_final.zkey) + ::: + +Now we need to add 4 rust files. First we'll add `build.rs` in the main project folder. This file should contain the following: + +```rust +fn main() { + // We're going to transpile the wasm witness generators to C + // Change this to where you put your zkeys and wasm files + rust_witness::transpile::transpile_wasm("./test-vectors/circom".to_string()); + // This is writing the UDL file which defines the functions exposed + // to your app. We have pre-generated this file for you + // This file must be written to ./src + std::fs::write("./src/mopro.udl", mopro_ffi::app_config::UDL).expect("Failed to write UDL"); + // Finally initialize uniffi and build the scaffolding into the + // rust binary + uniffi::generate_scaffolding("./src/mopro.udl").unwrap(); +} +``` + +Second we'll change the file at `./src/lib.rs` to look like the following: + +```rust +// Here we're generating the C witness generator functions +// for a circuit named `multiplier2`. +// Your circuit name will be the name of the wasm file all lowercase +// with spaces, dashes and underscores removed +// +// e.g. +// multiplier2 -> multiplier2 +// keccak_256_256_main -> keccak256256main +// aadhaar-verifier -> aadhaarverifier +rust_witness::witness!(multiplier2); + +// Here we're calling a macro exported by uniffi. This macro will +// write some functions and bind them to the uniffi UDL file. These +// functions will invoke the `get_circom_wtns_fn` generated below. +mopro_ffi::app!(); + +// This macro is used to define the `get_circom_wtns_fn` function +// which defines a mapping between zkey filename and witness generator. +// You can pass multiple comma seperated `(filename, witness_function)` pairs to it. +// You can read in the `circom` doc section how you can manually set this function. +// One way to create the witness generator function is to use the `rust_witness!` above. +mopro_ffi::set_circom_circuits! { + ("multiplier2_final.zkey", multiplier2_witness), +} +``` + +Finally we'll add a new file at `src/bin/ios.rs`: + +```rust +fn main() { + // A simple wrapper around a build command provided by mopro. + // In the future this will likely be published in the mopro crate itself. + mopro_ffi::app_config::ios::build(); +} +``` + +and another at `src/bin/android.rs`: + +```rust +fn main() { + // A simple wrapper around a build command provided by mopro. + // In the future this will likely be published in the mopro crate itself. + mopro_ffi::app_config::android::build(); +} +``` + +Now you're ready to build your static library! You should be able to run either `cargo run --bin ios` or `cargo run --bin android` to build the corresponding static library. Move on to [iOS setup](ios-setup) or [Android setup](android-setup) to begin integrating in an app. diff --git a/docs/versioned_docs/version-0.1.0/intro.md b/docs/versioned_docs/version-0.1.0/intro.md new file mode 100644 index 00000000..837f149b --- /dev/null +++ b/docs/versioned_docs/version-0.1.0/intro.md @@ -0,0 +1,34 @@ +--- +sidebar_position: 1 +--- + +# Introduction + +Mopro makes client-side proving simple. You can think of it as a toolkit for ZK app development. It primarily focuses on running natively mobile. + +How? Mopro connects different adapters with different platforms. You can think of an adapter as a way to use a library with some proof system and performance profile. Because Mopro takes care of hooking up your circuit to some library, and generating bindings for use on multiple platforms, you can focus on what you do best: ZK app development. + +![mopro adapters and platforms](/img/roadmap.png) + +Note that above is a work in progress, and the dashed lines indicate things that are still experimental and/or in an an early stage. + +If you just want to get started using mopro, see [getting started](getting-started/rust-setup). + +## Overview + +Mopro consists of a set of libraries and utilities. The following subprojects are including in the [mopro monorepo](https://github.com/zkmopro/mopro). + +Primary libraries and utilities of interest: + +- `mopro-ffi` - main package, exposes macros for configuring and building projects. +- `test-e2e` - example implementation of mopro in Android and iOS apps, used for testing. + +Secondary subprojects: + +- `docs` - This documentation website. + +## Architecture + +The following illustration shows how mopro and its components fit together into the wider ZKP ecosystem: + +![mopro architecture](/img/architecture.png) diff --git a/docs/versioned_docs/version-0.1.0/mopro-ffi.md b/docs/versioned_docs/version-0.1.0/mopro-ffi.md new file mode 100644 index 00000000..05b42369 --- /dev/null +++ b/docs/versioned_docs/version-0.1.0/mopro-ffi.md @@ -0,0 +1,14 @@ +# mopro-ffi + +`mopro-ffi` contains the logic for building a static library that can be invoked from a mobile app. This includes a macro for configuring `uniffi` as well as build commands for packaging an `xcframework` (for iOS) and `jniLibs` (for Android). + +## Development + +### Prerequisites + +1. Ensure you have Rust installed +2. If you're on OSX ensure the developer tools are installed + +### Building + +Run `cargo build` to build the library and `cargo test` to run the unit tests. diff --git a/docs/versioned_docs/version-0.1.0/performance.md b/docs/versioned_docs/version-0.1.0/performance.md new file mode 100644 index 00000000..45d91f3c --- /dev/null +++ b/docs/versioned_docs/version-0.1.0/performance.md @@ -0,0 +1,180 @@ +--- +sidebar_position: 5 +--- + +# Performance and Benchmarks + +## Circom + +In summary:
+Both native witness generation and proof generation are generally faster than `snarkjs` in the browser, with potential speed improvements of up to **20 times**.
+However, performance varies across different circuits. +We _recommend_ developers benchmark their custom circuits before selecting tools for app development. + +
+:::warning +- [witnesscalc](https://github.com/0xPolygonID/witnesscalc) hasn't been integrated in mopro. See [zkmopro/mopro#110](https://github.com/zkmopro/mopro/issues/110). +- [circom-witness-rs](https://github.com/philsippl/circom-witness-rs) is not fully compatible with circom circuits. See: [zkmopro/mopro#32](https://github.com/zkmopro/mopro/issues/32). +- [wasmer](https://github.com/arkworks-rs/circom-compat) doesn't work in iOS. See: [zkmopro/mopro#109](https://github.com/zkmopro/mopro/issues/109). +::: + +### iOS + +Benchmarks on an iPhone 12 mini (2020). + +
+ Witness generation + +| SHA256 | [witnesscalc](https://github.com/0xPolygonID/witnesscalc) | [circom-witness-rs](https://github.com/philsippl/circom-witness-rs) | [wasmer](https://github.com/arkworks-rs/circom-compat) | [w2c](https://github.com/vimwitch/rust-witness) | [snarkjs](https://github.com/iden3/snarkjs) | +|:--------------------:|:---------------------------------------------------------:|:-------------------------------------------------------------------:|:------------------------------------------------------:|:-----------------------------------------------:|:-------------------------------------------:| +| Average | 22.3 ms | 36.1 ms | 476.1 ms | 90.3 ms | 163.5 ms | +| Stdev | 1.2 ms | 0.3 ms | 27.8 ms | 1.2 ms | 6.7 ms | +| Comparing to snarkjs | **~7x** | ~4.5x | ~(-3)x | ~1.8 | - | + + + +| Keccak256 | [witnesscalc](https://github.com/0xPolygonID/witnesscalc) | [circom-witness-rs](https://github.com/philsippl/circom-witness-rs) | [wasmer](https://github.com/arkworks-rs/circom-compat) | [w2c](https://github.com/vimwitch/rust-witness) | [snarkjs](https://github.com/iden3/snarkjs) | +|:--------------------:|:---------------------------------------------------------:|:-------------------------------------------------------------------:|:------------------------------------------------------:|:-----------------------------------------------:|:-------------------------------------------:| +| Average | 144.7 ms | 26.2 ms | 440.7 ms | 160.7 ms | 257.1 ms | +| Stdev | 1.8 ms | 4.5 ms | 10.4 ms | 3.3 ms | 4.1 ms | +| Comparing to snarkjs | ~1.8x | **~10x** | ~(-1.7)x | ~1.6x | - | + + + +| RSA | [witnesscalc](https://github.com/0xPolygonID/witnesscalc) | [circom-witness-rs](https://github.com/philsippl/circom-witness-rs) | [wasmer](https://github.com/arkworks-rs/circom-compat) | [w2c](https://github.com/vimwitch/rust-witness) | [snarkjs](https://github.com/iden3/snarkjs) | +|:--------------------:|:---------------------------------------------------------:|:-------------------------------------------------------------------:|:------------------------------------------------------:|:-----------------------------------------------:|:-------------------------------------------:| +| Average | 208.5 ms | 513.1 ms | 5488 ms | 3861 ms | 5421 ms | +| Stdev | 5.8 ms | 11.2 ms | 47.8 ms | 10.8 ms | 9.9 ms | +| Comparing to snarkjs | **~26x** | ~10x | ~(-1)x | ~1.4x | - | + + +
+ +
+ Proof generation + +| SHA256 | [rapidsnark](https://github.com/iden3/rapidsnark) | [ark-works](https://github.com/arkworks-rs/circom-compat) | [snarkjs](https://github.com/iden3/snarkjs) | +|:--------------------:|:-------------------------------------------------:|:---------------------------------------------------------:|:-------------------------------------------:| +| Average | 795.2 ms | 550.4 ms | 2374.1 ms | +| Stdev | 17.2 ms | 27.2 ms | 62.9 ms | +| Comparing to snarkjs | ~3x | **~4.3x** | - | + + + +| Keccak256 | [rapidsnark](https://github.com/iden3/rapidsnark) | [ark-works](https://github.com/arkworks-rs/circom-compat) | [snarkjs](https://github.com/iden3/snarkjs) | +|:--------------------:|:-------------------------------------------------:|:---------------------------------------------------------:|:-------------------------------------------:| +| Average | 2647.9 ms | 1221.1 ms | 8149.1 ms | +| Stdev | 14.4 ms | 42.7 ms | 283.575 ms | +| Comparing to snarkjs | ~3x | **~6.7x** | - | + + + +| RSA | [rapidsnark](https://github.com/iden3/rapidsnark) | [ark-works](https://github.com/arkworks-rs/circom-compat) | [snarkjs](https://github.com/iden3/snarkjs) | +|:--------------------:|:-------------------------------------------------:|:---------------------------------------------------------:|:-------------------------------------------:| +| Average | 2908.6 ms | 2324.4 ms | 10304.8 ms | +| Stdev | 112.9 ms | 67.1 ms | 605.5 ms | +| Comparing to snarkjs | ~3.5x | **~4.4x** | - | + + +
+ +**Details:** [Spreadsheet of Circom benchmark (iOS)](https://docs.google.com/spreadsheets/d/1MFABmsYSUsWDmhbjleqhBXk7nkYwhu589yK-CHtRkNI/edit?usp=sharing) + +:::note + +- [Tachyon](https://github.com/kroma-network/tachyon) performs well in [macOS](#macos), but we haven't integrated it in + mobile. See [zkmopro/mopro#143](https://github.com/zkmopro/mopro/issues/143) + ::: + +### Android + +TBD + +### macOS + +Benchmarks on an Macbook Pro M1 Max (2021). + +
+ Witness generation + +| SHA256 | [Tachyon](https://github.com/kroma-network/tachyon) | [witnesscalc](https://github.com/0xPolygonID/witnesscalc) | [circom-witness-rs](https://github.com/philsippl/circom-witness-rs) | [wasmer](https://github.com/arkworks-rs/circom-compat) | [w2c](https://github.com/vimwitch/rust-witness) | [snarkjs](https://github.com/iden3/snarkjs) | +|:--------------------:|:---------------------------------------------------:|:---------------------------------------------------------:|:-------------------------------------------------------------------:|:------------------------------------------------------:|:-----------------------------------------------:|:-------------------------------------------:| +| Average | 32.7 ms | 22.2 ms | 42.8 ms | 454.5 ms | 88.8 ms | 132.8 ms | +| Stdev | 0.7 ms | 5.2 ms | 2.2 ms | 26.7 ms | 1.0 ms | 1.3 ms | +| Comparing to snarkjs | ~4x | **~6x** | ~3x | ~(-3.4)x | ~1.5x | - | + + + +| Keccak256 | [Tachyon](https://github.com/kroma-network/tachyon) | [witnesscalc](https://github.com/0xPolygonID/witnesscalc) | [circom-witness-rs](https://github.com/philsippl/circom-witness-rs) | [wasmer](https://github.com/arkworks-rs/circom-compat) | [w2c](https://github.com/vimwitch/rust-witness) | [snarkjs](https://github.com/iden3/snarkjs) | +|:--------------------:|:---------------------------------------------------:|:---------------------------------------------------------:|:-------------------------------------------------------------------:|:------------------------------------------------------:|:-----------------------------------------------:|:-------------------------------------------:| +| Average | 82.9 ms | 72.3 ms | 14.1 ms | 447.1 ms | 169 ms | 234.6 ms | +| Stdev | 0.2 ms | 7.7 ms | 0.8 ms | 5.9 ms | 2.0 ms | 3.2 ms | +| Comparing to snarkjs | ~2.8x | ~3x | **~16x** | ~(-1.9)x | x1.4x | - | + + + +| RSA | [Tachyon](https://github.com/kroma-network/tachyon) | [witnesscalc](https://github.com/0xPolygonID/witnesscalc) | [circom-witness-rs](https://github.com/philsippl/circom-witness-rs) | [wasmer](https://github.com/arkworks-rs/circom-compat) | [w2c](https://github.com/vimwitch/rust-witness) | [snarkjs](https://github.com/iden3/snarkjs) | +|:--------------------:|:---------------------------------------------------:|:---------------------------------------------------------:|:-------------------------------------------------------------------:|:------------------------------------------------------:|:-----------------------------------------------:|:-------------------------------------------:| +| Average | 218.4 ms | 167.6 ms | 522.9 ms | 5109 ms | 3847.2 ms | 4638.8 ms | +| Stdev | 16.8 ms | 7.5 ms | 7.7 ms | 25.1 ms | 61.3 ms | 32.4 ms | +| Comparing to snarkjs | ~21.2 | **~27x** | ~8.8x | ~(-1.1)x | ~1.2x | - | + + +
+ + +
+ Proof generation +| SHA256 | [Tachyon](https://github.com/kroma-network/tachyon) | [rapidsnark](https://github.com/iden3/rapidsnark) | [ark-works](https://github.com/arkworks-rs/circom-compat) | [snarkjs](https://github.com/iden3/snarkjs) | +| :--: | :--: | :--: | :--: | :--: | +| Average | 536.1 ms | 773.8 ms | 1137.3 ms | 1350.4 ms | +| Stdev | 10 ms | 17 ms | 127 ms | 26 ms | +| Comparing to snarkjs | **~2.5x** | ~1.7x | ~1.1 | - | + + + +| Keccak256 | [Tachyon](https://github.com/kroma-network/tachyon) | [rapidsnark](https://github.com/iden3/rapidsnark) | [ark-works](https://github.com/arkworks-rs/circom-compat) | [snarkjs](https://github.com/iden3/snarkjs) | +|:--------------------:|:---------------------------------------------------:|:-------------------------------------------------:|:---------------------------------------------------------:|:-------------------------------------------:| +| Average | 1931 ms | 2514 ms | 1133 ms | 3791 ms | +| Stdev | 31.9 ms | 75.2 ms | 168 ms | 58.6 ms | +| Comparing to snarkjs | ~1.9x | ~1.5x | **~3.3** | - | + + + +| RSA | [Tachyon](https://github.com/kroma-network/tachyon) | [rapidsnark](https://github.com/iden3/rapidsnark) | [ark-works](https://github.com/arkworks-rs/circom-compat) | [snarkjs](https://github.com/iden3/snarkjs) | +|:--------------------:|:---------------------------------------------------:|:-------------------------------------------------:|:---------------------------------------------------------:|:-------------------------------------------:| +| Average | 2307 ms | 2560 ms | 2530 ms | 5504 ms | +| Stdev | 18.7 ms | 21.3 ms | 266.1 ms | 69.3 ms | +| Comparing to snarkjs | **~2.3** | ~2.1x | ~2.1x | - | + + +
+ +**Details:** [Spreadsheet of Circom benchmark (macOS)](https://docs.google.com/spreadsheets/d/1irKg_TOP-yXms8igwCN_3OjVrtFe5gTHkuF0RbrVuho/edit?usp=sharing) +
+ +## Halo2 + +In summary:
+The performance of the Mopro build is comparable to the native Halo2 build.
+ +
+ +The bellow tests were run on a Macbook Pro M1 Pro (2021) as well as an iPhone 15 Pro (2023). + +| [Keccak256](https://github.com/ElusAegis/halo2-keccak-stable.git) | Prove Time (s) | Verify Time (s) | +|:-----------------------------------------------------------------:|:--------------:|:---------------:| +| Native (M1 Pro) | 10.3 s | 0.15 s | +| Emulator (M1 Pro) | 10.1 s | 0.13 s | +| iPhone 15 Pro | 11.0 s | 0.12 s | + +| [RSA](https://github.com/ElusAegis/halo2-rsa-mopro.git) | Prove Time (s) | Verify Time (s) | +|:-------------------------------------------------------:|:--------------:|:---------------:| +| Native (M1 Pro) | 76.5 s | 11.1 s | +| Emulator (M1 Pro) | 64.5 s | 9.0 s | +| iPhone 15 Pro | crashes | crashes | + +Note that the iPhone 15 Pro crashes when running the RSA circuit due to the large memory requirements. The circuit needs +around 5GB of memory to run, while the iPhone 15 Pro usually limits the application memory usage to 3GB. + +
\ No newline at end of file diff --git a/docs/versioned_docs/version-0.1.0/prerequisites.md b/docs/versioned_docs/version-0.1.0/prerequisites.md new file mode 100644 index 00000000..8dab1fe4 --- /dev/null +++ b/docs/versioned_docs/version-0.1.0/prerequisites.md @@ -0,0 +1,45 @@ +--- +sidebar_position: 2 +--- + +# Prerequisites + +Depending on what platforms and adapters you use, there are several prerequisites to install before getting started. + +- General + - [Rust](https://www.rust-lang.org/learn/get-started) +- iOS + - [Xcode](https://developer.apple.com/xcode/) +- Android + - [Android Studio](https://developer.android.com/studio) + - Also see [configuration](#android-configuration) below +- Circom + - Pre-built `zkey` and `wasm` files for your circuits + +## Android configuration + +Some additional configuration is required for Android. + +First, install the latest SDK. In Android Studio, go to `SDK Manager > SDK Tools` and install `NDK (Side by Side)` (see [Android Developer site](https://developer.android.com/studio/projects/install-ndk#default-version)). + +After that, set the following environment variables: + +1. Export `$ANDROID_HOME` and change `{USER_NAME}` to your username + +```sh +export ANDROID_HOME="/Users/{USER_NAME}/Library/Android/sdk" +``` + +2. Locate which NDK version you have + +```sh +ls $ANDROID_HOME/ndk # => 26.1.10909125 +``` + +3. Set it to your `NDK_PATH` environment variable + +```sh +NDK_PATH=$ANDROID_HOME/ndk/26.1.10909125 +``` + +> Reference: [Running Rust on Android with UniFFI](https://sal.dev/android/intro-rust-android-uniffi/). diff --git a/docs/versioned_sidebars/version-0.1.0-sidebars.json b/docs/versioned_sidebars/version-0.1.0-sidebars.json new file mode 100644 index 00000000..e5ab8d8e --- /dev/null +++ b/docs/versioned_sidebars/version-0.1.0-sidebars.json @@ -0,0 +1,52 @@ +{ + "docsSidebar": [ + { + "type": "doc", + "label": "Introduction", + "id": "intro" + }, + { + "type": "doc", + "label": "Prerequisites", + "id": "prerequisites" + }, + { + "type": "category", + "label": "Getting Started", + "items": [ + "getting-started/rust-setup", + "getting-started/ios-setup", + "getting-started/android-setup" + ] + }, + { + "type": "category", + "label": "Supported Adapters", + "items": [ + "adapters/overview", + "adapters/circom", + "adapters/halo2" + ] + }, + { + "type": "doc", + "label": "Mopro FFI", + "id": "mopro-ffi" + }, + { + "type": "doc", + "label": "Performance and Benchmarks", + "id": "performance" + }, + { + "type": "doc", + "label": "Community and Talks", + "id": "community" + }, + { + "type": "doc", + "label": "FAQ", + "id": "FAQ" + } + ] +} diff --git a/docs/versions.json b/docs/versions.json index daa9a702..fdf95ff4 100644 --- a/docs/versions.json +++ b/docs/versions.json @@ -1,3 +1,4 @@ [ + "0.1.0", "0.0.1" ]