Skip to content

Commit

Permalink
doc: versioned doc (#219)
Browse files Browse the repository at this point in the history
* doc: versioned doc

* chore: change from `0.0.2` to `0.1.0`
  • Loading branch information
vivianjeng authored Jul 19, 2024
1 parent d2e3630 commit 27787bb
Show file tree
Hide file tree
Showing 18 changed files with 1,220 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docs/docs/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion docs/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
8 changes: 4 additions & 4 deletions docs/versioned_docs/version-0.0.1/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down Expand Up @@ -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.
2 changes: 1 addition & 1 deletion docs/versioned_docs/version-0.0.1/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
40 changes: 40 additions & 0 deletions docs/versioned_docs/version-0.1.0/FAQ.md
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.
176 changes: 176 additions & 0 deletions docs/versioned_docs/version-0.1.0/adapters/circom.md
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.


129 changes: 129 additions & 0 deletions docs/versioned_docs/version-0.1.0/adapters/halo2.md
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.


Loading

0 comments on commit 27787bb

Please sign in to comment.