Nova Scotia: Middleware to compile Circom circuits to Nova prover

[Reference: https://github.com/nalinbhardwaj/Nova-Scotia]

My device: Macbook Pro 2020 with Intel chip

1
2
3
4
git clone https://github.com/nalinbhardwaj/Nova-Scotia.git
cd Nova-Scotia
cargo build
cargo run --example toy_bn254 #Available examples: bitcoin, toy_bn254, toy_pasta

toy_bn254.rs

1
2
3
4
5
6
7
8
9
10
11
fn main() {
let group_name = "bn254";

let circuit_filepath = format!("examples/toy/{}/toy.r1cs", group_name);
for witness_gen_filepath in [
format!("examples/toy/{}/toy_cpp/toy", group_name),
format!("examples/toy/{}/toy_js/toy.wasm", group_name),
] {
run_test(circuit_filepath.clone(), witness_gen_filepath);
}
}

toy_circuit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
pragma circom 2.0.3;

// include "https://github.com/0xPARC/circom-secp256k1/blob/master/circuits/bigint.circom";

template Example () {
signal input step_in[2];

signal output step_out[2];

signal input adder;

step_out[0] <== step_in[0] + adder;
step_out[1] <== step_in[0] + step_in[1];
}

component main { public [step_in] } = Example();

/* INPUT = {
"step_in": [1, 1],
"step_out": [1, 2],
"adder": 0
} */

example = toy_bn254

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Running test with witness generator: examples/toy/bn254/toy_cpp/toy and group: halo2curves::bn256::curve::G1
Number of constraints per step (primary circuit): 9987
Number of constraints per step (secondary circuit): 10536
Number of variables per step (primary circuit): 9982
Number of variables per step (secondary circuit): 10518
Creating a RecursiveSNARK...
RecursiveSNARK creation took 13.224248261s
Verifying a RecursiveSNARK...
RecursiveSNARK::verify: Ok(([0x0000000000000000000000000000000000000000000000000000000000000014, 0x0000000000000000000000000000000000000000000000000000000000000046], [0x0000000000000000000000000000000000000000000000000000000000000000])), took 3.157009284s
Generating a CompressedSNARK using Spartan with IPA-PC...
CompressedSNARK::prove: true, took 70.214257205s
Verifying a CompressedSNARK...
CompressedSNARK::verify: true, took 2.716456417s
Adding steps to our RecursiveSNARK...
Adding 2 steps to our RecursiveSNARK took 6.124253293s
Verifying a RecursiveSNARK...
RecursiveSNARK::verify: Ok(([0x000000000000000000000000000000000000000000000000000000000000001f, 0x0000000000000000000000000000000000000000000000000000000000000073], [0x0000000000000000000000000000000000000000000000000000000000000000])), took 3.17058345s
Running test with witness generator: examples/toy/bn254/toy_js/toy.wasm and group: halo2curves::bn256::curve::G1
Number of constraints per step (primary circuit): 9987
Number of constraints per step (secondary circuit): 10536
Number of variables per step (primary circuit): 9982
Number of variables per step (secondary circuit): 10518
Creating a RecursiveSNARK...
RecursiveSNARK creation took 13.44364122s
Verifying a RecursiveSNARK...
RecursiveSNARK::verify: Ok(([0x0000000000000000000000000000000000000000000000000000000000000014, 0x0000000000000000000000000000000000000000000000000000000000000046], [0x0000000000000000000000000000000000000000000000000000000000000000])), took 3.164956873s
Generating a CompressedSNARK using Spartan with IPA-PC...
CompressedSNARK::prove: true, took 71.255975254s
Verifying a CompressedSNARK...
CompressedSNARK::verify: true, took 2.705070478s
Adding steps to our RecursiveSNARK...
Adding 2 steps to our RecursiveSNARK took 6.359241709s
Verifying a RecursiveSNARK...
RecursiveSNARK::verify: Ok(([0x000000000000000000000000000000000000000000000000000000000000001f, 0x0000000000000000000000000000000000000000000000000000000000000073], [0x0000000000000000000000000000000000000000000000000000000000000000])), took 3.185926252s

example = toy_pasta

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Running test with witness generator: examples/toy/pasta/toy_cpp/toy and group: pasta_curves::curves::Ep
Number of constraints per step (primary circuit): 9819
Number of constraints per step (secondary circuit): 10347
Number of variables per step (primary circuit): 9814
Number of variables per step (secondary circuit): 10329
Creating a RecursiveSNARK...
RecursiveSNARK creation took 4.414209623s
Verifying a RecursiveSNARK...
RecursiveSNARK::verify: Ok(([0x0000000000000000000000000000000000000000000000000000000000000014, 0x0000000000000000000000000000000000000000000000000000000000000046], [0x0000000000000000000000000000000000000000000000000000000000000000])), took 370.838978ms
Generating a CompressedSNARK using Spartan with IPA-PC...
CompressedSNARK::prove: true, took 32.915398792s
Verifying a CompressedSNARK...
CompressedSNARK::verify: true, took 345.546614ms
Running test with witness generator: examples/toy/pasta/toy_js/toy.wasm and group: pasta_curves::curves::Ep
Number of constraints per step (primary circuit): 9819
Number of constraints per step (secondary circuit): 10347
Number of variables per step (primary circuit): 9814
Number of variables per step (secondary circuit): 10329
Creating a RecursiveSNARK...
RecursiveSNARK creation took 4.407457827s
Verifying a RecursiveSNARK...
RecursiveSNARK::verify: Ok(([0x0000000000000000000000000000000000000000000000000000000000000014, 0x0000000000000000000000000000000000000000000000000000000000000046], [0x0000000000000000000000000000000000000000000000000000000000000000])), took 266.348024ms
Generating a CompressedSNARK using Spartan with IPA-PC...
CompressedSNARK::prove: true, took 32.952874742s
Verifying a CompressedSNARK...
CompressedSNARK::verify: true, took 332.043144ms

Some Error and solution:

1
2
3
4
stdout: stderr: dyld[3280]: Library not loaded: /usr/local/opt/gmp/lib/libgmp.10.dylib

Referenced from: <70F76335-7705-34A9-B709-6DD492286528> /path/to/Nova-Scotia/examples/toy/pasta/toy_cpp/toy
Reason: tried: /some/possible/paths/
1
2
3
brew update && brew install gmp
brew ls gmp
cp /opt/homebrew/Cellar/gmp/6.3.0/lib/libgmp.10.dylib /one/of/the/possible/paths/

Notes: Cannot run on the MacOS with m1/m2 chips :(
(Error: have ‘arm64’, need ‘x86_64’)