-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* doc: versioned doc * chore: change from `0.0.2` to `0.1.0`
- Loading branch information
1 parent
d2e3630
commit 27787bb
Showing
18 changed files
with
1,220 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<String, Vec<BigInt>>) -> Vec<BigInt>; | ||
``` | ||
|
||
## 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<mopro_ffi::WtnsFn, mopro_ffi::MoproError> { | ||
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. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<String, Vec<String>>) -> Result<GenerateProofResult, Box<dyn std::error::Error>>; | ||
``` | ||
|
||
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<u8>`. 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<u8>, Vec<u8>) -> Result<bool, Box<dyn std::error::Error>>; | ||
``` | ||
|
||
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<Halo2ProveFn, MoproError> { | ||
match circuit { | ||
"fibonacci_pk.bin" => Ok(halo2_fibonacci::prove), | ||
_ => Err(MoproError::CircuitNotFound), | ||
} | ||
} | ||
|
||
fn get_halo2_verifying_circuit(circuit: &str) -> Result<Halo2VerifyFn, MoproError> { | ||
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. | ||
|
||
|
Oops, something went wrong.