Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NOVA Scotia folding scheme test done #227 #240

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e3041ff
Add Nova Scotia Packages
timou0911 Sep 14, 2024
2341cd6
Add Nova Scotia Packages
timou0911 Sep 14, 2024
30d9626
Add Nova Scotia Dependencies
timou0911 Sep 14, 2024
09d5e38
Add Nova Scotia Dependencies
timou0911 Sep 14, 2024
5df1c71
Add Nova Scotia Features
timou0911 Sep 14, 2024
86e8741
Add Nova Scotia
timou0911 Sep 14, 2024
a0caffe
Change Return Type
timou0911 Sep 14, 2024
6209b73
Change Return Type
timou0911 Sep 14, 2024
c67d5bf
Add toy example
timou0911 Sep 14, 2024
ebd31f0
nova_scotia test with error(22)
csiejimmyliu Sep 14, 2024
761c7f0
nova_scotia test with error(19)
csiejimmyliu Sep 14, 2024
2157b15
Fixing Errors(10)
timou0911 Sep 14, 2024
8f472dc
nova_scotia test with error(2): verify_nova_scotia_proof return type
csiejimmyliu Sep 14, 2024
b91fbce
test able to build (not compressed yet)
csiejimmyliu Sep 14, 2024
b471ca2
test fail (can't reproduce sample code yet)
csiejimmyliu Sep 15, 2024
8e68452
test pass with bn256_grumpkin(not compress yet)
csiejimmyliu Sep 15, 2024
7c46b20
test pass with bn256_grumpkin, compress done
csiejimmyliu Sep 16, 2024
220cabc
remove unuse import
csiejimmyliu Sep 19, 2024
805b0b2
comments done
csiejimmyliu Sep 21, 2024
0b6d0b7
Merge branch 'zkmopro:main' into main
csiejimmyliu Sep 21, 2024
c03face
rename circuit, remove temporary files, CI script, enable dependencies
csiejimmyliu Sep 25, 2024
f478b51
dev dependencies test
csiejimmyliu Sep 25, 2024
298f972
optional dependencies
csiejimmyliu Sep 26, 2024
a7bbad4
move above dev dependencies
csiejimmyliu Sep 26, 2024
9450c94
solve the NovaScotiaError problem
june-in-exile Oct 7, 2024
a3db961
try some brutal way to fix the import problem but fails
june-in-exile Oct 8, 2024
9e013be
update github action
june-in-exile Oct 8, 2024
4e0aa50
update nova_scotia_app! to make it testable
june-in-exile Oct 8, 2024
61eab82
refactor by adding nova_scotia_types.rs
june-in-exile Oct 8, 2024
103dd13
sorry I forgot to lint
june-in-exile Oct 8, 2024
86cf7ca
refactor for better readability
june-in-exile Oct 8, 2024
89b6b4c
remove type
june-in-exile Oct 8, 2024
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
948 changes: 776 additions & 172 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion mopro-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ circom = [
"byteorder",
]

nova_scotia = []
vivianjeng marked this conversation as resolved.
Show resolved Hide resolved

[dependencies]
uniffi = { version = "=0.28.0", features = ["cli", "build"] }

Expand Down Expand Up @@ -71,6 +73,12 @@ ark-bls12-381 = { version = "0.4.0", optional = true }
num-traits = { version = "0.2.0", optional = true }
anyhow = "1.0.86"

# Nova Scotia dependencies
nova-scotia = "0.5.0"
nova-snark = "0.23.0"
serde_json = "1.0.85"
pasta_curves = "0.5"
vivianjeng marked this conversation as resolved.
Show resolved Hide resolved

[build-dependencies]
rust-witness = "0.1.0"
uniffi = { version = "=0.28.0", features = ["build"] }
Expand All @@ -85,4 +93,4 @@ serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0"

# Halo2 dependencies
halo2-fibonacci = { git = "https://github.com/ElusAegis/halo2-fibonacci-sample.git" }
halo2-fibonacci = { git = "https://github.com/ElusAegis/halo2-fibonacci-sample.git" }
33 changes: 33 additions & 0 deletions mopro-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ pub mod app_config;
mod circom;
#[cfg(feature = "halo2")]
mod halo2;
#[cfg(feature = "nova_scotia")]
mod nova_scotia;

#[cfg(feature = "circom")]
pub use circom::{
Expand All @@ -14,6 +16,9 @@ pub use circom::{
#[cfg(feature = "halo2")]
pub use halo2::{Halo2ProveFn, Halo2VerifyFn};

#[cfg(feature = "nova_scotia")]
//pub use nova_scotia::{};

#[cfg(not(feature = "circom"))]
#[macro_export]
macro_rules! circom_app {
Expand Down Expand Up @@ -67,6 +72,30 @@ macro_rules! halo2_app {
};
}

#[cfg(not(feature = "nova_scotia"))]
#[macro_export]
macro_rules! nova_scotia_app {
() => {
fn generate_nova_scotia_proof(
r1cs_path: String,
cpp_bin_or_wasm_path: String,
private_inputs: Vec<HashMap<String, Value>>,
start_public_input: Vec<F<G1>>,
) -> Result<GenerateProofResult, MoproError> {
panic!("Nova Scotia is not enabled in this build. Please pass `nova-scotia` feature to `mopro-ffi` to enable Nova Scotia.")
}

fn verify_nova_scotia_proof(
recursive_snark: RecursiveSNARK<G1, G2, C1<G1>, C2<G2>>,
pp: &PublicParams<G1, G2, C1<G1>, C2<G2>>,
iteration_count: usize,
start_public_input: &[E1::Scalar],
vivianjeng marked this conversation as resolved.
Show resolved Hide resolved
) -> Result<bool, MoproError> {
panic!("Nova Scotia is not enabled in this build. Please pass `nova-scotia` feature to `mopro-ffi` to enable Nova Scotia.")
}
};
}

use thiserror::Error;

#[derive(Debug, Error)]
Expand All @@ -75,6 +104,8 @@ pub enum MoproError {
CircomError(String),
#[error("Halo2Error: {0}")]
Halo2Error(String),
#[error("NovaScotiaError: {0}")]
NovaScotiaError(String),
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -148,6 +179,8 @@ macro_rules! app {

mopro_ffi::halo2_app!();

mopro_ffi::nova_scotia_app!();

uniffi::include_scaffolding!("mopro");
};
}
195 changes: 195 additions & 0 deletions mopro-ffi/src/nova_scotia/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
#[macro_export]
macro_rules! nova_scotia_app {
() => {

fn generate_recursive_snark_proof(
witness_generator_file: PathBuf,
r1cs: circom::circuit::R1CS<F<G1>>,
private_inputs: Vec<HashMap<String, serde_json::Value>>,
start_public_input: [F<G1>; 2],
pp: &PublicParams<G1, G2, C1<G1>, C2<G2>>,
) -> Result<RecursiveSNARK<G1, G2, C1<G1>, C2<G2>>, mopro_ffi::MoproError> {

let res = create_recursive_circuit(
FileLocation::PathBuf(witness_generator_file),
r1cs,
private_inputs,
start_public_input.to_vec(),
&pp,
);

res.map_err(|e| mopro_ffi::MoproError::NovaScotiaError(format!("nova_scotia error: {}", e)))
}


fn verify_recursive_snark_proof(
recursive_snark: &RecursiveSNARK<G1, G2, C1<G1>, C2<G2>>,
pp: &PublicParams<G1, G2, C1<G1>, C2<G2>>,
iteration_count: usize,
start_public_input: [F<G1>; 2],
z0_secondary: [F<G2>; 1],
) -> Result<(Vec<F<G1>>, Vec<F<G2>>), mopro_ffi::MoproError> {

let res = recursive_snark.verify(
&pp,
iteration_count,
&start_public_input.clone(),
&z0_secondary,
);

res.map_err(|e| {
mopro_ffi::MoproError::NovaScotiaError(format!("error verifying proof: {}", e))
})
}


fn compress_snark_proof(
recursive_snark: RecursiveSNARK<G1, G2, C1<G1>, C2<G2>>,
pp: &PublicParams<G1, G2, C1<G1>, C2<G2>>,
pk: &ProverKey<G1, G2, C1<G1>, C2<G2>, S<G1>, S<G2>>,
) -> Result<CompressedSNARK<G1, G2, C1<G1>, C2<G2>, S<G1>, S<G2>>, mopro_ffi::MoproError> {

let res = CompressedSNARK::<_, _, _, _, S<G1>, S<G2>>::prove(&pp, &pk, &recursive_snark);

res.map_err(|e| {
mopro_ffi::MoproError::NovaScotiaError(format!("error compress proof: {}", e))
})
}


fn verify_compressed_snark_proof(
compressed_snark: CompressedSNARK<G1, G2, C1<G1>, C2<G2>,S<G1>, S<G2>>,
vk: &VerifierKey<G1, G2, C1<G1>, C2<G2>, S<G1>, S<G2>>,
iteration_count: usize,
start_public_input: [F<G1>; 2],
z0_secondary: [F<G2>; 1],
) -> Result<(Vec<F<G1>>, Vec<F<G2>>), mopro_ffi::MoproError> {

let res = compressed_snark.verify(
&vk,
iteration_count,
start_public_input.clone().to_vec(),
z0_secondary.to_vec(),
);

res.map_err(|e| {
mopro_ffi::MoproError::NovaScotiaError(format!("error verifying proof: {}", e))
})
}


};
}

#[cfg(test)]
mod test {
use std::{collections::HashMap, panic};

use nova_scotia::*;

use nova_snark::{
provider,
CompressedSNARK, PublicParams, RecursiveSNARK, ProverKey, VerifierKey,
};

use crate as mopro_ffi;
use serde_json::json;
use std::path::PathBuf;

nova_scotia_app!();

const R1CS_PATH: &str = "../test-vectors/nova_scotia/toy.r1cs";
const WASM_PATH: &str = "../test-vectors/nova_scotia/toy_js/toy.wasm";

// Define curve cycle, can be any curve cycle supported by Nova
type G1 = provider::bn256_grumpkin::bn256::Point;
type G2 = provider::bn256_grumpkin::grumpkin::Point;

#[test]
fn test_generate_and_verify_nova_scotia_proof() {
let root = std::env::current_dir().unwrap();

// Load r1cs file
let circuit_file = root.join(R1CS_PATH.to_string());
let r1cs = circom::reader::load_r1cs::<G1, G2>(&FileLocation::PathBuf(circuit_file));

// Load c++ binary or wasm file
let witness_generator_file = root.join(WASM_PATH.to_string());

// Generate private inputs
/*
each folding steps (step_in[0], step_in[1]):
step_out[0] <== step_in[0] + adder;
step_out[1] <== step_in[0] + step_in[1];

adder is the private input (auxiliary input) that we have.

step_in[0], step_in[1], adder
10, 10, 0
10, 20, 1
11, 30, 2
13, 41, 3
16, 54, 4
20, 70, 5 <-- state of things when we output results

*/
let iteration_count = 5;
let mut private_inputs = Vec::new();
for i in 0..iteration_count {
let mut private_input = HashMap::new();
private_input.insert("adder".to_string(), json!(i));
private_inputs.push(private_input);
}

// Set starting public input
let start_public_input = [F::<G1>::from(10), F::<G1>::from(10)];

// Create public parameters(CRS)
let pp = create_public_params::<G1, G2>(r1cs.clone());

let z0_secondary = [F::<G2>::from(0)];

if let Ok(proof_result) = generate_recursive_snark_proof(
witness_generator_file,
r1cs,
private_inputs,
start_public_input,
&pp,
) {

let result = verify_recursive_snark_proof(
&proof_result,
&pp,
iteration_count,
start_public_input,
z0_secondary,
);

assert!(result.is_ok());
let (pk, vk) = CompressedSNARK::<_, _, _, _, S<G1>, S<G2>>::setup(&pp).unwrap();

if let Ok(compressed_proof_result) = compress_snark_proof(
proof_result,
&pp,
&pk,
) {

let result = verify_compressed_snark_proof(
compressed_proof_result,
&vk,
iteration_count,
start_public_input,
z0_secondary,
);

assert!(result.is_ok());

} else {
panic!("Failed to generate the compressed proof!")
}

} else {
panic!("Failed to generate the recursive proof!")
}
}
}
Binary file added test-e2e/jna-5.13.0.jar
Binary file not shown.
22 changes: 22 additions & 0 deletions test-vectors/nova_scotia/toy.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,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
} */
Binary file added test-vectors/nova_scotia/toy.r1cs
Binary file not shown.
20 changes: 20 additions & 0 deletions test-vectors/nova_scotia/toy_js/generate_witness.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const wc = require("./witness_calculator.js");
const { readFileSync, writeFile } = require("fs");

if (process.argv.length != 5) {
console.log("Usage: node generate_witness.js <file.wasm> <input.json> <output.wtns>");
} else {
const input = JSON.parse(readFileSync(process.argv[3], "utf8"));

const buffer = readFileSync(process.argv[2]);
wc(buffer).then(async witnessCalculator => {
// const w= await witnessCalculator.calculateWitness(input,0);
// for (let i=0; i< w.length; i++){
// console.log(w[i]);
// }
const buff= await witnessCalculator.calculateWTNSBin(input,0);
writeFile(process.argv[4], buff, function(err) {
if (err) throw err;
});
});
}
Binary file added test-vectors/nova_scotia/toy_js/toy.wasm
Binary file not shown.
Loading