From 7125cea63faa1044a553af2d5a9785b52db830c3 Mon Sep 17 00:00:00 2001 From: Dmitry Vdovin Date: Fri, 25 Aug 2023 16:12:31 +0400 Subject: [PATCH 1/9] Add "plonk" feature, make r1cs support optional (enabled by default) --- Cargo.toml | 16 ++- src/lib.rs | 6 + src/setup/cli_plonk.rs | 49 ++++++++ src/setup/cli_r1cs.rs | 237 +++++++++++++++++++++++++++++++++++++++ src/setup/main.rs | 248 ++--------------------------------------- tests/circuit.rs | 2 + tests/transaction.rs | 26 ++++- tests/tree.rs | 2 + 8 files changed, 338 insertions(+), 248 deletions(-) create mode 100644 src/setup/cli_plonk.rs create mode 100644 src/setup/cli_r1cs.rs diff --git a/Cargo.toml b/Cargo.toml index 254a1e5..bc53ded 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,11 +14,10 @@ crate-type = ["rlib"] [[bin]] path = "src/setup/main.rs" name = "libzeropool-setup" -required-features = ["cli_libzeropool_setup"] +required-features = ["cli_libzeropool_setup"] [dependencies] -fawkes-crypto = { version = "4.3.3", features = ["rand_support"] } - +fawkes-crypto = { git = "https://github.com/zeropoolnetwork/fawkes-crypto", default-features = false, features = ["rand_support", "borsh_support", "serde_support"] } sha3 = "0.9.1" serde = { version = "1.0", features = ["derive"] } @@ -28,13 +27,18 @@ chacha20poly1305 = "0.8.0" clap={ package = "clap-v3", version = "3.0.0-beta.1", optional=true} convert_case = "0.4.0" +# TODO: Only needed for the Params trait. Reexport in fawkes-crypto. +halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2", tag = "v2022_09_10", optional = true } + [features] in1out127=[] in3out127=[] in7ount127=[] in15out127=[] -cli_libzeropool_setup = ["clap", "fawkes-crypto/rand_support", "fawkes-crypto/backend_bellman_groth16"] -default=["cli_libzeropool_setup", "in3out127"] +cli_libzeropool_setup = ["clap"] +default=["in3out127", "r1cs"] +plonk=["fawkes-crypto/plonk", "halo2_proofs"] +r1cs=["fawkes-crypto/r1cs", "fawkes-crypto/backend_bellman_groth16"] [dev-dependencies] -fawkes-crypto = { version = "4.3.3", features = ["rand_support", "backend_bellman_groth16"] } +fawkes-crypto = { git = "https://github.com/zeropoolnetwork/fawkes-crypto", default-features = false, features = ["rand_support", "borsh_support", "serde_support"] } diff --git a/src/lib.rs b/src/lib.rs index 1bbf856..0a0c4e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,9 @@ +#[cfg(all(feature = "r1cs", feature = "plonk"))] +compile_error!("Features \"r1cs\" and \"plonk\" are mutually exclusive"); + +#[cfg(not(any(feature = "r1cs", feature = "plonk")))] +compile_error!("At least one of features \"r1cs\" and \"plonk\" must be enabled"); + #[macro_use] pub extern crate fawkes_crypto; diff --git a/src/setup/cli_plonk.rs b/src/setup/cli_plonk.rs new file mode 100644 index 0000000..c394dfb --- /dev/null +++ b/src/setup/cli_plonk.rs @@ -0,0 +1,49 @@ +use std::fs::File; + +use clap::Clap; +use fawkes_crypto::{ + backend::plonk::{Parameters, engines::Bn256}, + circuit::cs::CS, +}; +use halo2_proofs::poly::commitment::Params; + +pub fn main() { + let opts: Opts = Opts::parse(); + match opts.command { + SubCommand::Setup(o) => cli_setup(o), + } +} + +fn cli_setup(o:SetupOpts) { + let params_path = o.params.unwrap_or("plonk_params.bin".to_string()); + let params: Parameters = Parameters::setup(o.k); + + let mut fp = File::create(params_path).unwrap(); + params.0.write(&mut fp).unwrap(); + + println!("setup OK"); +} + +#[derive(Clap)] +struct Opts { + #[clap(subcommand)] + command: SubCommand, +} + +#[derive(Clap)] +enum SubCommand { + /// Generate trusted setup parameters + Setup(SetupOpts), +} + +/// A subcommand for generating a trusted setup parameters +#[derive(Clap)] +struct SetupOpts { + /// Snark trusted setup parameters file + #[clap(short = "p", long = "params")] + params: Option, + /// Security parameter + #[clap(short = "k", default_value = "16")] + k: usize, +} + diff --git a/src/setup/cli_r1cs.rs b/src/setup/cli_r1cs.rs new file mode 100644 index 0000000..ffdae8b --- /dev/null +++ b/src/setup/cli_r1cs.rs @@ -0,0 +1,237 @@ + + +use libzeropool::{ + POOL_PARAMS, + circuit::tree::{tree_update, CTreePub, CTreeSec}, + circuit::tx::{c_transfer, CTransferPub, CTransferSec}, + clap::Clap, +}; +use core::panic; +use std::{fs::File, io::Write}; + +use fawkes_crypto::engines::bn256::Fr; +use fawkes_crypto::backend::bellman_groth16::engines::Bn256; +use fawkes_crypto::ff_uint::Num; +use fawkes_crypto::backend::bellman_groth16::{verifier::{VK, verify}, prover::{Proof, prove}, setup::setup, Parameters}; +use crate::evm_verifier::generate_sol_data; +use fawkes_crypto::circuit::cs::CS; +use fawkes_crypto::rand::rngs::OsRng; +use libzeropool::helpers::sample_data::State; +use convert_case::{Case, Casing}; + +#[derive(Clap)] +struct Opts { + #[clap(subcommand)] + command: SubCommand, +} + +#[derive(Clap)] +enum SubCommand { + /// Generate a SNARK proof + Prove(ProveOpts), + /// Verify a SNARK proof + Verify(VerifyOpts), + /// Generate trusted setup parameters + Setup(SetupOpts), + /// Generate verifier smart contract + GenerateVerifier(GenerateVerifierOpts), + /// Generate test object + GenerateTestData(GenerateTestDataOpts), +} + +/// A subcommand for generating a SNARK proof +#[derive(Clap)] +struct ProveOpts { + /// Circuit for prooving (transfer|tree_update) + #[clap(short = "c", long = "circuit", default_value = "transfer")] + circuit: String, + /// Snark trusted setup parameters file + #[clap(short = "p", long = "params")] + params: Option, + /// Input object JSON file + #[clap(short = "o", long = "object")] + object: Option, + /// Output file for proof JSON + #[clap(short = "r", long = "proof")] + proof: Option, + /// Output file for public inputs JSON + #[clap(short = "i", long = "inputs")] + inputs: Option, +} + +/// A subcommand for verifying a SNARK proof +#[derive(Clap)] +struct VerifyOpts { + /// Circuit for verifying (transfer|tree_update) + #[clap(short = "c", long = "circuit", default_value = "transfer")] + circuit: String, + /// Snark verification key + #[clap(short = "v", long = "vk")] + vk: Option, + /// Proof JSON file + #[clap(short = "r", long = "proof")] + proof: Option, + /// Public inputs JSON file + #[clap(short = "i", long = "inputs")] + inputs: Option, +} + +/// A subcommand for generating a trusted setup parameters +#[derive(Clap)] +struct SetupOpts { + /// Circuit for parameter generation (transfer|tree_update) + #[clap(short = "c", long = "circuit", default_value = "transfer")] + circuit: String, + /// Snark trusted setup parameters file + #[clap(short = "p", long = "params")] + params: Option, + /// Snark verifying key file + #[clap(short = "v", long = "vk")] + vk: Option, +} + +/// A subcommand for generating a Solidity verifier smart contract +#[derive(Clap)] +struct GenerateVerifierOpts { + /// Circuit for verifying (transfer|tree_update) + #[clap(short = "c", long = "circuit", default_value = "transfer")] + circuit: String, + /// Snark verification key + #[clap(short = "v", long = "vk")] + vk: Option, + /// Smart contract name + #[clap(short = "n", long = "name")] + contract_name: Option, + /// Output file name + #[clap(short = "s", long = "solidity")] + solidity: Option, +} + +#[derive(Clap)] +struct GenerateTestDataOpts { + /// Circuit for testing (transfer|tree_update) + #[clap(short = "c", long = "circuit", default_value = "transfer")] + circuit: String, + /// Input object JSON file + #[clap(short = "o", long = "object")] + object: Option +} + +fn tree_circuit>(public: CTreePub, secret: CTreeSec) { + tree_update(&public, &secret, &*POOL_PARAMS); +} + +fn tx_circuit>(public: CTransferPub, secret: CTransferSec) { + c_transfer(&public, &secret, &*POOL_PARAMS); +} + +fn cli_setup(o:SetupOpts) { + let params_path = o.params.unwrap_or(format!("{}_params.bin", o.circuit)); + let vk_path = o.vk.unwrap_or(format!("{}_verification_key.json", o.circuit)); + + + let params = match o.circuit.as_str() { + "tree_update" => setup::(tree_circuit), + "transfer" => setup::(tx_circuit), + _ => panic!("Wrong cicruit parameter") + }; + + let vk = params.get_vk(); + let vk_str = serde_json::to_string_pretty(&vk).unwrap(); + + let mut fp = File::create(params_path).unwrap(); + params.write(&mut fp).unwrap(); + std::fs::write(vk_path, &vk_str.into_bytes()).unwrap(); + println!("setup OK"); +} + +fn cli_generate_verifier(o: GenerateVerifierOpts) { + let circuit = o.circuit.clone(); + let vk_path = o.vk.unwrap_or(format!("{}_verification_key.json", circuit)); + let contract_name = o.contract_name.unwrap_or(format!("{}_verifier", circuit).to_case(Case::Pascal)); + let solidity_path = o.solidity.unwrap_or(format!("{}_verifier.sol", circuit)); + + + let vk_str = std::fs::read_to_string(vk_path).unwrap(); + let vk :VK = serde_json::from_str(&vk_str).unwrap(); + let sol_str = generate_sol_data(&vk, contract_name); + File::create(solidity_path).unwrap().write(&sol_str.into_bytes()).unwrap(); + println!("solidity verifier generated") +} + +fn cli_verify(o:VerifyOpts) { + let proof_path = o.proof.unwrap_or(format!("{}_proof.json", o.circuit)); + let vk_path = o.vk.unwrap_or(format!("{}_verification_key.json", o.circuit)); + let inputs_path = o.inputs.unwrap_or(format!("{}_inputs.json", o.circuit)); + + let vk_str = std::fs::read_to_string(vk_path).unwrap(); + let proof_str = std::fs::read_to_string(proof_path).unwrap(); + let public_inputs_str = std::fs::read_to_string(inputs_path).unwrap(); + + let vk:VK = serde_json::from_str(&vk_str).unwrap(); + let proof:Proof = serde_json::from_str(&proof_str).unwrap(); + let public_inputs:Vec> = serde_json::from_str(&public_inputs_str).unwrap(); + + println!("Verify result is {}.", verify(&vk, &proof, &public_inputs)) +} + +fn cli_generate_test_data(o:GenerateTestDataOpts) { + let object_path = o.object.unwrap_or(format!("{}_object.json", o.circuit)); + + match o.circuit.as_str() { + "transfer" => { + let mut rng = OsRng::default(); + let state = State::random_sample_state(&mut rng, &*POOL_PARAMS); + let data = state.random_sample_transfer(&mut rng, &*POOL_PARAMS); + let data_str = serde_json::to_string_pretty(&data).unwrap(); + std::fs::write(object_path, &data_str.into_bytes()).unwrap(); + }, + "tree_update" => std::unimplemented!(), + _ => panic!("Wrong cicruit parameter") + } + + println!("Test data generated") + +} + +fn cli_prove(o:ProveOpts) { + let params_path = o.params.unwrap_or(format!("{}_params.bin", o.circuit)); + let object_path = o.object.unwrap_or(format!("{}_object.json", o.circuit)); + let proof_path = o.proof.unwrap_or(format!("{}_proof.json", o.circuit)); + let inputs_path = o.inputs.unwrap_or(format!("{}_inputs.json", o.circuit)); + + let params_data = std::fs::read(params_path).unwrap(); + let mut params_data_cur = ¶ms_data[..]; + + let params = Parameters::::read(&mut params_data_cur, false, false).unwrap(); + let object_str = std::fs::read_to_string(object_path).unwrap(); + + let (inputs, snark_proof) = if o.circuit.eq("tree_update") { + let (public, secret) = serde_json::from_str(&object_str).unwrap(); + prove(¶ms, &public, &secret, tree_circuit) + } else { + let (public, secret) = serde_json::from_str(&object_str).unwrap(); + prove(¶ms, &public, &secret, tx_circuit) + }; + + + let proof_str = serde_json::to_string_pretty(&snark_proof).unwrap(); + let inputs_str = serde_json::to_string_pretty(&inputs).unwrap(); + + std::fs::write(proof_path, &proof_str.into_bytes()).unwrap(); + std::fs::write(inputs_path, &inputs_str.into_bytes()).unwrap(); + + println!("Proved") +} + + +pub fn main() { + let opts: Opts = Opts::parse(); + match opts.command { + SubCommand::Prove(o) => cli_prove(o), + SubCommand::Verify(o) => cli_verify(o), + SubCommand::Setup(o) => cli_setup(o), + SubCommand::GenerateVerifier(o) => cli_generate_verifier(o), + SubCommand::GenerateTestData(o) => cli_generate_test_data(o) + } +} diff --git a/src/setup/main.rs b/src/setup/main.rs index b0e194d..2f2a085 100644 --- a/src/setup/main.rs +++ b/src/setup/main.rs @@ -1,237 +1,13 @@ +#[cfg(feature = "r1cs")] +mod cli_r1cs; +#[cfg(feature = "r1cs")] mod evm_verifier; - -use libzeropool::{ - POOL_PARAMS, - circuit::tree::{tree_update, CTreePub, CTreeSec}, - circuit::tx::{c_transfer, CTransferPub, CTransferSec}, - clap::Clap, -}; -use core::panic; -use std::{fs::File, io::Write}; - -use fawkes_crypto::engines::bn256::Fr; -use fawkes_crypto::backend::bellman_groth16::engines::Bn256; -use fawkes_crypto::ff_uint::Num; -use fawkes_crypto::backend::bellman_groth16::{verifier::{VK, verify}, prover::{Proof, prove}, setup::setup, Parameters}; -use evm_verifier::generate_sol_data; -use fawkes_crypto::circuit::cs::CS; -use fawkes_crypto::rand::rngs::OsRng; -use libzeropool::helpers::sample_data::State; -use convert_case::{Case, Casing}; - -#[derive(Clap)] -struct Opts { - #[clap(subcommand)] - command: SubCommand, -} - -#[derive(Clap)] -enum SubCommand { - /// Generate a SNARK proof - Prove(ProveOpts), - /// Verify a SNARK proof - Verify(VerifyOpts), - /// Generate trusted setup parameters - Setup(SetupOpts), - /// Generate verifier smart contract - GenerateVerifier(GenerateVerifierOpts), - /// Generate test object - GenerateTestData(GenerateTestDataOpts), -} - -/// A subcommand for generating a SNARK proof -#[derive(Clap)] -struct ProveOpts { - /// Circuit for prooving (transfer|tree_update) - #[clap(short = "c", long = "circuit", default_value = "transfer")] - circuit: String, - /// Snark trusted setup parameters file - #[clap(short = "p", long = "params")] - params: Option, - /// Input object JSON file - #[clap(short = "o", long = "object")] - object: Option, - /// Output file for proof JSON - #[clap(short = "r", long = "proof")] - proof: Option, - /// Output file for public inputs JSON - #[clap(short = "i", long = "inputs")] - inputs: Option, -} - -/// A subcommand for verifying a SNARK proof -#[derive(Clap)] -struct VerifyOpts { - /// Circuit for verifying (transfer|tree_update) - #[clap(short = "c", long = "circuit", default_value = "transfer")] - circuit: String, - /// Snark verification key - #[clap(short = "v", long = "vk")] - vk: Option, - /// Proof JSON file - #[clap(short = "r", long = "proof")] - proof: Option, - /// Public inputs JSON file - #[clap(short = "i", long = "inputs")] - inputs: Option, -} - -/// A subcommand for generating a trusted setup parameters -#[derive(Clap)] -struct SetupOpts { - /// Circuit for parameter generation (transfer|tree_update) - #[clap(short = "c", long = "circuit", default_value = "transfer")] - circuit: String, - /// Snark trusted setup parameters file - #[clap(short = "p", long = "params")] - params: Option, - /// Snark verifying key file - #[clap(short = "v", long = "vk")] - vk: Option, -} - -/// A subcommand for generating a Solidity verifier smart contract -#[derive(Clap)] -struct GenerateVerifierOpts { - /// Circuit for verifying (transfer|tree_update) - #[clap(short = "c", long = "circuit", default_value = "transfer")] - circuit: String, - /// Snark verification key - #[clap(short = "v", long = "vk")] - vk: Option, - /// Smart contract name - #[clap(short = "n", long = "name")] - contract_name: Option, - /// Output file name - #[clap(short = "s", long = "solidity")] - solidity: Option, -} - -#[derive(Clap)] -struct GenerateTestDataOpts { - /// Circuit for testing (transfer|tree_update) - #[clap(short = "c", long = "circuit", default_value = "transfer")] - circuit: String, - /// Input object JSON file - #[clap(short = "o", long = "object")] - object: Option -} - -fn tree_circuit>(public: CTreePub, secret: CTreeSec) { - tree_update(&public, &secret, &*POOL_PARAMS); -} - -fn tx_circuit>(public: CTransferPub, secret: CTransferSec) { - c_transfer(&public, &secret, &*POOL_PARAMS); -} - -fn cli_setup(o:SetupOpts) { - let params_path = o.params.unwrap_or(format!("{}_params.bin", o.circuit)); - let vk_path = o.vk.unwrap_or(format!("{}_verification_key.json", o.circuit)); - - - let params = match o.circuit.as_str() { - "tree_update" => setup::(tree_circuit), - "transfer" => setup::(tx_circuit), - _ => panic!("Wrong cicruit parameter") - }; - - let vk = params.get_vk(); - let vk_str = serde_json::to_string_pretty(&vk).unwrap(); - - let mut fp = File::create(params_path).unwrap(); - params.write(&mut fp).unwrap(); - std::fs::write(vk_path, &vk_str.into_bytes()).unwrap(); - println!("setup OK"); -} - -fn cli_generate_verifier(o: GenerateVerifierOpts) { - let circuit = o.circuit.clone(); - let vk_path = o.vk.unwrap_or(format!("{}_verification_key.json", circuit)); - let contract_name = o.contract_name.unwrap_or(format!("{}_verifier", circuit).to_case(Case::Pascal)); - let solidity_path = o.solidity.unwrap_or(format!("{}_verifier.sol", circuit)); - - - let vk_str = std::fs::read_to_string(vk_path).unwrap(); - let vk :VK = serde_json::from_str(&vk_str).unwrap(); - let sol_str = generate_sol_data(&vk, contract_name); - File::create(solidity_path).unwrap().write(&sol_str.into_bytes()).unwrap(); - println!("solidity verifier generated") -} - -fn cli_verify(o:VerifyOpts) { - let proof_path = o.proof.unwrap_or(format!("{}_proof.json", o.circuit)); - let vk_path = o.vk.unwrap_or(format!("{}_verification_key.json", o.circuit)); - let inputs_path = o.inputs.unwrap_or(format!("{}_inputs.json", o.circuit)); - - let vk_str = std::fs::read_to_string(vk_path).unwrap(); - let proof_str = std::fs::read_to_string(proof_path).unwrap(); - let public_inputs_str = std::fs::read_to_string(inputs_path).unwrap(); - - let vk:VK = serde_json::from_str(&vk_str).unwrap(); - let proof:Proof = serde_json::from_str(&proof_str).unwrap(); - let public_inputs:Vec> = serde_json::from_str(&public_inputs_str).unwrap(); - - println!("Verify result is {}.", verify(&vk, &proof, &public_inputs)) -} - -fn cli_generate_test_data(o:GenerateTestDataOpts) { - let object_path = o.object.unwrap_or(format!("{}_object.json", o.circuit)); - - match o.circuit.as_str() { - "transfer" => { - let mut rng = OsRng::default(); - let state = State::random_sample_state(&mut rng, &*POOL_PARAMS); - let data = state.random_sample_transfer(&mut rng, &*POOL_PARAMS); - let data_str = serde_json::to_string_pretty(&data).unwrap(); - std::fs::write(object_path, &data_str.into_bytes()).unwrap(); - }, - "tree_update" => std::unimplemented!(), - _ => panic!("Wrong cicruit parameter") - } - - println!("Test data generated") - -} - -fn cli_prove(o:ProveOpts) { - let params_path = o.params.unwrap_or(format!("{}_params.bin", o.circuit)); - let object_path = o.object.unwrap_or(format!("{}_object.json", o.circuit)); - let proof_path = o.proof.unwrap_or(format!("{}_proof.json", o.circuit)); - let inputs_path = o.inputs.unwrap_or(format!("{}_inputs.json", o.circuit)); - - let params_data = std::fs::read(params_path).unwrap(); - let mut params_data_cur = ¶ms_data[..]; - - let params = Parameters::::read(&mut params_data_cur, false, false).unwrap(); - let object_str = std::fs::read_to_string(object_path).unwrap(); - - let (inputs, snark_proof) = if o.circuit.eq("tree_update") { - let (public, secret) = serde_json::from_str(&object_str).unwrap(); - prove(¶ms, &public, &secret, tree_circuit) - } else { - let (public, secret) = serde_json::from_str(&object_str).unwrap(); - prove(¶ms, &public, &secret, tx_circuit) - }; - - - let proof_str = serde_json::to_string_pretty(&snark_proof).unwrap(); - let inputs_str = serde_json::to_string_pretty(&inputs).unwrap(); - - std::fs::write(proof_path, &proof_str.into_bytes()).unwrap(); - std::fs::write(inputs_path, &inputs_str.into_bytes()).unwrap(); - - println!("Proved") -} - - -pub fn main() { - let opts: Opts = Opts::parse(); - match opts.command { - SubCommand::Prove(o) => cli_prove(o), - SubCommand::Verify(o) => cli_verify(o), - SubCommand::Setup(o) => cli_setup(o), - SubCommand::GenerateVerifier(o) => cli_generate_verifier(o), - SubCommand::GenerateTestData(o) => cli_generate_test_data(o) - } -} +#[cfg(feature = "plonk")] +mod cli_plonk; + +fn main() { + #[cfg(feature = "r1cs")] + cli_r1cs::main(); + #[cfg(feature = "plonk")] + cli_plonk::main(); +} \ No newline at end of file diff --git a/tests/circuit.rs b/tests/circuit.rs index fa87e84..d26c865 100644 --- a/tests/circuit.rs +++ b/tests/circuit.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "r1cs")] + use fawkes_crypto::circuit::cs::CS; use libzeropool::{ fawkes_crypto::{ diff --git a/tests/transaction.rs b/tests/transaction.rs index 8a695d5..16a89a4 100644 --- a/tests/transaction.rs +++ b/tests/transaction.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "r1cs")] + use libzeropool::{POOL_PARAMS, circuit::tx::{CTransferPub, CTransferSec, c_transfer}, fawkes_crypto::{ circuit::{ @@ -5,15 +7,27 @@ use libzeropool::{POOL_PARAMS, circuit::tx::{CTransferPub, CTransferSec, c_trans }, core::signal::Signal, rand::thread_rng, - backend::bellman_groth16::{ - engines::Bn256, - setup::setup, - prover, - verifier - } + }, }; + +#[cfg(feature = "r1cs")] +use libzeropool::fawkes_crypto::backend::bellman_groth16::{ + engines::Bn256, + setup::setup, + prover, + verifier +}; + +#[cfg(feature = "plonk")] +use libzeropool::fawkes_crypto::backend::plonk::{ + engines::Bn256, + setup::setup, + prover, + verifier +}; + use libzeropool::fawkes_crypto::engines::bn256::Fr; use std::time::Instant; diff --git a/tests/tree.rs b/tests/tree.rs index 68fabec..655775d 100644 --- a/tests/tree.rs +++ b/tests/tree.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "r1cs")] + use fawkes_crypto::rand::Rng; use libzeropool::{POOL_PARAMS, circuit::tree::{CTreePub, CTreeSec, tree_update}, native::tree::{TreePub, TreeSec}, From 9ad4e55b277df53b21fe408a6f5be59d91503896 Mon Sep 17 00:00:00 2001 From: Dmitry Vdovin Date: Thu, 7 Dec 2023 10:30:58 +0400 Subject: [PATCH 2/9] Fixes --- Cargo.toml | 8 ++++---- src/setup/{cli_r1cs.rs => cli_groth16.rs} | 0 src/setup/cli_plonk.rs | 2 +- src/setup/main.rs | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) rename src/setup/{cli_r1cs.rs => cli_groth16.rs} (100%) diff --git a/Cargo.toml b/Cargo.toml index bc53ded..1eee930 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ name = "libzeropool-setup" required-features = ["cli_libzeropool_setup"] [dependencies] -fawkes-crypto = { git = "https://github.com/zeropoolnetwork/fawkes-crypto", default-features = false, features = ["rand_support", "borsh_support", "serde_support"] } +fawkes-crypto = { git = "https://github.com/zeropoolnetwork/fawkes-crypto", branch = "fix/patch-deps-1", default-features = false, features = ["rand_support", "borsh_support", "serde_support"] } sha3 = "0.9.1" serde = { version = "1.0", features = ["derive"] } @@ -36,9 +36,9 @@ in3out127=[] in7ount127=[] in15out127=[] cli_libzeropool_setup = ["clap"] -default=["in3out127", "r1cs"] +default=["in3out127"] plonk=["fawkes-crypto/plonk", "halo2_proofs"] -r1cs=["fawkes-crypto/r1cs", "fawkes-crypto/backend_bellman_groth16"] +groth16=["fawkes-crypto/r1cs", "fawkes-crypto/backend_bellman_groth16"] [dev-dependencies] -fawkes-crypto = { git = "https://github.com/zeropoolnetwork/fawkes-crypto", default-features = false, features = ["rand_support", "borsh_support", "serde_support"] } +fawkes-crypto = { git = "https://github.com/zeropoolnetwork/fawkes-crypto", branch = "fix/patch-deps-1", default-features = false, features = ["rand_support", "borsh_support", "serde_support"] } diff --git a/src/setup/cli_r1cs.rs b/src/setup/cli_groth16.rs similarity index 100% rename from src/setup/cli_r1cs.rs rename to src/setup/cli_groth16.rs diff --git a/src/setup/cli_plonk.rs b/src/setup/cli_plonk.rs index c394dfb..4b9ddd3 100644 --- a/src/setup/cli_plonk.rs +++ b/src/setup/cli_plonk.rs @@ -19,7 +19,7 @@ fn cli_setup(o:SetupOpts) { let params: Parameters = Parameters::setup(o.k); let mut fp = File::create(params_path).unwrap(); - params.0.write(&mut fp).unwrap(); + Params::write(¶ms.0, &mut fp).unwrap(); println!("setup OK"); } diff --git a/src/setup/main.rs b/src/setup/main.rs index 2f2a085..67dcaa6 100644 --- a/src/setup/main.rs +++ b/src/setup/main.rs @@ -1,13 +1,13 @@ -#[cfg(feature = "r1cs")] -mod cli_r1cs; -#[cfg(feature = "r1cs")] +#[cfg(feature = "groth16")] +mod cli_groth16; +#[cfg(feature = "groth16")] mod evm_verifier; #[cfg(feature = "plonk")] mod cli_plonk; fn main() { - #[cfg(feature = "r1cs")] - cli_r1cs::main(); + #[cfg(feature = "groth16")] + cli_groth16::main(); #[cfg(feature = "plonk")] cli_plonk::main(); } \ No newline at end of file From efb16071a494b69a2c91865fae13aa092d7834c8 Mon Sep 17 00:00:00 2001 From: Dmitry Vdovin Date: Mon, 11 Dec 2023 07:34:19 +0400 Subject: [PATCH 3/9] Fix compiler error --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0a0c4e0..7bce080 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ #[cfg(all(feature = "r1cs", feature = "plonk"))] -compile_error!("Features \"r1cs\" and \"plonk\" are mutually exclusive"); +compile_error!("Features \"groth16\" and \"plonk\" are mutually exclusive"); -#[cfg(not(any(feature = "r1cs", feature = "plonk")))] +#[cfg(not(any(feature = "groth16", feature = "plonk")))] compile_error!("At least one of features \"r1cs\" and \"plonk\" must be enabled"); #[macro_use] From 323dfcc524a6dccb2866877ab12023db2226b1d0 Mon Sep 17 00:00:00 2001 From: Dmitry Vdovin Date: Wed, 10 Jan 2024 13:49:31 +0400 Subject: [PATCH 4/9] Fix plonk setup --- Cargo.toml | 16 ++++++++----- src/setup/cli_plonk.rs | 52 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1eee930..acfa5f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ name = "libzeropool-setup" required-features = ["cli_libzeropool_setup"] [dependencies] -fawkes-crypto = { git = "https://github.com/zeropoolnetwork/fawkes-crypto", branch = "fix/patch-deps-1", default-features = false, features = ["rand_support", "borsh_support", "serde_support"] } +fawkes-crypto = { git = "https://github.com/zeropoolnetwork/fawkes-crypto", branch = "fix/plonk-fixes", default-features = false, features = ["rand_support", "borsh_support", "serde_support"] } sha3 = "0.9.1" serde = { version = "1.0", features = ["derive"] } @@ -26,9 +26,7 @@ lazy_static = "1.4.0" chacha20poly1305 = "0.8.0" clap={ package = "clap-v3", version = "3.0.0-beta.1", optional=true} convert_case = "0.4.0" - -# TODO: Only needed for the Params trait. Reexport in fawkes-crypto. -halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2", tag = "v2022_09_10", optional = true } +near-halo2-verifier = { git = "https://github.com/zeropoolnetwork/near-halo2-verifier", branch = "master", optional = true } [features] in1out127=[] @@ -37,8 +35,14 @@ in7ount127=[] in15out127=[] cli_libzeropool_setup = ["clap"] default=["in3out127"] -plonk=["fawkes-crypto/plonk", "halo2_proofs"] +plonk=["fawkes-crypto/plonk", "near-halo2-verifier"] groth16=["fawkes-crypto/r1cs", "fawkes-crypto/backend_bellman_groth16"] [dev-dependencies] -fawkes-crypto = { git = "https://github.com/zeropoolnetwork/fawkes-crypto", branch = "fix/patch-deps-1", default-features = false, features = ["rand_support", "borsh_support", "serde_support"] } +fawkes-crypto = { git = "https://github.com/zeropoolnetwork/fawkes-crypto", branch = "fix/plonk-fixes", default-features = false, features = ["rand_support", "borsh_support", "serde_support"] } + +[patch."https://github.com/privacy-scaling-explorations/halo2curves"] +halo2curves = { git = "https://github.com/zeropoolnetwork/halo2curves", branch = "zeropool-near" } + +[patch.crates-io] +parity-secp256k1 = { git = "https://github.com/paritytech/rust-secp256k1" } \ No newline at end of file diff --git a/src/setup/cli_plonk.rs b/src/setup/cli_plonk.rs index 4b9ddd3..e52a0d2 100644 --- a/src/setup/cli_plonk.rs +++ b/src/setup/cli_plonk.rs @@ -1,11 +1,16 @@ use std::fs::File; +use std::io::Write; use clap::Clap; -use fawkes_crypto::{ - backend::plonk::{Parameters, engines::Bn256}, - circuit::cs::CS, -}; -use halo2_proofs::poly::commitment::Params; +use fawkes_crypto::{backend::plonk::{Parameters, engines::Bn256}, BorshSerialize, circuit::cs::CS}; +use fawkes_crypto::backend::plonk::setup::setup; +use fawkes_crypto::engines::bn256::Fr; +use near_halo2_verifier::bn256::G1Affine; +use near_halo2_verifier::loader::NearLoader; +use near_halo2_verifier::PlonkVerifierData; +use libzeropool::circuit::tree::{CTreePub, CTreeSec, tree_update}; +use libzeropool::circuit::tx::{c_transfer, CTransferPub, CTransferSec}; +use libzeropool::POOL_PARAMS; pub fn main() { let opts: Opts = Opts::parse(); @@ -14,14 +19,43 @@ pub fn main() { } } +fn tree_circuit>(public: CTreePub, secret: CTreeSec) { + tree_update(&public, &secret, &*POOL_PARAMS); +} + +fn tx_circuit>(public: CTransferPub, secret: CTransferSec) { + c_transfer(&public, &secret, &*POOL_PARAMS); +} + fn cli_setup(o:SetupOpts) { let params_path = o.params.unwrap_or("plonk_params.bin".to_string()); - let params: Parameters = Parameters::setup(o.k); - let mut fp = File::create(params_path).unwrap(); - Params::write(¶ms.0, &mut fp).unwrap(); + let params = if !std::path::Path::new(¶ms_path).exists() { + let params: Parameters = Parameters::setup(o.k); + println!("setup OK"); + let mut fp = File::create(params_path).unwrap(); + params.write(&mut fp).unwrap(); + params + } else { + let mut fp = File::open(params_path).unwrap(); + Parameters::read(&mut fp).unwrap() + }; + + let (vk, _) = setup(¶ms, tree_circuit); + let tree_vd = PlonkVerifierData::new(params.0.clone(), vk.0, o.k); + let tree_vd_bytes = tree_vd.try_to_vec().unwrap(); + let mut fp = File::create("tree_vd.bin").unwrap(); + fp.write_all(&tree_vd_bytes).unwrap(); + + println!("tree OK"); + + let (vk, _) = setup(¶ms, tx_circuit); + let tx_vd = PlonkVerifierData::new(params.0.clone(), vk.0, o.k); + let tx_vd_bytes = tx_vd.try_to_vec().unwrap(); + let mut fp = File::create("tx_vd.bin").unwrap(); + fp.write_all(&tx_vd_bytes).unwrap(); - println!("setup OK"); + println!("tx OK"); } #[derive(Clap)] From cb56f8c816f74350537458bcee87a5f716d5ba77 Mon Sep 17 00:00:00 2001 From: Dmitry Vdovin Date: Fri, 12 Jan 2024 15:43:37 +0400 Subject: [PATCH 5/9] Fix vk file names --- src/setup/cli_plonk.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/setup/cli_plonk.rs b/src/setup/cli_plonk.rs index e52a0d2..a82d7a5 100644 --- a/src/setup/cli_plonk.rs +++ b/src/setup/cli_plonk.rs @@ -5,8 +5,6 @@ use clap::Clap; use fawkes_crypto::{backend::plonk::{Parameters, engines::Bn256}, BorshSerialize, circuit::cs::CS}; use fawkes_crypto::backend::plonk::setup::setup; use fawkes_crypto::engines::bn256::Fr; -use near_halo2_verifier::bn256::G1Affine; -use near_halo2_verifier::loader::NearLoader; use near_halo2_verifier::PlonkVerifierData; use libzeropool::circuit::tree::{CTreePub, CTreeSec, tree_update}; use libzeropool::circuit::tx::{c_transfer, CTransferPub, CTransferSec}; @@ -44,7 +42,7 @@ fn cli_setup(o:SetupOpts) { let (vk, _) = setup(¶ms, tree_circuit); let tree_vd = PlonkVerifierData::new(params.0.clone(), vk.0, o.k); let tree_vd_bytes = tree_vd.try_to_vec().unwrap(); - let mut fp = File::create("tree_vd.bin").unwrap(); + let mut fp = File::create("tree_vk.bin").unwrap(); fp.write_all(&tree_vd_bytes).unwrap(); println!("tree OK"); @@ -52,7 +50,7 @@ fn cli_setup(o:SetupOpts) { let (vk, _) = setup(¶ms, tx_circuit); let tx_vd = PlonkVerifierData::new(params.0.clone(), vk.0, o.k); let tx_vd_bytes = tx_vd.try_to_vec().unwrap(); - let mut fp = File::create("tx_vd.bin").unwrap(); + let mut fp = File::create("tx_vk.bin").unwrap(); fp.write_all(&tx_vd_bytes).unwrap(); println!("tx OK"); From 84b5de519a343685ab346a4db6145cfdd9ab740b Mon Sep 17 00:00:00 2001 From: Dmitry Vdovin Date: Fri, 12 Jan 2024 15:48:11 +0400 Subject: [PATCH 6/9] Change default value for k to 20 --- src/setup/cli_plonk.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/setup/cli_plonk.rs b/src/setup/cli_plonk.rs index a82d7a5..6889c27 100644 --- a/src/setup/cli_plonk.rs +++ b/src/setup/cli_plonk.rs @@ -75,7 +75,7 @@ struct SetupOpts { #[clap(short = "p", long = "params")] params: Option, /// Security parameter - #[clap(short = "k", default_value = "16")] + #[clap(short = "k", default_value = "20")] k: usize, } From 6d0507fdfc6b5b8ad9863a79083fd302403fbef9 Mon Sep 17 00:00:00 2001 From: Dmitry Vdovin Date: Sun, 21 Jan 2024 02:45:11 +0400 Subject: [PATCH 7/9] Implement VK/PK serialization for plonk --- src/setup/cli_plonk.rs | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/setup/cli_plonk.rs b/src/setup/cli_plonk.rs index 6889c27..22d7ea8 100644 --- a/src/setup/cli_plonk.rs +++ b/src/setup/cli_plonk.rs @@ -39,18 +39,40 @@ fn cli_setup(o:SetupOpts) { Parameters::read(&mut fp).unwrap() }; - let (vk, _) = setup(¶ms, tree_circuit); + let (vk, pk) = setup(¶ms, tree_circuit); + + let mut buf = Vec::new(); + vk.write(&mut buf).unwrap(); + let mut fp = File::create("tree_vk.bin").unwrap(); + fp.write_all(&buf).unwrap(); + + let mut buf = Vec::new(); + pk.write(&mut buf).unwrap(); + let mut fp = File::create("tree_pk.bin").unwrap(); + fp.write_all(&buf).unwrap(); + let tree_vd = PlonkVerifierData::new(params.0.clone(), vk.0, o.k); let tree_vd_bytes = tree_vd.try_to_vec().unwrap(); - let mut fp = File::create("tree_vk.bin").unwrap(); + let mut fp = File::create("tree_vd.bin").unwrap(); fp.write_all(&tree_vd_bytes).unwrap(); println!("tree OK"); - let (vk, _) = setup(¶ms, tx_circuit); + let (vk, pk) = setup(¶ms, tx_circuit); + + let mut buf = Vec::new(); + vk.write(&mut buf).unwrap(); + let mut fp = File::create("transfer_vk.bin").unwrap(); + fp.write_all(&buf).unwrap(); + + let mut buf = Vec::new(); + pk.write(&mut buf).unwrap(); + let mut fp = File::create("transfer_pk.bin").unwrap(); + fp.write_all(&buf).unwrap(); + let tx_vd = PlonkVerifierData::new(params.0.clone(), vk.0, o.k); let tx_vd_bytes = tx_vd.try_to_vec().unwrap(); - let mut fp = File::create("tx_vk.bin").unwrap(); + let mut fp = File::create("transfer_vd.bin").unwrap(); fp.write_all(&tx_vd_bytes).unwrap(); println!("tx OK"); From 3419809f0da859326e3a3b3db985f251ae6e02cb Mon Sep 17 00:00:00 2001 From: Dmitry Vdovin Date: Fri, 2 Feb 2024 00:54:36 +0400 Subject: [PATCH 8/9] Fix plonk key setup --- src/setup/cli_plonk.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/setup/cli_plonk.rs b/src/setup/cli_plonk.rs index 22d7ea8..64a9e02 100644 --- a/src/setup/cli_plonk.rs +++ b/src/setup/cli_plonk.rs @@ -51,7 +51,7 @@ fn cli_setup(o:SetupOpts) { let mut fp = File::create("tree_pk.bin").unwrap(); fp.write_all(&buf).unwrap(); - let tree_vd = PlonkVerifierData::new(params.0.clone(), vk.0, o.k); + let tree_vd = PlonkVerifierData::new(params.0.clone(), vk.0, 3); let tree_vd_bytes = tree_vd.try_to_vec().unwrap(); let mut fp = File::create("tree_vd.bin").unwrap(); fp.write_all(&tree_vd_bytes).unwrap(); @@ -70,7 +70,7 @@ fn cli_setup(o:SetupOpts) { let mut fp = File::create("transfer_pk.bin").unwrap(); fp.write_all(&buf).unwrap(); - let tx_vd = PlonkVerifierData::new(params.0.clone(), vk.0, o.k); + let tx_vd = PlonkVerifierData::new(params.0.clone(), vk.0, 5); let tx_vd_bytes = tx_vd.try_to_vec().unwrap(); let mut fp = File::create("transfer_vd.bin").unwrap(); fp.write_all(&tx_vd_bytes).unwrap(); From 8c03dfedc2aaec33b59fae0105304883937a8fbc Mon Sep 17 00:00:00 2001 From: Dmitry Vdovin Date: Fri, 2 Feb 2024 00:55:13 +0400 Subject: [PATCH 9/9] Add cli_libzeropool_setup_plonk feature --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index acfa5f1..aede873 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,8 +34,9 @@ in3out127=[] in7ount127=[] in15out127=[] cli_libzeropool_setup = ["clap"] +cli_libzeropool_setup_plonk = ["cli_libzeropool_setup", "plonk", "near-halo2-verifier"] default=["in3out127"] -plonk=["fawkes-crypto/plonk", "near-halo2-verifier"] +plonk=["fawkes-crypto/plonk"] groth16=["fawkes-crypto/r1cs", "fawkes-crypto/backend_bellman_groth16"] [dev-dependencies]