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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/provers/groth16/circom-adapter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ repository.workspace = true
lambdaworks-math.workspace = true
lambdaworks-groth16.workspace = true

serde = { version = "1.0" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1"
76 changes: 76 additions & 0 deletions crates/provers/groth16/circom-adapter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Circom - Lambdaworks Groth16 Adapter

This package allows one to perform trusted setup, prove, and verify constraints generated by [SnarkJS](https://github.com/iden3/snarkjs) from a [Circom](https://github.com/iden3/circom) circuit over [BLS12-381](https://github.com/lambdaclass/lambdaworks/tree/main/crates/math/src/elliptic_curve/short_weierstrass/curves/bls12_381).

## Setup

1. Install [Circom](https://github.com/iden3/circom) and [SnarkJS](https://github.com/iden3/snarkjs).

2. Compile your circuit with `circom`, e.g. for a circuit named `test.circom` you would do:

```bash
circom test.circom --r1cs --wasm -p bls12381
```

> [!IMPORTANT]
> Note that `-p bls12381` is important as that is the field supported by Lambdaworks Circom Adapter.

3. Compiling a circuit like above will create a `test_js` directory, and a `test.r1cs` file. Now, we will create a witness for an input that is saved within `input.json`:

```bash
node test_js/generate_witness.js test_js/test.wasm input.json witness.wtns
```

This will generate a **witness.wtns** file.

4. For the Circom Adapter we need to export the witness and R1CS files as JSON:

```bash
snarkjs wtns export json witness.wtns witness.wtns.json
snarkjs r1cs export json test.r1cs test.r1cs.json
```

To do these steps all at once, you can copy-paste the following snippet to your terminal in the same directory as your circuit, using your own circuit name instead of `test` here:

```bash
circom test.circom --r1cs --wasm -p bls12381;

node test_js/generate_witness.js test_js/test.wasm input.json witness.wtns;

snarkjs wtns export json witness.wtns;
snarkjs r1cs export json test.r1cs test.r1cs.json;
```

## Usage

This crate exposes a `circom_to_lambda` function along with readers for R1CS and witness files. `circom_to_lambda` accepts a Witness and R1CS.

```rust
let circom_r1cs = read_circom_r1cs("test.r1cs.json").expect("could not read r1cs");
let circom_wtns = read_circom_witness("witness.json").expect("could not read witness");

let (qap, wtns, pubs) = circom_to_lambda(circom_r1cs, circom_wtns);
```

This function returns a Lambdaworks-compatible QAP, the witness assignments and public signals. Then one should perform setup, prove, and verify. Here's the complete procedure:

```rust
fn poseidon_parse_prove_verify() {
let (qap, wtns, pubs) = circom_to_lambda(
&fs::read_to_string("test.r1cs.json").expect("Error reading file"),
&fs::read_to_string("witness.json").expect("Error reading file"),
);

let (pk, vk) = setup(&qap);
let proof = Prover::prove(&wtns, &qap, &pk);
let accept = verify(&vk, &proof, &pubs);
assert!(accept);
}
```

## Examples

There are a few examples within the [tests](./tests/) folder:

- [`poseidon_test.rs`](./tests/poseidon_test.rs): Poseidon hash of $100$ is proven and verified.
- [`vitalik_test.rs`](./tests/vitalik_test.rs): Here we demonstrate the example from [Vitalik's Medium post](https://medium.com/@VitalikButerin/quadratic-arithmetic-programs-from-zero-to-hero-f6d558cea649) where $x^3 + x + 5 = 35$ is zk-proven.
83 changes: 0 additions & 83 deletions crates/provers/groth16/circom-adapter/src/README.md

This file was deleted.

104 changes: 0 additions & 104 deletions crates/provers/groth16/circom-adapter/src/integration_tests.rs

This file was deleted.

Loading
Loading