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

feat(core): update read_zkey with new_unchecked #129

Merged
merged 3 commits into from
Apr 26, 2024
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
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ark-zkey/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ flamer = "0.5"
ark-serialize = { version = "=0.4.1", features = ["derive"] }
ark-bn254 = { version = "=0.4.0" }
ark-groth16 = { version = "=0.4.0" }
ark-circom = { git = "https://github.com/arkworks-rs/circom-compat.git" }
ark-circom = { git = "https://github.com/vimwitch/circom-compat.git" }
ark-relations = { version = "=0.4.0" }
ark-ff = { version = "=0.4.1" }
ark-ec = { version = "=0.4.1" }
2 changes: 1 addition & 1 deletion mopro-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ calc-native-witness = ["witness"] # experimental feature to calculate witness wi
build-native-witness = ["witness/build-witness"] # only enable build-native-witness feature when building the witness graph

[dependencies]
ark-circom = { git = "https://github.com/arkworks-rs/circom-compat.git" }
ark-circom = { git = "https://github.com/vimwitch/circom-compat.git" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
ark-serialize = { version = "=0.4.1", features = ["derive"] }
Expand Down
4 changes: 2 additions & 2 deletions mopro-core/examples/circom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ use std::collections::HashMap;

fn main() {
let wasm_path = "./examples/circom/multiplier2/target/multiplier2_js/multiplier2.wasm";
let arkzkey_path = "./examples/circom/multiplier2/target/multiplier2_final.arkzkey";
let zkey_path = "./examples/circom/multiplier2/target/multiplier2_final.zkey";

// Instantiate CircomState
let mut circom_state = CircomState::new();

// Setup
let setup_res = circom_state.initialize(arkzkey_path, wasm_path);
let setup_res = circom_state.initialize(zkey_path, wasm_path);
assert!(setup_res.is_ok());

let _serialized_pk = setup_res.unwrap();
Expand Down
Binary file not shown.
92 changes: 49 additions & 43 deletions mopro-core/src/middleware/circom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ use self::{
};
use crate::MoproError;

use std::collections::HashMap;
//use std::io::Cursor;
use std::io::Cursor;
use std::sync::Mutex;
use std::time::Instant;
use std::{collections::HashMap, fs::File, io::BufReader};

use ark_bn254::{Bn254, Fr};
use ark_circom::{
read_zkey,
CircomReduction,
WitnessCalculator, //read_zkey,
};
Expand Down Expand Up @@ -52,7 +53,7 @@ type CircuitInputs = HashMap<String, Vec<BigInt>>;
// TODO: Split up this namespace a bit, right now quite a lot of things going on

pub struct CircomState {
arkzkey: Option<(ProvingKey<Bn254>, ConstraintMatrices<Fr>)>,
zkey: Option<(ProvingKey<Bn254>, ConstraintMatrices<Fr>)>,
wtns: Option<WitnessCalculator>,
}

Expand All @@ -66,21 +67,21 @@ impl Default for CircomState {

// TODO: Replace printlns with logging

//const ZKEY_BYTES: &[u8] = include_bytes!(env!("BUILD_RS_ZKEY_FILE"));
const ZKEY_BYTES: &[u8] = include_bytes!(env!("BUILD_RS_ZKEY_FILE"));

const ARKZKEY_BYTES: &[u8] = include_bytes!(env!("BUILD_RS_ARKZKEY_FILE"));
// const ARKZKEY_BYTES: &[u8] = include_bytes!(env!("BUILD_RS_ARKZKEY_FILE"));

// static ZKEY: Lazy<(ProvingKey<Bn254>, ConstraintMatrices<Fr>)> = Lazy::new(|| {
// let mut reader = Cursor::new(ZKEY_BYTES);
// read_zkey(&mut reader).expect("Failed to read zkey")
// });

static ARKZKEY: Lazy<(ProvingKey<Bn254>, ConstraintMatrices<Fr>)> = Lazy::new(|| {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have to remove the ARKZKEY stuff you think? or is this preferable?

thinking mostly about space savings which are quite significant

//let mut reader = Cursor::new(ARKZKEY_BYTES);
// TODO: Use reader? More flexible; unclear if perf diff
read_arkzkey_from_bytes(ARKZKEY_BYTES).expect("Failed to read arkzkey")
static ZKEY: Lazy<(ProvingKey<Bn254>, ConstraintMatrices<Fr>)> = Lazy::new(|| {
let mut reader = Cursor::new(ZKEY_BYTES);
read_zkey(&mut reader).expect("Failed to read zkey")
});

// static ARKZKEY: Lazy<(ProvingKey<Bn254>, ConstraintMatrices<Fr>)> = Lazy::new(|| {
// //let mut reader = Cursor::new(ARKZKEY_BYTES);
// // TODO: Use reader? More flexible; unclear if perf diff
// read_arkzkey_from_bytes(ARKZKEY_BYTES).expect("Failed to read arkzkey")
// });

#[cfg(not(feature = "dylib"))]
const WASM: &[u8] = include_bytes!(env!("BUILD_RS_WASM_FILE"));

Expand Down Expand Up @@ -140,7 +141,8 @@ pub fn initialize() {
// Initialize ARKZKEY
// TODO: Speed this up even more!
let now = std::time::Instant::now();
Lazy::force(&ARKZKEY);
Lazy::force(&ZKEY);
// Lazy::force(&ARKZKEY);
println!("Initializing arkzkey took: {:.2?}", now.elapsed());
}

Expand All @@ -157,17 +159,17 @@ fn from_dylib(path: &Path) -> Mutex<WitnessCalculator> {
Mutex::new(result)
}

// #[must_use]
// pub fn zkey() -> &'static (ProvingKey<Bn254>, ConstraintMatrices<Fr>) {
// &ZKEY
// }

// Experimental
#[must_use]
pub fn arkzkey() -> &'static (ProvingKey<Bn254>, ConstraintMatrices<Fr>) {
&ARKZKEY
pub fn zkey() -> &'static (ProvingKey<Bn254>, ConstraintMatrices<Fr>) {
&ZKEY
}

// Experimental
// #[must_use]
// pub fn arkzkey() -> &'static (ProvingKey<Bn254>, ConstraintMatrices<Fr>) {
// &ARKZKEY
// }

/// Provides access to the `WITNESS_CALCULATOR` singleton, initializing it if necessary.
/// It expects the path to the dylib file to be set in the `CIRCUIT_WASM_DYLIB` environment variable.
#[cfg(feature = "dylib")]
Expand Down Expand Up @@ -223,8 +225,8 @@ pub fn generate_proof2(
println!("Witness generation took: {:.2?}", now.elapsed());

let now = std::time::Instant::now();
//let zkey = zkey();
let zkey = arkzkey();
let zkey = zkey();
// let zkey = arkzkey();
println!("Loading arkzkey took: {:.2?}", now.elapsed());

let public_inputs = full_assignment.as_slice()[1..zkey.1.num_instance_variables].to_vec();
Expand Down Expand Up @@ -253,7 +255,8 @@ pub fn verify_proof2(
serialized_inputs: SerializableInputs,
) -> Result<bool, MoproError> {
let start = Instant::now();
let zkey = arkzkey();
let zkey = zkey();
// let zkey = arkzkey();
let pvk = prepare_verifying_key(&zkey.0.vk);

let proof_verified =
Expand All @@ -268,15 +271,18 @@ pub fn verify_proof2(
impl CircomState {
pub fn new() -> Self {
Self {
arkzkey: None,
zkey: None,
// arkzkey: None,
wtns: None,
}
}

pub fn initialize(&mut self, arkzkey_path: &str, wasm_path: &str) -> Result<(), MoproError> {
let arkzkey =
read_arkzkey(arkzkey_path).map_err(|e| MoproError::CircomError(e.to_string()))?;
self.arkzkey = Some(arkzkey);
pub fn initialize(&mut self, zkey_path: &str, wasm_path: &str) -> Result<(), MoproError> {
let mut file = File::open(zkey_path).map_err(|e| MoproError::CircomError(e.to_string()))?;
let zkey = read_zkey(&mut file).map_err(|e| MoproError::CircomError(e.to_string()))?;

// read_arkzkey(arkzkey_path).map_err(|e| MoproError::CircomError(e.to_string()))?;
self.zkey = Some(zkey);

let wtns = WitnessCalculator::new(wasm_path)
.map_err(|e| MoproError::CircomError(e.to_string()))
Expand Down Expand Up @@ -309,7 +315,7 @@ impl CircomState {
println!("Witness generation took: {:.2?}", now.elapsed());

let now = std::time::Instant::now();
let zkey = self.arkzkey.as_ref().ok_or(MoproError::CircomError(
let zkey = self.zkey.as_ref().ok_or(MoproError::CircomError(
"Zkey has not been set up".to_string(),
))?;
println!("Loading arkzkey took: {:.2?}", now.elapsed());
Expand Down Expand Up @@ -339,7 +345,7 @@ impl CircomState {
serialized_inputs: SerializableInputs,
) -> Result<bool, MoproError> {
let start = Instant::now();
let zkey = self.arkzkey.as_ref().ok_or(MoproError::CircomError(
let zkey = self.zkey.as_ref().ok_or(MoproError::CircomError(
"Zkey has not been set up".to_string(),
))?;
let pvk = prepare_verifying_key(&zkey.0.vk);
Expand Down Expand Up @@ -386,12 +392,12 @@ mod tests {
#[test]
fn test_setup_prove_verify_simple() {
let wasm_path = "./examples/circom/multiplier2/target/multiplier2_js/multiplier2.wasm";
let arkzkey_path = "./examples/circom/multiplier2/target/multiplier2_final.arkzkey";
let zkey_path = "./examples/circom/multiplier2/target/multiplier2_final.zkey";
// Instantiate CircomState
let mut circom_state = CircomState::new();

// Setup
let setup_res = circom_state.initialize(arkzkey_path, wasm_path);
let setup_res = circom_state.initialize(zkey_path, wasm_path);
assert!(setup_res.is_ok());

let _serialized_pk = setup_res.unwrap();
Expand Down Expand Up @@ -432,12 +438,12 @@ mod tests {
fn test_setup_prove_verify_keccak() {
let wasm_path =
"./examples/circom/keccak256/target/keccak256_256_test_js/keccak256_256_test.wasm";
let arkzkey_path = "./examples/circom/keccak256/target/keccak256_256_test_final.arkzkey";
let zkey_path = "./examples/circom/keccak256/target/keccak256_256_test_final.zkey";
// Instantiate CircomState
let mut circom_state = CircomState::new();

// Setup
let setup_res = circom_state.initialize(arkzkey_path, wasm_path);
let setup_res = circom_state.initialize(zkey_path, wasm_path);
assert!(setup_res.is_ok());

let _serialized_pk = setup_res.unwrap();
Expand Down Expand Up @@ -485,10 +491,10 @@ mod tests {
let mut circom_state = CircomState::new();

let wasm_path = "badpath/multiplier2.wasm";
let arkzkey_path = "badpath/multiplier2.arkzkey";
let zkey_path = "badpath/multiplier2.zkey";

// Act: Call the setup method
let result = circom_state.initialize(arkzkey_path, wasm_path);
let result = circom_state.initialize(zkey_path, wasm_path);

// Assert: Check that the method returns an error
assert!(result.is_err());
Expand Down Expand Up @@ -558,13 +564,13 @@ mod tests {
#[test]
fn test_setup_prove_rsa() {
let wasm_path = "./examples/circom/rsa/target/main_js/main.wasm";
let arkzkey_path = "./examples/circom/rsa/target/main_final.arkzkey";
let zkey_path = "./examples/circom/rsa/target/main_final.zkey";

// Instantiate CircomState
let mut circom_state = CircomState::new();

// Setup
let setup_res = circom_state.initialize(arkzkey_path, wasm_path);
let setup_res = circom_state.initialize(zkey_path, wasm_path);
assert!(setup_res.is_ok());

let _serialized_pk = setup_res.unwrap();
Expand Down Expand Up @@ -669,13 +675,13 @@ mod tests {
fn test_setup_prove_anon_aadhaar() {
let wasm_path =
"./examples/circom/anonAadhaar/target/aadhaar-verifier_js/aadhaar-verifier.wasm";
let arkzkey_path = "./examples/circom/anonAadhaar/target/aadhaar-verifier_final.arkzkey";
let zkey_path = "./examples/circom/anonAadhaar/target/aadhaar-verifier_final.zkey";

// Instantiate CircomState
let mut circom_state = CircomState::new();

// Setup
let setup_res = circom_state.initialize(arkzkey_path, wasm_path);
let setup_res = circom_state.initialize(zkey_path, wasm_path);
assert!(setup_res.is_ok());

let _serialized_pk = setup_res.unwrap();
Expand Down
17 changes: 8 additions & 9 deletions mopro-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ impl MoproCircom {
}
}

pub fn initialize(&self, arkzkey_path: String, wasm_path: String) -> Result<(), MoproError> {
pub fn initialize(&self, zkey_path: String, wasm_path: String) -> Result<(), MoproError> {
let mut state_guard = self.state.write().unwrap();
state_guard.initialize(arkzkey_path.as_str(), wasm_path.as_str())?;
state_guard.initialize(zkey_path.as_str(), wasm_path.as_str())?;
Ok(())
}

Expand Down Expand Up @@ -320,17 +320,16 @@ mod tests {

#[test]
fn test_end_to_end() -> Result<(), MoproError> {
// Paths to your wasm and arkzkey files
// Paths to your wasm and zkey files
let wasm_path =
"./../mopro-core/examples/circom/multiplier2/target/multiplier2_js/multiplier2.wasm";
let arkzkey_path =
"./../mopro-core/examples/circom/multiplier2/target/multiplier2_final.arkzkey";
let zkey_path = "./../mopro-core/examples/circom/multiplier2/target/multiplier2_final.zkey";

// Create a new MoproCircom instance
let mopro_circom = MoproCircom::new();

// Step 1: Initialize
let init_result = mopro_circom.initialize(arkzkey_path.to_string(), wasm_path.to_string());
let init_result = mopro_circom.initialize(zkey_path.to_string(), wasm_path.to_string());
assert!(init_result.is_ok());

let mut inputs = HashMap::new();
Expand Down Expand Up @@ -374,14 +373,14 @@ mod tests {
// Paths to your wasm and r1cs files
let wasm_path =
"./../mopro-core/examples/circom/keccak256/target/keccak256_256_test_js/keccak256_256_test.wasm";
let arkzkey_path =
"./../mopro-core/examples/circom/keccak256/target/keccak256_256_test_final.arkzkey";
let zkey_path =
"./../mopro-core/examples/circom/keccak256/target/keccak256_256_test_final.zkey";

// Create a new MoproCircom instance
let mopro_circom = MoproCircom::new();

// Step 1: Setup
let setup_result = mopro_circom.initialize(arkzkey_path.to_string(), wasm_path.to_string());
let setup_result = mopro_circom.initialize(zkey_path.to_string(), wasm_path.to_string());
assert!(setup_result.is_ok());

// Prepare inputs
Expand Down
2 changes: 1 addition & 1 deletion mopro-ffi/src/mopro.udl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ interface MoproCircom {
constructor();

[Throws=MoproError]
void initialize(string arkzkey_path, string wasm_path);
void initialize(string zkey_path, string wasm_path);

[Throws=MoproError]
GenerateProofResult generate_proof(record<string, sequence<string>> circuit_inputs);
Expand Down
4 changes: 2 additions & 2 deletions mopro-ffi/tests/bindings/test_mopro.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import uniffi.mopro.*

var wasmPath = "../mopro-core/examples/circom/multiplier2/target/multiplier2_js/multiplier2.wasm"
var arkzkeyPath = "../mopro-core/examples/circom/multiplier2/target/multiplier2_final.arkzkey"
var zkeyPath = "../mopro-core/examples/circom/multiplier2/target/multiplier2_final.zkey"

try {
// Setup
var moproCircom = MoproCircom()
moproCircom.initialize(arkzkeyPath, wasmPath)
moproCircom.initialize(zkeyPath, wasmPath)

// Prepare inputs
val inputs = mutableMapOf<String, List<String>>()
Expand Down
4 changes: 2 additions & 2 deletions mopro-ffi/tests/bindings/test_mopro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Foundation
let moproCircom = MoproCircom()

let wasmPath = "./../../../../mopro-core/examples/circom/multiplier2/target/multiplier2_js/multiplier2.wasm"
let arkzkeyPath = "./../../../../mopro-core/examples/circom/multiplier2/target/multiplier2_final.arkzkey"
let zkeyPath = "./../../../../mopro-core/examples/circom/multiplier2/target/multiplier2_final.zkey"

func serializeOutputs(_ stringArray: [String]) -> [UInt8] {
var bytesArray: [UInt8] = []
Expand Down Expand Up @@ -33,7 +33,7 @@ func serializeOutputs(_ stringArray: [String]) -> [UInt8] {

do {
// Setup
try moproCircom.initialize(arkzkeyPath: arkzkeyPath ,wasmPath: wasmPath)
try moproCircom.initialize(zkeyPath: zkeyPath ,wasmPath: wasmPath)

// Prepare inputs
var inputs = [String: [String]]()
Expand Down
4 changes: 2 additions & 2 deletions mopro-ffi/tests/bindings/test_mopro_keccak.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import uniffi.mopro.*

var wasmPath =
"../mopro-core/examples/circom/keccak256/target/keccak256_256_test_js/keccak256_256_test.wasm"
var arkzkeyPath = "../mopro-core/examples/circom/keccak256/target/keccak256_256_test_final.arkzkey"
var zkeyPath = "../mopro-core/examples/circom/keccak256/target/keccak256_256_test_final.zkey"

try {
var moproCircom = MoproCircom()
moproCircom.initialize(arkzkeyPath, wasmPath)
moproCircom.initialize(zkeyPath, wasmPath)

val inputs = mutableMapOf<String, List<String>>()
inputs["in"] =
Expand Down
Loading
Loading