diff --git a/Cargo.toml b/Cargo.toml index 893e792b..c5b6a1a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,10 @@ [workspace] members = [ "taiga_halo2", - # "taiga_zk_garage", ] resolver = "2" [patch.crates-io] -# ark-serialize = { git="https://github.com/simonmasson/algebra", rev="e2ea75c" } -# ark-ff = { git="https://github.com/simonmasson/algebra", rev="e2ea75c" } -# ark-ec = { git="https://github.com/simonmasson/algebra", rev="e2ea75c" } halo2_gadgets = { git = "https://github.com/heliaxdev/halo2", branch = "taiga" } halo2_proofs = { git = "https://github.com/heliaxdev/halo2", branch = "taiga" } pasta_curves = { git = "https://github.com/heliaxdev/pasta_curves", branch = "taiga" } diff --git a/taiga_zk_garage/Cargo.toml b/taiga_zk_garage/Cargo.toml deleted file mode 100644 index d3f4bae0..00000000 --- a/taiga_zk_garage/Cargo.toml +++ /dev/null @@ -1,41 +0,0 @@ -[package] -name = "taiga_zk_garage" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -ark-serialize = { version = "^0.3.0", default-features = false } -ark-ff = { git="https://github.com/simonmasson/algebra", rev="e2ea75c" } -ark-ec = { git="https://github.com/simonmasson/algebra", rev="e2ea75c" } -ark-poly-commit = "0.3" -ark-poly = "0.3" -ark-bls12-381-new = { git="https://github.com/simonmasson/curves/", branch="new-pairing-layer" } -ark-ed-on-bls12-381-new = { git="https://github.com/simonmasson/curves/", branch="new-pairing-layer" } -ark-bw6-764-new = { git="https://github.com/simonmasson/curves/", branch="new-pairing-layer" } - -rand = "0.8.4" -sha2 = "0.10.1" -plonk-core = { git = "https://github.com/heliaxdev/ark-plonk/", features = ["trace"], branch="taiga/randomized-circuits-rebase" } -plonk-hashing = { git = "https://github.com/heliaxdev/ark-plonk/", branch="taiga/randomized-circuits-rebase" } -blake2 = "0.9" -lazy_static = "1" -derivative = { version = "2", features = ["use_core"] } -thiserror = "1" -blake2b_simd = "1" -ark-std = "0.3" -rand_core = {version = "0.6", default-features=false, features = ["getrandom"] } - -[dev-dependencies] -ark-std = "0.3" -criterion = "0.3" -proptest = "1.0.0" - -# [[bench]] -# name = "action_proof" -# harness = false - -[[bench]] -name = "vp_proof" -harness = false diff --git a/taiga_zk_garage/Performance.md b/taiga_zk_garage/Performance.md deleted file mode 100644 index d1c96948..00000000 --- a/taiga_zk_garage/Performance.md +++ /dev/null @@ -1,56 +0,0 @@ -# NUM_NOTE = 4 - -``` -Compile: -VP(2^17)-compile_with_blinding secs: 17, nanos: 505948000 -Action(2^15) secs: 4, nanos: 975182000 -Blind VP(2^15) secs: 17, nanos: 505948000 - -Prove: -VP(2^17) secs: 17, nanos: 735556000 -Action(2^15) secs: 4, nanos: 678785000 -Blind VP(2^15) secs: 19, nanos: 338197000 - -Verify -VP(2^17) secs: 0, nanos: 14212000 -Action(2^15) secs: 0, nanos: 9618000 -Blind VP(2^15) secs: 0, nanos: 43840000 -``` - -``` -tx(4 actions, 16 vps, 16 vp blinds) -tx prove+vp compile: secs: 1160, nanos: 198469000 -verify: secs: 0, nanos: 844403000 -``` - -# NUM_NOTE = 3 - -``` -Compile: -VP(2^16)-compile_with_blinding secs: 10, nanos: 87050000 - -Prove: -VP(2^16) secs: 10, nanos: 71476000 -``` - -``` -tx(2 actions, 8 vps, 8 vp blinds) -tx prove+vp compile: secs: 591, nanos: 227595000 -verify: secs: 0, nanos: 587065000 -``` - -# NUM_NOTE = 2 - -``` -Compile: -VP(2^16)-compile_with_blinding secs: 9, nanos: 987286000 - -Prove: -VP(2^16) secs: 9, nanos: 946505000 -``` - -``` -tx(2 actions, 8 vps, 8 vp blinds) -tx prove+vp compile: secs: 436, nanos: 500172000 -verify: secs: 0, nanos: 555699000 -``` \ No newline at end of file diff --git a/taiga_zk_garage/benches/action_proof.rs b/taiga_zk_garage/benches/action_proof.rs deleted file mode 100644 index 361b67fd..00000000 --- a/taiga_zk_garage/benches/action_proof.rs +++ /dev/null @@ -1,74 +0,0 @@ -use criterion::{criterion_group, criterion_main, Criterion}; -use plonk_core::circuit::{verify_proof, VerifierData}; -use plonk_core::prelude::Circuit; -use plonk_core::proof_system::pi::PublicInputs; -use rand::rngs::OsRng; -use taiga_zk_garage::action::ActionInfo; -use taiga_zk_garage::circuit::circuit_parameters::CircuitParameters; -use taiga_zk_garage::circuit::circuit_parameters::PairingCircuitParameters as CP; -use taiga_zk_garage::constant::ACTION_CIRCUIT_SIZE; -use taiga_zk_garage::constant::ACTION_PUBLIC_INPUT_NF_INDEX; - -fn bench_action_proof(name: &str, c: &mut Criterion) { - type Fr = ::CurveScalarField; - type P = ::InnerCurve; - type PC = ::CurvePC; - - let mut rng = OsRng; - let action_info = ActionInfo::::dummy(&mut rng); - let (action, mut action_circuit) = action_info.build(&mut rng).unwrap(); - - // Generate CRS - let pp = CP::get_pc_setup_params(ACTION_CIRCUIT_SIZE); - - // Compile the circuit - let pk = CP::get_action_pk(); - let vk = CP::get_action_vk(); - - // Prover bench - let prover_name = name.to_string() + "-prover"; - c.bench_function(&prover_name, |b| { - b.iter(|| { - action_circuit - .gen_proof::(pp, pk.clone(), b"Test") - .unwrap(); - }) - }); - let (proof, action_public_input) = action_circuit - .gen_proof::(pp, pk.clone(), b"Test") - .unwrap(); - - // Verifier bench - let verifier_name = name.to_string() + "-verifier"; - c.bench_function(&verifier_name, |b| { - b.iter(|| { - let mut expect_public_input = PublicInputs::new(); - expect_public_input.insert(ACTION_PUBLIC_INPUT_NF_INDEX, action.nf.inner()); - expect_public_input.insert(ACTION_PUBLIC_INPUT_NF_INDEX, action.root); - expect_public_input.insert(ACTION_PUBLIC_INPUT_NF_INDEX, action.cm.inner()); - assert_eq!(action_public_input, expect_public_input); - let verifier_data = VerifierData::new(vk.clone(), expect_public_input); - assert!(verify_proof::( - pp, - verifier_data.key, - &proof, - &verifier_data.pi, - b"Test" - ) - .is_ok()); - }) - }); - let mut expect_public_input = PublicInputs::new(); - expect_public_input.insert(ACTION_PUBLIC_INPUT_NF_INDEX, action.nf.inner()); - expect_public_input.insert(ACTION_PUBLIC_INPUT_NF_INDEX, action.root); - expect_public_input.insert(ACTION_PUBLIC_INPUT_NF_INDEX, action.cm.inner()); - assert_eq!(action_public_input, expect_public_input); - let verifier_data = VerifierData::new(vk.clone(), expect_public_input); - verify_proof::(pp, verifier_data.key, &proof, &verifier_data.pi, b"Test").unwrap(); -} -fn criterion_benchmark(c: &mut Criterion) { - bench_action_proof("zk-garage-action-proof", c); -} - -criterion_group!(benches, criterion_benchmark); -criterion_main!(benches); diff --git a/taiga_zk_garage/benches/vp_proof.rs b/taiga_zk_garage/benches/vp_proof.rs deleted file mode 100644 index da2b451b..00000000 --- a/taiga_zk_garage/benches/vp_proof.rs +++ /dev/null @@ -1,78 +0,0 @@ -use criterion::{criterion_group, criterion_main, Criterion}; -use plonk_core::{ - circuit::{verify_proof, VerifierData}, - prelude::{Circuit, StandardComposer}, -}; -use rand::rngs::OsRng; -use taiga_zk_garage::app::App; -use taiga_zk_garage::circuit::circuit_parameters::PairingCircuitParameters as CP; -use taiga_zk_garage::circuit::validity_predicate::NUM_NOTE; -use taiga_zk_garage::{ - circuit::{ - circuit_parameters::CircuitParameters, vp_examples::balance::BalanceValidityPredicate, - }, - note::Note, -}; -type Fr = ::CurveScalarField; -type P = ::InnerCurve; -type PC = ::CurvePC; - -fn bench_vp_proof(name: &str, c: &mut Criterion) { - let mut rng = OsRng; - - let xan = App::::dummy(&mut rng); - // input notes - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy_from_app(xan.clone(), &mut rng)); - // output notes - let mut output_notes = input_notes.clone(); - let tmp = output_notes[0].value; - output_notes[0].value = output_notes[1].value; - output_notes[1].value = tmp; - - let mut balance_vp = BalanceValidityPredicate::new(input_notes, output_notes); - - let mut composer = StandardComposer::::new(); - balance_vp.gadget(&mut composer).unwrap(); - composer.check_circuit_satisfied(); - - let pp = CP::get_pc_setup_params(balance_vp.padded_circuit_size()); - let (pk, vk) = balance_vp.compile::(pp).unwrap(); - - // Prover bench - // ! TOO SLOW ! - // let prover_name = name.to_string() + "-prover"; - // c.bench_function(&prover_name, |b| { - // b.iter(|| { - // balance_vp.gen_proof::(pp, pk.clone(), b"Test").unwrap(); - // }) - // }); - let (proof, public_input) = balance_vp.gen_proof::(pp, pk, b"Test").unwrap(); - - // Verifier bench - let verifier_name = name.to_string() + "-verifier"; - c.bench_function(&verifier_name, |b| { - b.iter(|| { - let verifier_data = VerifierData::new(vk.clone(), public_input.clone()); - assert!(verify_proof::( - pp, - verifier_data.key, - &proof, - &verifier_data.pi, - b"Test" - ) - .is_ok()); - }) - }); - let verifier_data = VerifierData::new(vk, public_input); - assert!( - verify_proof::(pp, verifier_data.key, &proof, &verifier_data.pi, b"Test") - .is_ok() - ); -} - -fn criterion_benchmark(c: &mut Criterion) { - bench_vp_proof("zk-garage-vp-proof", c); -} - -criterion_group!(benches, criterion_benchmark); -criterion_main!(benches); diff --git a/taiga_zk_garage/src/action.rs b/taiga_zk_garage/src/action.rs deleted file mode 100644 index dc68bf6f..00000000 --- a/taiga_zk_garage/src/action.rs +++ /dev/null @@ -1,166 +0,0 @@ -use crate::app::App; -use crate::circuit::action_circuit::ActionCircuit; -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::error::TaigaError; -use crate::merkle_tree::{MerklePath, Node, TAIGA_COMMITMENT_TREE_DEPTH}; -use crate::note::{Note, NoteCommitment}; -use crate::nullifier::Nullifier; -use crate::poseidon::{FieldHasher, WIDTH_3}; -use crate::user::{User, UserSendAddress}; -use crate::vp_description::ValidityPredicateDescription; -use ark_ff::UniformRand; -use plonk_hashing::poseidon::constants::PoseidonConstants; -use rand::RngCore; - -/// The action result used in transaction. -#[derive(Copy, Debug, Clone)] -pub struct Action { - /// The root of the note commitment Merkle tree. - pub root: CP::CurveScalarField, - /// The nullifier of the spend note. - pub nf: Nullifier, - /// The commitment of the output note. - pub cm: NoteCommitment, - // TODO: The EncryptedNote. - // encrypted_note, -} - -/// The information to build Action and ActionCircuit. -#[derive(Debug, Clone)] -pub struct ActionInfo { - spend: SpendInfo, - output: OutputInfo, -} - -#[derive(Debug, Clone)] -pub struct SpendInfo { - note: Note, - auth_path: [(CP::CurveScalarField, bool); TAIGA_COMMITMENT_TREE_DEPTH], - root: CP::CurveScalarField, -} - -#[derive(Debug, Clone)] -pub struct OutputInfo { - addr_send_closed: UserSendAddress, - addr_recv_vp: ValidityPredicateDescription, - addr_app_vp: ValidityPredicateDescription, - value: u64, - data: CP::CurveScalarField, -} - -impl ActionInfo { - pub fn new(spend: SpendInfo, output: OutputInfo) -> Self { - Self { spend, output } - } - - pub fn dummy(rng: &mut impl RngCore) -> Self { - let spend_note = Note::::dummy(rng); - let merkle_path = - MerklePath::>::dummy( - rng, - TAIGA_COMMITMENT_TREE_DEPTH, - ); - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - let spend_info = SpendInfo::::new(spend_note, merkle_path, &poseidon_param); - - let output_info = OutputInfo::::dummy(rng); - - ActionInfo::::new(spend_info, output_info) - } - - pub fn build( - self, - rng: &mut impl RngCore, - ) -> Result<(Action, ActionCircuit), TaigaError> { - let spend_cm = self.spend.note.commitment()?; - let nk = self.spend.note.user.send_com.get_nk().unwrap(); - let nf = Nullifier::::derive_native( - &nk, - &self.spend.note.rho, - &self.spend.note.psi, - &spend_cm, - ); - - let user = User:: { - send_com: self.output.addr_send_closed, - recv_vp: self.output.addr_recv_vp, - }; - let app = App:: { - app_vp: self.output.addr_app_vp, - }; - - let note_rcm = CP::CurveScalarField::rand(rng); - let output_note = Note::new(user, app, self.output.value, nf, self.output.data, note_rcm); - - let output_cm = output_note.commitment()?; - let action = Action:: { - nf, - cm: output_cm, - root: self.spend.root, - }; - - let action_circuit = ActionCircuit:: { - spend_note: self.spend.note, - auth_path: self.spend.auth_path, - output_note, - }; - - Ok((action, action_circuit)) - } -} - -impl SpendInfo { - pub fn new( - note: Note, - merkle_path: MerklePath, - hasher: &BH, - ) -> Self - where - BH: FieldHasher, - { - let cm_node = Node::::new(note.commitment().unwrap().inner()); - let root = merkle_path.root(cm_node, hasher).unwrap().inner(); - let auth_path: [(CP::CurveScalarField, bool); TAIGA_COMMITMENT_TREE_DEPTH] = - merkle_path.get_path().as_slice().try_into().unwrap(); - Self { - note, - auth_path, - root, - } - } -} - -impl OutputInfo { - pub fn new( - addr_send_closed: UserSendAddress, - addr_recv_vp: ValidityPredicateDescription, - addr_app_vp: ValidityPredicateDescription, - value: u64, - data: CP::CurveScalarField, - ) -> Self { - Self { - addr_send_closed, - addr_recv_vp, - addr_app_vp, - value, - data, - } - } - - pub fn dummy(rng: &mut impl RngCore) -> Self { - use rand::Rng; - let addr_send_closed = UserSendAddress::::from_closed(CP::CurveScalarField::rand(rng)); - let addr_recv_vp = ValidityPredicateDescription::::dummy(rng); - let addr_app_vp = ValidityPredicateDescription::::dummy(rng); - let value: u64 = rng.gen(); - let data = CP::CurveScalarField::rand(rng); - Self { - addr_send_closed, - addr_recv_vp, - addr_app_vp, - value, - data, - } - } -} diff --git a/taiga_zk_garage/src/app.rs b/taiga_zk_garage/src/app.rs deleted file mode 100644 index 0ddd2c96..00000000 --- a/taiga_zk_garage/src/app.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::error::TaigaError; -use crate::poseidon::{FieldHasher, WIDTH_3}; -use crate::utils::bits_to_fields; -use crate::vp_description::ValidityPredicateDescription; -use plonk_hashing::poseidon::constants::PoseidonConstants; -use rand::RngCore; - -#[derive(Debug, Clone)] -pub struct App { - pub app_vp: ValidityPredicateDescription, -} - -impl App { - pub fn new(app_vp_description: ValidityPredicateDescription) -> Self { - Self { - app_vp: app_vp_description, - } - } - - pub fn dummy(rng: &mut impl RngCore) -> Self { - Self { - app_vp: ValidityPredicateDescription::dummy(rng), - } - } - - pub fn address(&self) -> Result { - // Init poseidon param. - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - - let address_fields = bits_to_fields::(&self.app_vp.to_bits()); - poseidon_param.native_hash_two(&address_fields[0], &address_fields[1]) - } -} - -#[test] -fn app_address_computation() { - let mut rng = ark_std::test_rng(); - let xan = App::::dummy(&mut rng); - xan.address().unwrap(); -} diff --git a/taiga_zk_garage/src/circuit.rs b/taiga_zk_garage/src/circuit.rs deleted file mode 100644 index feb7bf85..00000000 --- a/taiga_zk_garage/src/circuit.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod action_circuit; -pub mod blinding_circuit; -pub mod circuit_parameters; -pub mod gadgets; -pub mod integrity; -pub mod validity_predicate; -pub mod vp_examples; diff --git a/taiga_zk_garage/src/circuit/action_circuit.rs b/taiga_zk_garage/src/circuit/action_circuit.rs deleted file mode 100644 index 165240fc..00000000 --- a/taiga_zk_garage/src/circuit/action_circuit.rs +++ /dev/null @@ -1,111 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::circuit::gadgets::merkle_tree::merkle_tree_gadget; -use crate::circuit::integrity::{input_note_constraint, output_note_constraint}; -use crate::constant::ACTION_CIRCUIT_SIZE; -use crate::merkle_tree::TAIGA_COMMITMENT_TREE_DEPTH; -use crate::note::Note; -use crate::poseidon::WIDTH_3; -use plonk_core::{circuit::Circuit, constraint_system::StandardComposer}; -use plonk_hashing::poseidon::constants::PoseidonConstants; - -/// Action circuit -#[derive(Debug, Clone)] -pub struct ActionCircuit { - /// Spent note - pub spend_note: Note, - pub auth_path: [(CP::CurveScalarField, bool); TAIGA_COMMITMENT_TREE_DEPTH], - /// Output note - pub output_note: Note, -} - -impl Circuit for ActionCircuit -where - CP: CircuitParameters, -{ - const CIRCUIT_ID: [u8; 32] = [0xff; 32]; - - fn gadget( - &mut self, - composer: &mut StandardComposer, - ) -> Result<(), plonk_core::prelude::Error> { - // spent note - let nf = { - let input_note_var = input_note_constraint(&self.spend_note, composer)?; - // check merkle tree and publish root - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - let root = merkle_tree_gadget::< - CP::CurveScalarField, - CP::InnerCurve, - PoseidonConstants, - >( - composer, - &input_note_var.cm, - &self.auth_path, - &poseidon_param, - )?; - composer.public_inputize(&root); - - // TODO: user send address VP commitment and app VP commitment - input_note_var.nf - }; - - // output note - { - let _output_note_var = output_note_constraint(&self.output_note, &nf, composer)?; - - // TODO: add user receive address VP commitment and app VP commitment - - // TODO: add note encryption - } - - composer.check_circuit_satisfied(); - println!("circuit size: {}", composer.circuit_bound()); - - Ok(()) - } - fn padded_circuit_size(&self) -> usize { - ACTION_CIRCUIT_SIZE - } -} - -#[test] -fn action_circuit_test() { - use crate::circuit::circuit_parameters::{CircuitParameters, PairingCircuitParameters as CP}; - type Fr = ::CurveScalarField; - type P = ::InnerCurve; - type PC = ::CurvePC; - use crate::action::*; - use crate::constant::{ - ACTION_PUBLIC_INPUT_CM_INDEX, ACTION_PUBLIC_INPUT_NF_INDEX, ACTION_PUBLIC_INPUT_ROOT_INDEX, - }; - use ark_std::test_rng; - use plonk_core::circuit::{verify_proof, VerifierData}; - use plonk_core::proof_system::pi::PublicInputs; - - let mut rng = test_rng(); - let action_info = ActionInfo::::dummy(&mut rng); - let (action, mut action_circuit) = action_info.build(&mut rng).unwrap(); - - // Generate CRS - let pp = CP::get_pc_setup_params(ACTION_CIRCUIT_SIZE); - - // Compile the circuit - let pk = CP::get_action_pk(); - let vk = CP::get_action_vk(); - - // Prover - let (proof, action_public_input) = action_circuit - .gen_proof::(pp, pk.clone(), b"Test") - .unwrap(); - - // Check the public inputs - let mut expect_public_input = PublicInputs::new(); - expect_public_input.insert(ACTION_PUBLIC_INPUT_NF_INDEX, action.nf.inner()); - expect_public_input.insert(ACTION_PUBLIC_INPUT_ROOT_INDEX, action.root); - expect_public_input.insert(ACTION_PUBLIC_INPUT_CM_INDEX, action.cm.inner()); - assert_eq!(action_public_input, expect_public_input); - // Verifier - let verifier_data = VerifierData::new(vk.clone(), expect_public_input); - verify_proof::(pp, verifier_data.key, &proof, &verifier_data.pi, b"Test").unwrap(); -} diff --git a/taiga_zk_garage/src/circuit/blinding_circuit.rs b/taiga_zk_garage/src/circuit/blinding_circuit.rs deleted file mode 100644 index f1dfef6a..00000000 --- a/taiga_zk_garage/src/circuit/blinding_circuit.rs +++ /dev/null @@ -1,243 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::circuit::vp_examples::field_addition::FieldAdditionValidityPredicate; -use crate::constant::BLINDING_CIRCUIT_SIZE; -use crate::poseidon::WIDTH_9; -use crate::vp_description::ValidityPredicateDescription; -use ark_ec::twisted_edwards_extended::GroupAffine as TEGroupAffine; -use ark_ff::UniformRand; -use ark_ff::{BigInteger, PrimeField}; -use ark_poly::univariate::DensePolynomial; -use ark_poly_commit::PolynomialCommitment; - -use plonk_core::{ - circuit::Circuit, constraint_system::StandardComposer, prelude::Error, prelude::Variable, - proof_system::Blinding, -}; -use plonk_hashing::poseidon::{ - constants::PoseidonConstants, - poseidon::{PlonkSpec, Poseidon}, -}; -use rand::RngCore; -const BLINDING_PC_NUM: usize = 6; - -pub struct BlindingCircuit { - vp_desc: ValidityPredicateDescription, - blinding: Blinding, - zh: [CP::CurveBaseField; 2], -} - -impl Circuit for BlindingCircuit -where - CP: CircuitParameters, -{ - const CIRCUIT_ID: [u8; 32] = [0x01; 32]; - - // Default implementation - fn gadget( - &mut self, - composer: &mut StandardComposer, - ) -> Result<(), Error> { - // parse the public inputs (todo is Com(Z_H) a public input?) - let com_z_h = TEGroupAffine::::new(self.zh[0], self.zh[1]); - - let blind_vec = vec![ - self.blinding.q_m, - self.blinding.q_l, - self.blinding.q_r, - self.blinding.q_o, - self.blinding.q_4, - self.blinding.q_c, - ]; - assert_eq!(blind_vec.len(), BLINDING_PC_NUM); - let vp_desc = self.vp_desc.get_pack().unwrap(); - - // Constrain vp blinding - for (point, blind) in vp_desc[0..2 * BLINDING_PC_NUM] - .chunks(2) - .zip(blind_vec.iter()) - { - let q = composer.add_affine(TEGroupAffine::::new(point[0], point[1])); - let blind_convert = - CP::CurveBaseField::from_le_bytes_mod_order(&blind.into_repr().to_bytes_le()); - let b = composer.add_input(blind_convert); - let b_zh = composer.fixed_base_scalar_mul(b, com_z_h); - let b_zh_add_q = composer.point_addition_gate(q, b_zh); - - // public blinded point - composer.public_inputize(b_zh_add_q.x()); - composer.public_inputize(b_zh_add_q.y()); - } - - // Constrain Com_q(vp_desc) - let poseidon_param_9: PoseidonConstants = - PoseidonConstants::generate::(); - let mut poseidon_circuit = - Poseidon::<_, PlonkSpec, WIDTH_9>::new(composer, &poseidon_param_9); - - let hash_vec = vp_desc - .chunks_exact(8) - .map(|chunk| { - poseidon_circuit.reset(composer); - for x in chunk.iter() { - let var = composer.add_input(*x); - poseidon_circuit.input(var).unwrap(); - } - poseidon_circuit.output_hash(composer) - }) - .collect::>(); - - poseidon_circuit.reset(composer); - for v in hash_vec.iter() { - poseidon_circuit.input(*v).unwrap(); - } - let compressed_vp_desc = poseidon_circuit.output_hash(composer); - - // public compressed_vp_desc for test, remove it when implemented com_vp. - composer.public_inputize(&compressed_vp_desc); - - // TODO: Constrain com_vp - - println!("circuit size: {}", composer.circuit_bound()); - composer.check_circuit_satisfied(); - Ok(()) - } - - fn padded_circuit_size(&self) -> usize { - BLINDING_CIRCUIT_SIZE - } -} - -impl BlindingCircuit { - pub fn new( - rng: &mut impl RngCore, - vp_desc: ValidityPredicateDescription, - vp_setup: &, - >>::UniversalParams, - vp_circuit_size: usize, - ) -> Result { - let blinding = Blinding::::rand(rng); - let zh = CP::get_zh(vp_setup, vp_circuit_size); - - Ok(Self { - vp_desc, - blinding, - zh, - }) - } - - pub fn get_blinding(&self) -> Blinding { - self.blinding - } - - pub fn dummy(rng: &mut impl RngCore) -> Self { - let blinding = Blinding::::rand(rng); - let mut dummy_vp = FieldAdditionValidityPredicate::::dummy(rng); - let vp_circuit_size = dummy_vp.padded_circuit_size(); - let vp_setup = CP::get_pc_setup_params(vp_circuit_size); - let vp_desc = ValidityPredicateDescription::from_vp(&mut dummy_vp, vp_setup).unwrap(); - let zh = CP::get_zh(vp_setup, vp_circuit_size); - - Self { - vp_desc, - blinding, - zh, - } - } -} - -#[ignore] -#[test] -fn test_blinding_circuit() { - // creation of a (balance) VP - // creation of the corresponding blinding circuit - // checking the blinding circuit - - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use crate::circuit::validity_predicate::NUM_NOTE; - use crate::circuit::vp_examples::balance::BalanceValidityPredicate; - use crate::note::Note; - use crate::utils::ws_to_te; - use crate::vp_description::ValidityPredicateDescription; - use plonk_core::circuit::{verify_proof, VerifierData}; - use plonk_core::proof_system::pi::PublicInputs; - type Fr = ::CurveScalarField; - type Fq = ::CurveBaseField; - type P = ::InnerCurve; - type OP = ::Curve; - type PC = ::CurvePC; - type Opc = ::OuterCurvePC; - use ark_std::test_rng; - - let mut rng = test_rng(); - - // A balance VP - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let output_notes = input_notes.clone(); - let mut balance_vp = BalanceValidityPredicate::new(input_notes, output_notes); - balance_vp - .gadget(&mut StandardComposer::::new()) - .unwrap(); - - // we blind the VP desc - let pp = CP::get_pc_setup_params(balance_vp.padded_circuit_size()); - let vp_desc = ValidityPredicateDescription::from_vp(&mut balance_vp, pp).unwrap(); - let vp_desc_compressed = vp_desc.get_compressed(); - - // the blinding circuit, containing the random values used to blind - let mut blinding_circuit = - BlindingCircuit::::new(&mut rng, vp_desc, pp, balance_vp.padded_circuit_size()) - .unwrap(); - - // verifying key with the blinding - let (_, vk_blind) = balance_vp - .compile_with_blinding::(pp, &blinding_circuit.get_blinding()) - .unwrap(); - - let blinding_circuit_size = blinding_circuit.padded_circuit_size(); - let pp_blind = CP::get_opc_setup_params(blinding_circuit_size); - - let pk = CP::get_blind_vp_pk(); - let vk = CP::get_blind_vp_vk(); - - // Blinding Prover - let (proof, blinding_public_input) = blinding_circuit - .gen_proof::(pp_blind, pk.clone(), b"Test") - .unwrap(); - - // Expecting vk_blind(out of circuit) - let mut expect_public_input = PublicInputs::new(); - let q_m = ws_to_te(vk_blind.arithmetic.q_m.0); - expect_public_input.insert(392, q_m.x); - expect_public_input.insert(393, q_m.y); - let q_l = ws_to_te(vk_blind.arithmetic.q_l.0); - expect_public_input.insert(782, q_l.x); - expect_public_input.insert(783, q_l.y); - let q_r = ws_to_te(vk_blind.arithmetic.q_r.0); - expect_public_input.insert(1172, q_r.x); - expect_public_input.insert(1173, q_r.y); - let q_o = ws_to_te(vk_blind.arithmetic.q_o.0); - expect_public_input.insert(1562, q_o.x); - expect_public_input.insert(1563, q_o.y); - let q_4 = ws_to_te(vk_blind.arithmetic.q_4.0); - expect_public_input.insert(1952, q_4.x); - expect_public_input.insert(1953, q_4.y); - let q_c = ws_to_te(vk_blind.arithmetic.q_c.0); - expect_public_input.insert(2342, q_c.x); - expect_public_input.insert(2343, q_c.y); - expect_public_input.insert(21388, vp_desc_compressed); - - assert_eq!(blinding_public_input, expect_public_input); - - // Blinding Verifier - let verifier_data = VerifierData::new(vk.clone(), blinding_public_input); - verify_proof::( - pp_blind, - verifier_data.key, - &proof, - &verifier_data.pi, - b"Test", - ) - .unwrap(); -} diff --git a/taiga_zk_garage/src/circuit/circuit_parameters.rs b/taiga_zk_garage/src/circuit/circuit_parameters.rs deleted file mode 100644 index 99ba6b6d..00000000 --- a/taiga_zk_garage/src/circuit/circuit_parameters.rs +++ /dev/null @@ -1,185 +0,0 @@ -use crate::constant::{ACTION_KEY, BLIND_VP_KEY, OPC_SETUP_MAP, PC_SETUP_MAP}; -use crate::utils::ws_to_te; -use ark_ec::{ - //short_weierstrass_jacobian::GroupAffine as SWGroupAffine, - SWModelParameters, - TEModelParameters, -}; -use ark_ff::PrimeField; -use ark_poly::univariate::DensePolynomial; -use ark_poly_commit::PolynomialCommitment; -use plonk_core::commitment::{HomomorphicCommitment, KZG10}; -use plonk_core::proof_system::{ProverKey, VerifierKey}; -use std::ops::Neg; - -pub trait CircuitParameters: Copy { - // Inner Curve Curve Outer Curve - // Scalar Field Fr Fq - // Base Field Fr Fq - - // Curve - type CurveScalarField: PrimeField; - type CurveBaseField: PrimeField; - type Curve: TEModelParameters< - ScalarField = Self::CurveScalarField, - BaseField = Self::CurveBaseField, - >; - // Inner curve - type InnerCurveScalarField: PrimeField; - type InnerCurve: TEModelParameters< - ScalarField = Self::InnerCurveScalarField, - BaseField = Self::CurveScalarField, - >; - // Outer curve - type OuterCurveBaseField: PrimeField; - type OuterCurve: SWModelParameters< - ScalarField = Self::CurveBaseField, - BaseField = Self::OuterCurveBaseField, - >; - - type CurvePC: HomomorphicCommitment; - type OuterCurvePC: HomomorphicCommitment; - - fn pack_vk( - vk: &VerifierKey, - ) -> Vec; - - fn get_zh( - vp_setup: &, - >>::UniversalParams, - vp_circuit_size: usize, - ) -> [Self::CurveBaseField; 2]; - - fn get_pc_setup_params<'staitc>( - circuit_size: usize, - ) -> &'staitc , - >>::UniversalParams; - - fn get_opc_setup_params<'staitc>( - circuit_size: usize, - ) -> &'staitc , - >>::UniversalParams; - - fn get_action_pk<'staitc>() -> &'staitc ProverKey; - fn get_action_vk<'staitc>() -> &'staitc VerifierKey; - fn get_blind_vp_pk<'staitc>() -> &'staitc ProverKey; - fn get_blind_vp_vk<'staitc>() -> &'staitc VerifierKey; -} - -// // We decided to continue with KZG for now. -// pub struct DLCircuitParameters {} - -// impl CircuitParameters for DLCircuitParameters { -// type CurveScalarField = ark_vesta::Fr; -// type CurveBaseField = ark_vesta::Fq; -// type Curve = ark_vesta::VestaParameters; -// type InnerCurveScalarField = ark_pallas::Fr; -// type InnerCurve = ark_pallas::PallasParameters; -// type OuterCurveBaseField = ark_pallas::Fq; -// type OuterCurve = ark_pallas::PallasParameters; -// type CurvePC = IPA, blake2::Blake2b>; -// type OuterCurvePC = IPA, blake2::Blake2b>; -// } - -#[derive(Copy, Debug, Clone)] -pub struct PairingCircuitParameters {} - -impl CircuitParameters for PairingCircuitParameters { - type CurveScalarField = ark_bls12_381_new::Fr; - type CurveBaseField = ark_bls12_381_new::Fq; - type Curve = ark_bls12_381_new::g1::Parameters; - type InnerCurveScalarField = ark_ed_on_bls12_381_new::Fr; - type InnerCurve = ark_ed_on_bls12_381_new::Parameters; - type OuterCurveBaseField = ark_bw6_764_new::Fq; - type OuterCurve = ark_bw6_764_new::g1::Parameters; - type CurvePC = KZG10; - type OuterCurvePC = KZG10; - - fn pack_vk( - vk: &VerifierKey, - ) -> Vec { - let com_vec = vec![ - ws_to_te(vk.arithmetic.q_m.0), - ws_to_te(vk.arithmetic.q_l.0), - ws_to_te(vk.arithmetic.q_r.0), - ws_to_te(vk.arithmetic.q_o.0), - ws_to_te(vk.arithmetic.q_4.0), - ws_to_te(vk.arithmetic.q_c.0), - ws_to_te(vk.arithmetic.q_arith.0), - ws_to_te(vk.range_selector_commitment.0), - ws_to_te(vk.logic_selector_commitment.0), - ws_to_te(vk.fixed_group_add_selector_commitment.0), - ws_to_te(vk.variable_group_add_selector_commitment.0), - ws_to_te(vk.permutation.left_sigma.0), - ws_to_te(vk.permutation.right_sigma.0), - ws_to_te(vk.permutation.out_sigma.0), - ws_to_te(vk.permutation.fourth_sigma.0), - ws_to_te(vk.lookup.q_lookup.0), - ws_to_te(vk.lookup.table_1.0), - ws_to_te(vk.lookup.table_2.0), - ws_to_te(vk.lookup.table_3.0), - ws_to_te(vk.lookup.table_4.0), - ]; - - let mut ret = vec![]; - com_vec.into_iter().for_each(|v| { - ret.push(v.x); - ret.push(v.y); - }); - ret - } - - fn get_zh( - vp_setup: &, - >>::UniversalParams, - vp_circuit_size: usize, - ) -> [Self::CurveBaseField; 2] { - let (ck, _) = Self::CurvePC::trim(vp_setup, vp_circuit_size, 0, None).unwrap(); - let n = ck.powers_of_g.len(); - let com_g_n = ck.powers_of_g[n - 1]; - let com_g_0 = ck.powers_of_g[0]; - let ws_com_zh = com_g_n + com_g_0.neg(); - let com_z_h = ws_to_te(ws_com_zh); - [com_z_h.x, com_z_h.y] - } - - fn get_pc_setup_params<'staitc>( - circuit_size: usize, - ) -> &'staitc , - >>::UniversalParams { - PC_SETUP_MAP.get(&circuit_size).unwrap() - } - - fn get_opc_setup_params<'staitc>( - circuit_size: usize, - ) -> &'staitc , - >>::UniversalParams { - OPC_SETUP_MAP.get(&circuit_size).unwrap() - } - - fn get_action_pk<'staitc>() -> &'staitc ProverKey { - &ACTION_KEY.0 - } - fn get_action_vk<'staitc>() -> &'staitc VerifierKey { - &ACTION_KEY.1 - } - fn get_blind_vp_pk<'staitc>() -> &'staitc ProverKey { - &BLIND_VP_KEY.0 - } - fn get_blind_vp_vk<'staitc>() -> &'staitc VerifierKey - { - &BLIND_VP_KEY.1 - } -} diff --git a/taiga_zk_garage/src/circuit/gadgets.rs b/taiga_zk_garage/src/circuit/gadgets.rs deleted file mode 100644 index 07848a98..00000000 --- a/taiga_zk_garage/src/circuit/gadgets.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod field_addition; -pub mod hash; -pub mod merkle_tree; -pub mod point_addition; -pub mod scalar_multiplication; -pub mod trivial; diff --git a/taiga_zk_garage/src/circuit/gadgets/field_addition.rs b/taiga_zk_garage/src/circuit/gadgets/field_addition.rs deleted file mode 100644 index 533a4634..00000000 --- a/taiga_zk_garage/src/circuit/gadgets/field_addition.rs +++ /dev/null @@ -1,41 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use ark_ff::One; -use plonk_core::{constraint_system::Variable, prelude::StandardComposer}; - -pub fn field_addition_gadget( - composer: &mut StandardComposer, - var_a: Variable, - var_b: Variable, -) -> Variable { - // simple circuit for the computaiton of a+b (and return the variable corresponding to c=a+b). - let one = CP::CurveScalarField::one(); - let c = composer.value_of_var(var_a) + composer.value_of_var(var_b); - let var_zero = composer.zero_var(); - // Make first constraint a + b = c (as public input) - composer.arithmetic_gate(|gate| { - gate.witness(var_a, var_b, Some(var_zero)) - .add(one, one) - .pi(-c) - }); - composer.add_input(c) -} - -#[test] -fn test_field_addition_gadget() { - use crate::circuit::circuit_parameters::{CircuitParameters, PairingCircuitParameters as CP}; - use plonk_core::constraint_system::StandardComposer; - - let a = ::CurveScalarField::from(2u64); - let b = ::CurveScalarField::from(1u64); - let c = ::CurveScalarField::from(3u64); - let mut composer = StandardComposer::< - ::CurveScalarField, - ::InnerCurve, - >::new(); - let var_a = composer.add_input(a); - let var_b = composer.add_input(b); - let var_c = composer.add_input(c); - let var_a_plus_b = field_addition_gadget::(&mut composer, var_a, var_b); - composer.assert_equal(var_c, var_a_plus_b); - composer.check_circuit_satisfied(); -} diff --git a/taiga_zk_garage/src/circuit/gadgets/hash.rs b/taiga_zk_garage/src/circuit/gadgets/hash.rs deleted file mode 100644 index 9a2966f4..00000000 --- a/taiga_zk_garage/src/circuit/gadgets/hash.rs +++ /dev/null @@ -1,60 +0,0 @@ -use crate::poseidon::{WIDTH_3, WIDTH_5}; -use ark_ec::TEModelParameters; -use ark_ff::PrimeField; -use plonk_core::{ - constraint_system::StandardComposer, - prelude::{Error, Variable}, -}; -use plonk_hashing::poseidon::{ - constants::PoseidonConstants, - poseidon::{PlonkSpec, Poseidon}, -}; - -/// A FieldHasherGadget takes field variables as input and outputs -/// the result variable. `circuit_hash_two` takes two field variables; -/// `circuit_hash` takes at most four field variables. -pub trait FieldHasherGadget> { - fn circuit_hash_two( - &self, - composer: &mut StandardComposer, - left: &Variable, - right: &Variable, - ) -> Result; - - fn circuit_hash( - &self, - composer: &mut StandardComposer, - inputs: &[Variable], - ) -> Result; -} - -/// A FieldHasherGadget implementation for Poseidon hash. -impl> FieldHasherGadget - for PoseidonConstants -{ - fn circuit_hash_two( - &self, - composer: &mut StandardComposer, - left: &Variable, - right: &Variable, - ) -> Result { - let mut poseidon_circuit = Poseidon::<_, PlonkSpec, WIDTH_3>::new(composer, self); - poseidon_circuit.input(*left).unwrap(); - poseidon_circuit.input(*right).unwrap(); - - Ok(poseidon_circuit.output_hash(composer)) - } - - fn circuit_hash( - &self, - composer: &mut StandardComposer, - inputs: &[Variable], - ) -> Result { - let mut poseidon_circuit = Poseidon::<_, PlonkSpec, WIDTH_5>::new(composer, self); - // Default padding zero - inputs.iter().for_each(|f| { - poseidon_circuit.input(*f).unwrap(); - }); - Ok(poseidon_circuit.output_hash(composer)) - } -} diff --git a/taiga_zk_garage/src/circuit/gadgets/merkle_tree.rs b/taiga_zk_garage/src/circuit/gadgets/merkle_tree.rs deleted file mode 100644 index 9485d0e4..00000000 --- a/taiga_zk_garage/src/circuit/gadgets/merkle_tree.rs +++ /dev/null @@ -1,86 +0,0 @@ -use crate::circuit::gadgets::hash::FieldHasherGadget; -use ark_ec::TEModelParameters; -use ark_ff::PrimeField; -use plonk_core::{ - constraint_system::StandardComposer, - prelude::{Error, Variable}, -}; - -/// A Merkle Tree Gadget takes leaf node variable, authorization path to the -/// root and the FieldHasherGadget, then returns the merkle root variable. -pub fn merkle_tree_gadget< - F: PrimeField, - P: TEModelParameters, - BHG: FieldHasherGadget, ->( - composer: &mut StandardComposer, - cur_leaf: &Variable, - auth_path: &[(F, bool)], - hash_gadget: &BHG, -) -> Result { - let mut cur = *cur_leaf; - - // Ascend the merkle tree authentication path - for e in auth_path.iter() { - // Determines if the current subtree is the "right" leaf at this - // depth of the tree. - let cur_is_right = match e.1 { - false => composer.add_input(F::zero()), - true => composer.add_input(F::one()), - }; - - // Witness the authentication path element adjacent - // at this depth. - let path_element = composer.add_input(e.0); - - // Swap the two if the current subtree is on the right - let ul = composer.conditional_select(cur_is_right, path_element, cur); - let ur = composer.conditional_select(cur_is_right, cur, path_element); - - // Compute the new subtree value - cur = hash_gadget.circuit_hash_two(composer, &ul, &ur)?; - } - - Ok(cur) -} - -#[test] -fn test_merkle_circuit() { - use crate::circuit::circuit_parameters::{CircuitParameters, PairingCircuitParameters}; - use crate::merkle_tree::TAIGA_COMMITMENT_TREE_DEPTH; - use crate::merkle_tree::{MerklePath, Node}; - use crate::poseidon::POSEIDON_HASH_PARAM_BLS12_381_NEW_SCALAR_ARITY2; - type Fr = ::CurveScalarField; - type P = ::InnerCurve; - use ark_std::test_rng; - use plonk_hashing::poseidon::constants::PoseidonConstants; - - let mut rng = test_rng(); - let merkle_path = - MerklePath::>::dummy(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH); - - let cur_leaf = Node::rand(&mut rng); - let expected = merkle_path - .root( - cur_leaf.clone(), - &POSEIDON_HASH_PARAM_BLS12_381_NEW_SCALAR_ARITY2, - ) - .unwrap(); - - let mut composer = StandardComposer::::new(); - let commitment = composer.add_input(cur_leaf.inner()); - let root = merkle_tree_gadget::>( - &mut composer, - &commitment, - &merkle_path.get_path(), - &POSEIDON_HASH_PARAM_BLS12_381_NEW_SCALAR_ARITY2, - ) - .unwrap(); - composer.check_circuit_satisfied(); - - let expected_var = composer.add_input(expected.inner()); - composer.assert_equal(expected_var, root); - composer.check_circuit_satisfied(); - - println!("circuit size for merkel tree: {}", composer.circuit_bound()); -} diff --git a/taiga_zk_garage/src/circuit/gadgets/point_addition.rs b/taiga_zk_garage/src/circuit/gadgets/point_addition.rs deleted file mode 100644 index 9af9090a..00000000 --- a/taiga_zk_garage/src/circuit/gadgets/point_addition.rs +++ /dev/null @@ -1,65 +0,0 @@ -use ark_ec::TEModelParameters; -use ark_ff::PrimeField; -use plonk_core::prelude::{Point, StandardComposer}; - -pub fn point_addition_gadget>( - composer: &mut StandardComposer, - var_a: Point

, - var_b: Point

, -) -> Point

{ - // simple circuit for the computaiton of a+b (and return the variable corresponding to c=a+b). - composer.point_addition_gate(var_a, var_b) -} - -#[test] -fn test_point_addition_gadget() { - use crate::circuit::circuit_parameters::{CircuitParameters, PairingCircuitParameters as CP}; - use ark_ec::twisted_edwards_extended::GroupAffine as TEGroupAffine; - use ark_ec::TEModelParameters; - - // Test over InnerCurve - type PC = ::CurvePC; - type F = ::CurveScalarField; - type P = ::InnerCurve; - - // Points - let (x, y) = P::AFFINE_GENERATOR_COEFFS; - let generator = TEGroupAffine::

::new(x, y); - let expected_point = generator + generator; - - // gadget - let mut composer = StandardComposer::< - ::CurveScalarField, - ::InnerCurve, - >::new(); - let x_var = composer.add_input(x); - let y_var = composer.add_input(y); - let point_a: Point

= Point::new(x_var, y_var); - let point_b: Point

= Point::new(x_var, y_var); - let point = composer.point_addition_gate(point_a, point_b); - composer.assert_equal_public_point(point, expected_point); - composer.check_circuit_satisfied(); - - // Test over Curve - type Opc = ::OuterCurvePC; - type Fq = ::CurveBaseField; - type OP = ::Curve; - - // Points - let (x, y) = OP::AFFINE_GENERATOR_COEFFS; - let generator = TEGroupAffine::::new(x, y); - let expected_point = generator + generator; - - // gadget - let mut composer = StandardComposer::< - ::CurveBaseField, - ::Curve, - >::new(); - let x_var = composer.add_input(x); - let y_var = composer.add_input(y); - let point_a: Point = Point::new(x_var, y_var); - let point_b: Point = Point::new(x_var, y_var); - let point = composer.point_addition_gate(point_a, point_b); - composer.assert_equal_public_point(point, expected_point); - composer.check_circuit_satisfied(); -} diff --git a/taiga_zk_garage/src/circuit/gadgets/scalar_multiplication.rs b/taiga_zk_garage/src/circuit/gadgets/scalar_multiplication.rs deleted file mode 100644 index 09c712b1..00000000 --- a/taiga_zk_garage/src/circuit/gadgets/scalar_multiplication.rs +++ /dev/null @@ -1,79 +0,0 @@ -use ark_ec::twisted_edwards_extended::GroupAffine as TEGroupAffine; -use ark_ec::TEModelParameters; -use ark_ff::PrimeField; -use plonk_core::{ - constraint_system::Variable, - prelude::{Point, StandardComposer}, -}; - -pub fn scalar_multiplication_gadget>( - composer: &mut StandardComposer, - var_n: Variable, -) -> Point

{ - // simple circuit for the computaiton of [n] * a (and return the variable corresponding to b=[n]a). - let (x, y) = P::AFFINE_GENERATOR_COEFFS; - let generator = TEGroupAffine::

::new(x, y); - composer.fixed_base_scalar_mul(var_n, generator) -} - -#[test] -fn test_scalar_multiplication_gadget() { - use crate::circuit::circuit_parameters::{CircuitParameters, PairingCircuitParameters as CP}; - use ark_ec::twisted_edwards_extended::GroupAffine as TEGroupAffine; - use ark_ec::TEModelParameters; - - type PC = ::CurvePC; - type F = ::CurveScalarField; - type P = ::InnerCurve; - type Opc = ::OuterCurvePC; - type Fq = ::CurveBaseField; - type OP = ::Curve; - use ark_poly_commit::PolynomialCommitment; - use plonk_core::proof_system::Prover; - use plonk_core::proof_system::Verifier; - use rand::rngs::OsRng; - - // Points - let (x, y) = OP::AFFINE_GENERATOR_COEFFS; - let generator = TEGroupAffine::::new(x, y); - let scalar = Fq::from(3); - let expected_point = generator + generator + generator; - - // public params - let u_params = Opc::setup(512, None, &mut OsRng).unwrap(); - - // Commit Key - let (ck, vk) = Opc::trim(&u_params, 512, 0, None).unwrap(); - - // prover - let mut prover: Prover = Prover::new(b"demo"); - - // gadget - let composer_prover = prover.mut_cs(); - let var_n = composer_prover.add_input(scalar); - let point = composer_prover.fixed_base_scalar_mul(var_n, generator); - composer_prover.assert_equal_public_point(point, expected_point); - composer_prover.check_circuit_satisfied(); - - // Preprocess circuit - prover.preprocess(&ck).unwrap(); - - let public_inputs = prover.cs.get_pi().clone(); - - let proof = prover.prove(&ck).unwrap(); - - // Verifier - let mut verifier = Verifier::::new(b"demo"); - - // Verifier gadget - let composer_verifier = verifier.mut_cs(); - let var_n = composer_verifier.add_input(scalar); - let point = composer_verifier.fixed_base_scalar_mul(var_n, generator); - composer_verifier.assert_equal_public_point(point, expected_point); - composer_verifier.check_circuit_satisfied(); - - // // Preprocess - verifier.preprocess(&ck).unwrap(); - - assert!(verifier.verify(&proof, &vk, &public_inputs).is_ok()); -} diff --git a/taiga_zk_garage/src/circuit/gadgets/trivial.rs b/taiga_zk_garage/src/circuit/gadgets/trivial.rs deleted file mode 100644 index d4a6b781..00000000 --- a/taiga_zk_garage/src/circuit/gadgets/trivial.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use ark_ff::One; -use plonk_core::prelude::StandardComposer; - -pub fn trivial_gadget( - composer: &mut StandardComposer, - _private_inputs: &[CP::CurveScalarField], - _public_inputs: &[CP::CurveScalarField], -) { - // no input in this trivial gadget... - let var_one = composer.add_input(CP::CurveScalarField::one()); - composer.arithmetic_gate(|gate| { - gate.witness(var_one, var_one, None) - .add(CP::CurveScalarField::one(), CP::CurveScalarField::one()) - }); -} - -#[test] -fn test_trivial_gadget() { - use crate::circuit::circuit_parameters::{CircuitParameters, PairingCircuitParameters as CP}; - use plonk_core::constraint_system::StandardComposer; - - let mut composer = StandardComposer::< - ::CurveScalarField, - ::InnerCurve, - >::new(); - trivial_gadget::(&mut composer, &[], &[]); - composer.check_circuit_satisfied(); -} diff --git a/taiga_zk_garage/src/circuit/integrity.rs b/taiga_zk_garage/src/circuit/integrity.rs deleted file mode 100644 index 7c1bf303..00000000 --- a/taiga_zk_garage/src/circuit/integrity.rs +++ /dev/null @@ -1,463 +0,0 @@ -// The interfaces may not be perfectly defined, the caller can refine them if needed. - -use crate::circuit::{circuit_parameters::CircuitParameters, gadgets::hash::FieldHasherGadget}; -// use crate::error::TaigaError; -use crate::note::Note; -use crate::poseidon::{WIDTH_3, WIDTH_5, WIDTH_9}; -use ark_ff::{Field, One, PrimeField}; -use plonk_core::{ - constraint_system::StandardComposer, - prelude::{Error, Variable}, -}; -use plonk_hashing::poseidon::{ - constants::PoseidonConstants, - poseidon::{PlonkSpec, Poseidon}, -}; - -pub fn spent_user_address_integrity_circuit( - composer: &mut StandardComposer, - nk: &Variable, - // convert the vp variables inside, move out if needed. - send_vp_bytes: &[bool], - recv_vp_bytes: &[bool], -) -> Result<(Variable, Vec), Error> { - // Init poseidon hash gadget. - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - - // convert send_vp bits to two variable - let (mut send_com_fields, send_vp_bits) = bits_to_variables::(composer, send_vp_bytes); - - // send_com = Com_r(send_vp_hash || nk) - send_com_fields.push(*nk); - let address_send = poseidon_param.circuit_hash(composer, &send_com_fields)?; - - // convert recv_vp bits to two variable - let (recv_vp, _recv_vp_bits) = bits_to_variables::(composer, recv_vp_bytes); - - // generate address variable - let mut address_vars = vec![address_send]; - address_vars.extend(recv_vp); - let address = poseidon_param.circuit_hash(composer, &address_vars)?; - Ok((address, send_vp_bits)) -} - -pub fn output_user_address_integrity_circuit( - composer: &mut StandardComposer, - address_send: &Variable, - // convert the vp variables inside, move out if needed. - recv_vp_bytes: &[bool], -) -> Result<(Variable, Vec), Error> { - // Init poseidon hash gadget. - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - - // convert recv_vp bits to two variable - let (recv_vp, recv_vp_bits) = bits_to_variables::(composer, recv_vp_bytes); - - // generate address variable - let mut address_vars = vec![*address_send]; - address_vars.extend(recv_vp); - let address = poseidon_param.circuit_hash(composer, &address_vars)?; - Ok((address, recv_vp_bits)) -} - -pub fn app_integrity_circuit( - composer: &mut StandardComposer, - // convert the vp variables inside, move out if needed. - app_vp_bytes: &[bool], -) -> Result<(Variable, Vec), Error> { - // Init poseidon hash gadget. - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - - // convert app_vp bits to two variable - let (app_vp_vars, app_bits_var) = bits_to_variables::(composer, app_vp_bytes); - - // generate address variable - let app_address = - poseidon_param.circuit_hash_two(composer, &app_vp_vars[0], &app_vp_vars[1])?; - - Ok((app_address, app_bits_var)) -} - -pub fn note_commitment_circuit( - composer: &mut StandardComposer, - address: &Variable, - app: &Variable, - value: &Variable, // To be decided where to constrain the range of value, add the range constraints here first. - data: &Variable, - rho: &Variable, - rcm: &Variable, -) -> Result<(Variable, Variable), Error> { - // constrain the value to be 64 bit - composer.range_gate(*value, 64); - - // psi = prf(rho, rcm) - let poseidon_param_3: PoseidonConstants = - PoseidonConstants::generate::(); - let psi = poseidon_param_3.circuit_hash_two(composer, rho, rcm)?; - - // cm = crh(address, value, data, rho, psi, rcm, app) - let poseidon_param_9: PoseidonConstants = - PoseidonConstants::generate::(); - let mut poseidon_circuit = - Poseidon::<_, PlonkSpec, WIDTH_9>::new(composer, &poseidon_param_9); - // Default padding zero - poseidon_circuit.input(*address).unwrap(); - poseidon_circuit.input(*app).unwrap(); - poseidon_circuit.input(*value).unwrap(); - poseidon_circuit.input(*data).unwrap(); - poseidon_circuit.input(*rho).unwrap(); - poseidon_circuit.input(psi).unwrap(); - poseidon_circuit.input(*rcm).unwrap(); - Ok((poseidon_circuit.output_hash(composer), psi)) -} - -// cm is a scalar -pub fn nullifier_circuit( - composer: &mut StandardComposer, - nk: &Variable, - rho: &Variable, - psi: &Variable, - cm: &Variable, -) -> Result { - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - let variavle_vec = vec![*nk, *rho, *psi, *cm]; - let nullifier_variable = poseidon_param.circuit_hash(composer, &variavle_vec)?; - - // public the nullifier - composer.public_inputize(&nullifier_variable); - - // return the nullifier variable.(if we don't need it, pls get rid of it) - Ok(nullifier_variable) -} - -// cm is a point -// pub fn nullifier_circuit( -// composer: &mut StandardComposer, -// nk: &Variable, -// rho: &Variable, -// psi: &Variable, -// cm: &Point, -// ) -> Result { -// let poseidon_param: PoseidonConstants = -// PoseidonConstants::generate::(); -// let prf_ret = poseidon_param.circuit_hash_two(composer, nk, rho)?; - -// // scalar = prf_nk(rho) + psi -// let scalar = composer.arithmetic_gate(|gate| { -// gate.witness(prf_ret, *psi, None) -// .add(CP::CurveScalarField::one(), CP::CurveScalarField::one()) -// }); - -// // point_scalar = scalar * generator -// let point_scalar = -// composer.fixed_base_scalar_mul(scalar, TEGroupAffine::prime_subgroup_generator()); - -// // nullifier_point = point_scalar + cm -// let nullifier_point = composer.point_addition_gate(point_scalar, *cm); - -// // public the nullifier -// let nullifier_variable = nullifier_point.x(); -// composer.public_inputize(nullifier_variable); - -// // return the nullifier variable.(if we don't need it, pls get rid of it) -// Ok(*nullifier_variable) -// } - -// To keep consistent with crate::utils::bytes_to_fields -// The bits are from unformatted bytes or non-CP::CurveScalarField type. -// The bits can not be from CP::CurveScalarField, it will have one bit loss. -pub fn bits_to_variables( - composer: &mut StandardComposer, - bits: &[bool], -) -> (Vec, Vec) { - let bit_variables: Vec = bits - .iter() - .map(|bit| composer.add_input(CP::CurveScalarField::from(*bit as u64))) - .collect(); - - let scalar_variables = bit_variables - .chunks(CP::CurveScalarField::size_in_bits() - 1) - .map(|elt| { - let mut accumulator_var = composer.zero_var(); - for (power, bit) in elt.iter().enumerate() { - composer.boolean_gate(*bit); - - let two_pow = CP::CurveScalarField::from(2u64).pow([power as u64, 0, 0, 0]); - - accumulator_var = composer.arithmetic_gate(|gate| { - gate.witness(*bit, accumulator_var, None) - .add(two_pow, CP::CurveScalarField::one()) - }); - } - accumulator_var - }) - .collect(); - - (scalar_variables, bit_variables) -} - -// FIXME: It includes all the variables in input note, maybe it's not necessary. -pub struct ValidityPredicateInputNoteVariables { - pub sender_addr: Variable, - pub nk: Variable, - // send_vp_bits will be used in vp commitment in future. - pub send_vp_bits: Vec, - pub app_addr: Variable, - // app_bits will be used in vp commitment in future. - pub app_bits: Vec, - pub value: Variable, - pub data: Variable, - pub nf: Variable, - pub cm: Variable, -} - -// FIXME: It includes all the variables in output note, maybe it's not necessary. -pub struct ValidityPredicateOutputNoteVariables { - pub recipient_addr: Variable, - pub recv_vp_bits: Vec, - pub app_addr: Variable, - pub app_bits: Vec, - pub value: Variable, - pub data: Variable, -} - -pub fn input_note_constraint( - note: &Note, - composer: &mut StandardComposer, -) -> Result -where - CP: CircuitParameters, -{ - // check user address - let nk = note.user.send_com.get_nk().unwrap(); - let nk_var = composer.add_input(nk.inner()); - let send_vp = note.user.send_com.get_send_vp().unwrap(); - let (sender_addr, send_vp_bits) = spent_user_address_integrity_circuit::( - composer, - &nk_var, - &send_vp.to_bits(), - ¬e.user.recv_vp.to_bits(), - )?; - - // check app address - let (app_addr, app_bits) = app_integrity_circuit::(composer, ¬e.app.app_vp.to_bits())?; - - // check note commitment - let value_var = composer.add_input(CP::CurveScalarField::from(note.value)); - let data_var = composer.add_input(note.data); - let rho_var = composer.add_input(note.rho.inner()); - let note_rcm_var = composer.add_input(note.rcm); - let (cm_var, psi_var) = note_commitment_circuit::( - composer, - &sender_addr, - &app_addr, - &value_var, - &data_var, - &rho_var, - ¬e_rcm_var, - )?; - - let nf = nullifier_circuit::(composer, &nk_var, &rho_var, &psi_var, &cm_var)?; - - Ok(ValidityPredicateInputNoteVariables { - sender_addr, - nk: nk_var, - send_vp_bits, - app_addr, - app_bits, - value: value_var, - data: data_var, - nf, - cm: cm_var, - }) -} - -pub fn output_note_constraint( - note: &Note, - nf: &Variable, - composer: &mut StandardComposer, -) -> Result -where - CP: CircuitParameters, -{ - // check user address - let addr_send = note.user.send_com.get_closed().unwrap(); - let addr_send_var = composer.add_input(addr_send); - let (recipient_addr, recv_vp_bits) = output_user_address_integrity_circuit::( - composer, - &addr_send_var, - ¬e.user.recv_vp.to_bits(), - )?; - - // check app address - let (app_addr, app_bits) = app_integrity_circuit::(composer, ¬e.app.app_vp.to_bits())?; - - // check and publish note commitment - let value_var = composer.add_input(CP::CurveScalarField::from(note.value)); - let data_var = composer.add_input(note.data); - let note_rcm_var = composer.add_input(note.rcm); - let (cm_var, _psi_var) = note_commitment_circuit::( - composer, - &recipient_addr, - &app_addr, - &value_var, - &data_var, - nf, - ¬e_rcm_var, - )?; - - composer.public_inputize(&cm_var); - - Ok(ValidityPredicateOutputNoteVariables { - recipient_addr, - recv_vp_bits, - app_addr, - app_bits, - value: value_var, - data: data_var, - }) -} - -mod test { - use crate::circuit::circuit_parameters::{CircuitParameters, PairingCircuitParameters}; - type Fr = ::CurveScalarField; - type P = ::InnerCurve; - type Fq = ::CurveBaseField; - - #[test] - fn test_bits_to_variables() { - use crate::circuit::integrity::bits_to_variables; - use crate::utils::bits_to_fields; - use ark_ff::{BigInteger, PrimeField}; - use ark_std::{test_rng, UniformRand}; - use plonk_core::constraint_system::StandardComposer; - - let mut rng = test_rng(); - let src_scalar = Fq::rand(&mut rng); - let src_scalar_bits = src_scalar.into_repr().to_bits_le(); - - // inside-circuit convert - let mut composer = StandardComposer::::new(); - let (target_var, _) = - bits_to_variables::(&mut composer, &src_scalar_bits); - composer.check_circuit_satisfied(); - - println!( - "circuit size of bits_to_variables: {}", - composer.circuit_bound() - ); - - // out-of-circuit convert, expect result - let target_expect = bits_to_fields::(&src_scalar_bits); - - assert_eq!(target_var.len(), target_expect.len()); - for i in 0..target_var.len() { - let expected_var = composer.add_input(target_expect[i]); - composer.assert_equal(expected_var, target_var[i]); - } - composer.check_circuit_satisfied(); - } - - #[test] - fn test_integrity_circuit() { - use crate::app::App; - use crate::circuit::integrity::app_integrity_circuit; - use crate::circuit::integrity::note_commitment_circuit; - use crate::circuit::integrity::nullifier_circuit; - use crate::circuit::integrity::spent_user_address_integrity_circuit; - use crate::note::Note; - use crate::nullifier::Nullifier; - use crate::user::User; - use ark_std::{test_rng, UniformRand}; - use plonk_core::constraint_system::StandardComposer; - use rand::Rng; - - let mut rng = test_rng(); - let mut composer = StandardComposer::::new(); - - // Test user address integrity - // Create a user - let user = User::::dummy(&mut rng); - - let nk = user.send_com.get_nk().unwrap(); - let nk_var = composer.add_input(nk.inner()); - let send_vp = user.send_com.get_send_vp().unwrap(); - let (address_var, _) = spent_user_address_integrity_circuit::( - &mut composer, - &nk_var, - &send_vp.to_bits(), - &user.recv_vp.to_bits(), - ) - .unwrap(); - let expect_address_opaque = user.address().unwrap(); - let expected_address_var = composer.add_input(expect_address_opaque); - composer.assert_equal(expected_address_var, address_var); - composer.check_circuit_satisfied(); - - // Test app integrity - // Create a app - let app = App::::dummy(&mut rng); - - let (app_var, _) = - app_integrity_circuit::(&mut composer, &app.app_vp.to_bits()) - .unwrap(); - let expected_app_addr = app.address().unwrap(); - let app_expected_var = composer.add_input(expected_app_addr); - composer.assert_equal(app_expected_var, app_var); - composer.check_circuit_satisfied(); - - // Test note commitment - // Create a note - let rho = Nullifier::new(Fr::rand(&mut rng)); - let value: u64 = rng.gen(); - let data = Fr::rand(&mut rng); - let rcm = Fr::rand(&mut rng); - let note = Note::new(user, app, value, rho, data, rcm); - - let value_var = composer.add_input(Fr::from(value)); - let data_var = composer.add_input(note.data); - let rho_var = composer.add_input(note.rho.inner()); - let note_rcm_var = composer.add_input(note.rcm); - - let (cm_var, psi_var) = note_commitment_circuit::( - &mut composer, - &address_var, - &app_var, - &value_var, - &data_var, - &rho_var, - ¬e_rcm_var, - ) - .unwrap(); - - let expect_cm = note.commitment().unwrap(); - let cm_expected_var = composer.add_input(expect_cm.inner()); - composer.assert_equal(cm_expected_var, cm_var); - composer.check_circuit_satisfied(); - - // Test nullifier - let expect_nf = Nullifier::::derive_native( - &nk, ¬e.rho, ¬e.psi, &expect_cm, - ); - let nullifier_variable = nullifier_circuit::( - &mut composer, - &nk_var, - &rho_var, - &psi_var, - &cm_var, - ) - .unwrap(); - let nf_expected_var = composer.add_input(expect_nf.inner()); - composer.assert_equal(nf_expected_var, nullifier_variable); - composer.check_circuit_satisfied(); - - println!( - "circuit size of test_integrity_circuit: {}", - composer.circuit_bound() - ); - } -} diff --git a/taiga_zk_garage/src/circuit/validity_predicate.rs b/taiga_zk_garage/src/circuit/validity_predicate.rs deleted file mode 100644 index 63d9c8a9..00000000 --- a/taiga_zk_garage/src/circuit/validity_predicate.rs +++ /dev/null @@ -1,83 +0,0 @@ -pub const NUM_NOTE: usize = 4; -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::circuit::integrity::{ - input_note_constraint, output_note_constraint, ValidityPredicateInputNoteVariables, - ValidityPredicateOutputNoteVariables, -}; -use crate::note::Note; -use ark_poly::univariate::DensePolynomial; -use ark_poly_commit::PolynomialCommitment; -use plonk_core::{ - circuit::Circuit, - constraint_system::StandardComposer, - error::to_pc_error, - prelude::Error, - proof_system::{verifier::Verifier, VerifierKey}, -}; - -pub trait ValidityPredicate: - Circuit -{ - // Default implementation, used in gadgets function in Circuit trait. - fn gadget_vp( - &mut self, - composer: &mut StandardComposer, - ) -> Result<(), Error> { - let (input_note_variables, output_note_variables) = self.basic_constraints(composer)?; - self.custom_constraints(composer, &input_note_variables, &output_note_variables) - } - - // Default implementation, constrains the notes integrity and outputs variables of notes. - fn basic_constraints( - &self, - composer: &mut StandardComposer, - ) -> Result< - ( - Vec, - Vec, - ), - Error, - > { - let input_notes = self.get_input_notes(); - let output_notes = self.get_output_notes(); - let mut input_note_variables = vec![]; - let mut output_note_variables = vec![]; - for i in 0..NUM_NOTE { - let input_note_var = input_note_constraint(&input_notes[i], composer)?; - let output_note_var = - output_note_constraint(&output_notes[i], &input_note_var.nf, composer)?; - input_note_variables.push(input_note_var); - output_note_variables.push(output_note_var); - } - Ok((input_note_variables, output_note_variables)) - } - - fn get_desc_vp( - &mut self, - vp_setup: &, - >>::UniversalParams, - ) -> Result, Error> { - let (ck, _) = CP::CurvePC::trim(vp_setup, self.padded_circuit_size(), 0, None) - .map_err(to_pc_error::)?; - let mut verifier = Verifier::new(b"CircuitCompilation"); - self.gadget(verifier.mut_cs())?; - verifier.preprocess(&ck)?; - Ok(verifier - .verifier_key - .expect("Unexpected error. Missing VerifierKey in compilation")) - } - - // VP designer should implement the following functions. - fn get_input_notes(&self) -> &[Note; NUM_NOTE]; - fn get_output_notes(&self) -> &[Note; NUM_NOTE]; - fn custom_constraints( - &self, - _composer: &mut StandardComposer, - _input_note_variables: &[ValidityPredicateInputNoteVariables], - _output_note_variables: &[ValidityPredicateOutputNoteVariables], - ) -> Result<(), Error> { - Ok(()) - } -} diff --git a/taiga_zk_garage/src/circuit/vp_examples.rs b/taiga_zk_garage/src/circuit/vp_examples.rs deleted file mode 100644 index 40d43aef..00000000 --- a/taiga_zk_garage/src/circuit/vp_examples.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod balance; -pub mod field_addition; -pub mod point_addition; -pub mod scalar_multiplication; -pub mod white_list_apps; -pub mod white_list_senders; diff --git a/taiga_zk_garage/src/circuit/vp_examples/balance.rs b/taiga_zk_garage/src/circuit/vp_examples/balance.rs deleted file mode 100644 index b86bcdd0..00000000 --- a/taiga_zk_garage/src/circuit/vp_examples/balance.rs +++ /dev/null @@ -1,133 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::circuit::gadgets::field_addition::field_addition_gadget; -use crate::circuit::integrity::{ - ValidityPredicateInputNoteVariables, ValidityPredicateOutputNoteVariables, -}; -use crate::circuit::validity_predicate::{ValidityPredicate, NUM_NOTE}; -use crate::note::Note; -use plonk_core::{circuit::Circuit, constraint_system::StandardComposer, prelude::Error}; - -// BalanceValidityPredicate have a custom constraint with a + b = c, -// in which a, b are private inputs and c is a public input. -pub struct BalanceValidityPredicate { - // basic "private" inputs to the VP - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], -} - -impl BalanceValidityPredicate { - pub fn new(input_notes: [Note; NUM_NOTE], output_notes: [Note; NUM_NOTE]) -> Self { - Self { - input_notes, - output_notes, - } - } -} - -impl ValidityPredicate for BalanceValidityPredicate -where - CP: CircuitParameters, -{ - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes - } - - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes - } - - fn custom_constraints( - &self, - composer: &mut StandardComposer, - input_note_variables: &[ValidityPredicateInputNoteVariables], - output_note_variables: &[ValidityPredicateOutputNoteVariables], - ) -> Result<(), Error> { - // check that all notes use the same app - let var_app = input_note_variables[0].app_addr; - for note_var in input_note_variables { - composer.assert_equal(note_var.app_addr, var_app); - } - for note_var in output_note_variables { - composer.assert_equal(note_var.app_addr, var_app); - } - - // sum of the input note values - let mut balance_input_var = composer.zero_var(); - for note_var in input_note_variables { - balance_input_var = - field_addition_gadget::(composer, balance_input_var, note_var.value); - } - // sum of the output note values - let mut balance_output_var = composer.zero_var(); - for note_var in output_note_variables { - balance_output_var = - field_addition_gadget::(composer, balance_output_var, note_var.value); - } - composer.assert_equal(balance_input_var, balance_output_var); - Ok(()) - } -} - -impl Circuit for BalanceValidityPredicate -where - CP: CircuitParameters, -{ - const CIRCUIT_ID: [u8; 32] = [0x00; 32]; - - // Default implementation - fn gadget( - &mut self, - composer: &mut StandardComposer, - ) -> Result<(), Error> { - self.gadget_vp(composer) - } - - fn padded_circuit_size(&self) -> usize { - 1 << 17 - } -} - -#[ignore] -#[test] -fn test_balance_vp_example() { - use crate::app::App; - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use plonk_core::circuit::{verify_proof, VerifierData}; - type Fr = ::CurveScalarField; - type P = ::InnerCurve; - type PC = ::CurvePC; - use ark_std::test_rng; - - let mut rng = test_rng(); - let xan = App::::dummy(&mut rng); - // input notes - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy_from_app(xan.clone(), &mut rng)); - // output notes - let mut output_notes = input_notes.clone(); - let tmp = output_notes[0].value; - output_notes[0].value = output_notes[1].value; - output_notes[1].value = tmp; - - let mut balance_vp = BalanceValidityPredicate { - input_notes, - output_notes, - }; - - let mut composer = StandardComposer::::new(); - balance_vp.gadget(&mut composer).unwrap(); - composer.check_circuit_satisfied(); - println!("circuit size of balance_vp: {}", composer.circuit_bound()); - - // Generate CRS - let pp = CP::get_pc_setup_params(balance_vp.padded_circuit_size()); - - // Compile the circuit - let (pk, vk) = balance_vp.compile::(pp).unwrap(); - - // Prover - let (proof, public_input) = balance_vp.gen_proof::(pp, pk, b"Test").unwrap(); - - // Verifier - let verifier_data = VerifierData::new(vk, public_input); - verify_proof::(pp, verifier_data.key, &proof, &verifier_data.pi, b"Test").unwrap(); -} diff --git a/taiga_zk_garage/src/circuit/vp_examples/field_addition.rs b/taiga_zk_garage/src/circuit/vp_examples/field_addition.rs deleted file mode 100644 index e6ac6a5c..00000000 --- a/taiga_zk_garage/src/circuit/vp_examples/field_addition.rs +++ /dev/null @@ -1,142 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::circuit::gadgets::field_addition::field_addition_gadget; -use crate::circuit::integrity::{ - ValidityPredicateInputNoteVariables, ValidityPredicateOutputNoteVariables, -}; -use crate::circuit::validity_predicate::{ValidityPredicate, NUM_NOTE}; -use crate::note::Note; -use ark_ff::UniformRand; -use plonk_core::{circuit::Circuit, constraint_system::StandardComposer, prelude::Error}; -use rand::RngCore; - -// FieldAdditionValidityPredicate have a custom constraint with a + b = c, -// in which a, b are private inputs and c is a public input. -pub struct FieldAdditionValidityPredicate { - // basic "private" inputs to the VP - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], - // custom "private" inputs to the VP - a: CP::CurveScalarField, - b: CP::CurveScalarField, - // custom "public" inputs to the VP - pub c: CP::CurveScalarField, -} - -impl FieldAdditionValidityPredicate { - pub fn new( - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], - rng: &mut impl RngCore, - ) -> Self { - let a = CP::CurveScalarField::rand(rng); - let b = CP::CurveScalarField::rand(rng); - let c = a + b; - Self { - input_notes, - output_notes, - a, - b, - c, - } - } - - pub fn dummy(rng: &mut impl RngCore) -> Self { - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(rng)); - let output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(rng)); - let a = CP::CurveScalarField::rand(rng); - let b = CP::CurveScalarField::rand(rng); - let c = a + b; - Self { - input_notes, - output_notes, - a, - b, - c, - } - } -} - -impl ValidityPredicate for FieldAdditionValidityPredicate -where - CP: CircuitParameters, -{ - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes - } - - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes - } - - fn custom_constraints( - &self, - composer: &mut StandardComposer, - _input_note_variables: &[ValidityPredicateInputNoteVariables], - _output_note_variables: &[ValidityPredicateOutputNoteVariables], - ) -> Result<(), Error> { - let var_a = composer.add_input(self.a); - let var_b = composer.add_input(self.b); - let var_a_plus_b = field_addition_gadget::(composer, var_a, var_b); - let var_c = composer.add_input(self.c); - composer.assert_equal(var_c, var_a_plus_b); - Ok(()) - } -} - -impl Circuit for FieldAdditionValidityPredicate -where - CP: CircuitParameters, -{ - const CIRCUIT_ID: [u8; 32] = [0x00; 32]; - - // Default implementation - fn gadget( - &mut self, - composer: &mut StandardComposer, - ) -> Result<(), Error> { - self.gadget_vp(composer) - } - - fn padded_circuit_size(&self) -> usize { - 1 << 17 - } -} - -#[ignore] -#[test] -fn test_field_addition_vp_example() { - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - type Fr = ::CurveScalarField; - type P = ::InnerCurve; - type PC = ::CurvePC; - type Fq = ::CurveBaseField; - type OP = ::Curve; - type Opc = ::OuterCurvePC; - use ark_std::test_rng; - use plonk_core::circuit::{verify_proof, VerifierData}; - - let mut rng = test_rng(); - let mut field_addition_vp = FieldAdditionValidityPredicate::::dummy(&mut rng); - - // Generate vp CRS - let vp_setup = CP::get_pc_setup_params(field_addition_vp.padded_circuit_size()); - - // Compile vp(must use compile_with_blinding) - let (pk, vk_blind) = field_addition_vp.compile::(vp_setup).unwrap(); - - // VP Prover - let (proof, public_input) = field_addition_vp - .gen_proof::(vp_setup, pk, b"Test") - .unwrap(); - - // VP verifier - let verifier_data = VerifierData::new(vk_blind, public_input); - verify_proof::( - vp_setup, - verifier_data.key, - &proof, - &verifier_data.pi, - b"Test", - ) - .unwrap(); -} diff --git a/taiga_zk_garage/src/circuit/vp_examples/point_addition.rs b/taiga_zk_garage/src/circuit/vp_examples/point_addition.rs deleted file mode 100644 index 5a603736..00000000 --- a/taiga_zk_garage/src/circuit/vp_examples/point_addition.rs +++ /dev/null @@ -1,123 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::circuit::gadgets::point_addition::point_addition_gadget; -use crate::circuit::integrity::{ - ValidityPredicateInputNoteVariables, ValidityPredicateOutputNoteVariables, -}; -use crate::circuit::validity_predicate::{ValidityPredicate, NUM_NOTE}; -use crate::note::Note; -use ark_ec::twisted_edwards_extended::GroupAffine as TEGroupAffine; -use plonk_core::{circuit::Circuit, constraint_system::StandardComposer, prelude::Error}; - -// PointAdditionValidityPredicate have a custom constraint with a + b = c, -// in which a, b are private inputs and c is a public input. -pub struct PointAdditionValidityPredicate { - // basic "private" inputs to the VP - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], - // custom "private" inputs to the VP - a: TEGroupAffine, - b: TEGroupAffine, - // custom "public" inputs to the VP - pub c: TEGroupAffine, -} - -impl ValidityPredicate for PointAdditionValidityPredicate -where - CP: CircuitParameters, -{ - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes - } - - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes - } - - fn custom_constraints( - &self, - composer: &mut StandardComposer, - _input_note_variables: &[ValidityPredicateInputNoteVariables], - _output_note_variables: &[ValidityPredicateOutputNoteVariables], - ) -> Result<(), Error> { - let var_a = composer.add_affine(self.a); - let var_b = composer.add_affine(self.b); - let var_a_plus_b = - point_addition_gadget::(composer, var_a, var_b); - composer.assert_equal_public_point(var_a_plus_b, self.c); - Ok(()) - } -} - -impl Circuit for PointAdditionValidityPredicate -where - CP: CircuitParameters, -{ - const CIRCUIT_ID: [u8; 32] = [0x00; 32]; - - // Default implementation - fn gadget( - &mut self, - composer: &mut StandardComposer, - ) -> Result<(), Error> { - self.gadget_vp(composer) - } - - fn padded_circuit_size(&self) -> usize { - 1 << 17 - } -} - -#[ignore] -#[test] -fn test_point_addition_vp_example() { - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - type Fr = ::CurveScalarField; - type P = ::InnerCurve; - type PC = ::CurvePC; - type Fq = ::CurveBaseField; - type OP = ::Curve; - type Opc = ::OuterCurvePC; - use ark_ec::TEModelParameters; - use ark_poly_commit::PolynomialCommitment; - use ark_std::test_rng; - use plonk_core::circuit::{verify_proof, VerifierData}; - - // (useless) notes - let mut rng = test_rng(); - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - - let (x, y) = P::AFFINE_GENERATOR_COEFFS; - let a = TEGroupAffine::

::new(x, y); - let b = TEGroupAffine::

::new(x, y); - let c = a + b; - let mut point_addition_vp = PointAdditionValidityPredicate { - input_notes, - output_notes, - a, - b, - c, - }; - - // Generate vp CRS - let vp_setup = PC::setup(point_addition_vp.padded_circuit_size(), None, &mut rng).unwrap(); - - // Compile vp(must use compile_with_blinding) - let (pk, vk_blind) = point_addition_vp.compile::(&vp_setup).unwrap(); - - // VP Prover - let (proof, public_input) = point_addition_vp - .gen_proof::(&vp_setup, pk, b"Test") - .unwrap(); - - // VP verifier - let verifier_data = VerifierData::new(vk_blind, public_input); - verify_proof::( - &vp_setup, - verifier_data.key, - &proof, - &verifier_data.pi, - b"Test", - ) - .unwrap(); -} diff --git a/taiga_zk_garage/src/circuit/vp_examples/scalar_multiplication.rs b/taiga_zk_garage/src/circuit/vp_examples/scalar_multiplication.rs deleted file mode 100644 index 737d4416..00000000 --- a/taiga_zk_garage/src/circuit/vp_examples/scalar_multiplication.rs +++ /dev/null @@ -1,127 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::circuit::gadgets::scalar_multiplication::scalar_multiplication_gadget; -use crate::circuit::integrity::{ - ValidityPredicateInputNoteVariables, ValidityPredicateOutputNoteVariables, -}; -use crate::circuit::validity_predicate::{ValidityPredicate, NUM_NOTE}; -use crate::note::Note; -use ark_ec::twisted_edwards_extended::GroupAffine as TEGroupAffine; -use plonk_core::{circuit::Circuit, constraint_system::StandardComposer, prelude::Error}; - -// ScalarMultiplicationValidityPredicate have a custom constraint with a + b = c, -// in which a, b are private inputs and c is a public input. -pub struct ScalarMultiplicationValidityPredicate { - // basic "private" inputs to the VP - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], - // custom "private" inputs to the VP - n: CP::CurveScalarField, - // custom "public" inputs to the VP - pub c: TEGroupAffine, -} - -impl ValidityPredicate for ScalarMultiplicationValidityPredicate -where - CP: CircuitParameters, -{ - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes - } - - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes - } - - fn custom_constraints( - &self, - composer: &mut StandardComposer, - _input_note_variables: &[ValidityPredicateInputNoteVariables], - _output_note_variables: &[ValidityPredicateOutputNoteVariables], - ) -> Result<(), Error> { - let var_n = composer.add_input(self.n); - let output = - scalar_multiplication_gadget::(composer, var_n); - composer.assert_equal_public_point(output, self.c); - Ok(()) - } -} - -impl Circuit for ScalarMultiplicationValidityPredicate -where - CP: CircuitParameters, -{ - const CIRCUIT_ID: [u8; 32] = [0x00; 32]; - - // Default implementation - fn gadget( - &mut self, - composer: &mut StandardComposer, - ) -> Result<(), Error> { - self.gadget_vp(composer) - } - - fn padded_circuit_size(&self) -> usize { - 1 << 17 - } -} - -#[ignore] -#[test] -fn test_scalar_multiplication_vp_example() { - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - type Fr = ::CurveScalarField; - type P = ::InnerCurve; - type PC = ::CurvePC; - type Fq = ::CurveBaseField; - type OP = ::Curve; - type Opc = ::OuterCurvePC; - use ark_ec::group::Group; - use ark_ec::TEModelParameters; - use ark_poly_commit::PolynomialCommitment; - use ark_std::test_rng; - use plonk_core::circuit::{verify_proof, VerifierData}; - - // (useless) notes - let mut rng = test_rng(); - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - - let (x, y) = P::AFFINE_GENERATOR_COEFFS; - let fixed_base = TEGroupAffine::

::new(x, y); - // for a generic n, we need to use a InnerCurveScalarField element and then convert it to a Fr element for the circuit - let n = Fr::from(12); - let c = fixed_base.double().double().double() + fixed_base.double().double(); - let mut scalar_multiplication_vp = ScalarMultiplicationValidityPredicate { - input_notes, - output_notes, - n, - c, - }; - - // Generate vp CRS - let vp_setup = PC::setup( - scalar_multiplication_vp.padded_circuit_size(), - None, - &mut rng, - ) - .unwrap(); - - // Compile vp(must use compile_with_blinding) - let (pk, vk_blind) = scalar_multiplication_vp.compile::(&vp_setup).unwrap(); - - // VP Prover - let (proof, public_input) = scalar_multiplication_vp - .gen_proof::(&vp_setup, pk, b"Test") - .unwrap(); - - // VP verifier - let verifier_data = VerifierData::new(vk_blind, public_input); - verify_proof::( - &vp_setup, - verifier_data.key, - &proof, - &verifier_data.pi, - b"Test", - ) - .unwrap(); -} diff --git a/taiga_zk_garage/src/circuit/vp_examples/white_list_apps.rs b/taiga_zk_garage/src/circuit/vp_examples/white_list_apps.rs deleted file mode 100644 index 0885948c..00000000 --- a/taiga_zk_garage/src/circuit/vp_examples/white_list_apps.rs +++ /dev/null @@ -1,159 +0,0 @@ -use crate::app::App; -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::circuit::gadgets::merkle_tree::merkle_tree_gadget; -use crate::circuit::integrity::{ - ValidityPredicateInputNoteVariables, ValidityPredicateOutputNoteVariables, -}; -use crate::circuit::validity_predicate::{ValidityPredicate, NUM_NOTE}; -use crate::merkle_tree::{MerklePath, Node}; -use crate::note::Note; -use crate::poseidon::WIDTH_3; -use plonk_core::{circuit::Circuit, constraint_system::StandardComposer, prelude::Error}; -use plonk_hashing::poseidon::constants::PoseidonConstants; - -// WhiteListAppsValidityPredicate have a custom constraint checking that the received notes come from known senders. -pub struct WhiteListAppsValidityPredicate { - // basic "private" inputs to the VP - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], - // custom "private" inputs to the VP - white_list_apps: Vec>, - mk_root: Node>, - paths: Vec>>, -} - -impl ValidityPredicate for WhiteListAppsValidityPredicate -where - CP: CircuitParameters, -{ - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes - } - - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes - } - - fn custom_constraints( - &self, - composer: &mut StandardComposer, - _input_note_variables: &[ValidityPredicateInputNoteVariables], - output_note_variables: &[ValidityPredicateOutputNoteVariables], - ) -> Result<(), Error> { - let expected_var = composer.add_input(self.mk_root.inner()); - let poseidon_hash_param_bls12_381_new_scalar_arity2 = - PoseidonConstants::generate::(); - for (output_note_variable, path) in output_note_variables.iter().zip(self.paths.clone()) { - let app_var = output_note_variable.app_addr; - let root_var = merkle_tree_gadget::< - CP::CurveScalarField, - CP::InnerCurve, - PoseidonConstants, - >( - composer, - &app_var, - &path.get_path(), - &poseidon_hash_param_bls12_381_new_scalar_arity2, - ) - .unwrap(); - composer.assert_equal(expected_var, root_var); - } - Ok(()) - } -} - -impl Circuit for WhiteListAppsValidityPredicate -where - CP: CircuitParameters, -{ - const CIRCUIT_ID: [u8; 32] = [0x00; 32]; - - // Default implementation - fn gadget( - &mut self, - composer: &mut StandardComposer, - ) -> Result<(), Error> { - self.gadget_vp(composer) - } - - fn padded_circuit_size(&self) -> usize { - 1 << 17 - } -} - -#[ignore] -#[test] -fn test_white_list_apps_vp_example() { - use plonk_core::circuit::{verify_proof, VerifierData}; - - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use crate::merkle_tree::MerkleTreeLeafs; - use crate::poseidon::WIDTH_3; - use ark_std::test_rng; - - type Fr = ::CurveScalarField; - type P = ::InnerCurve; - type PC = ::CurvePC; - - let mut rng = test_rng(); - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - - // white list is a list of app addresses, containing the output note app addresses. - let white_list_apps: Vec> = vec![ - App::::dummy(&mut rng), - output_notes[1].app.clone(), - App::::dummy(&mut rng), - App::::dummy(&mut rng), - output_notes[3].app.clone(), - output_notes[2].app.clone(), - App::::dummy(&mut rng), - output_notes[0].app.clone(), - App::::dummy(&mut rng), - ]; - - let white_list_apps_to_fields: Vec = white_list_apps - .iter() - .map(|v| v.address().unwrap()) - .collect(); - - let poseidon_hash_param_bls12_381_new_scalar_arity2 = PoseidonConstants::generate::(); - let mk_root = - MerkleTreeLeafs::>::new(white_list_apps_to_fields.to_vec()) - .root(&poseidon_hash_param_bls12_381_new_scalar_arity2); - - let paths: Vec>> = vec![ - MerklePath::build_merkle_path(&white_list_apps_to_fields, 7), - MerklePath::build_merkle_path(&white_list_apps_to_fields, 1), - MerklePath::build_merkle_path(&white_list_apps_to_fields, 5), - MerklePath::build_merkle_path(&white_list_apps_to_fields, 4), - ]; - - let mut white_list_apps_vp = WhiteListAppsValidityPredicate { - input_notes, - output_notes, - white_list_apps, - mk_root, - paths, - }; - let mut composer = StandardComposer::::new(); - white_list_apps_vp.gadget(&mut composer).unwrap(); - composer.check_circuit_satisfied(); - println!( - "circuit size of white_list_apps_vp: {}", - composer.circuit_bound() - ); - - // Generate CRS - let pp = CP::get_pc_setup_params(white_list_apps_vp.padded_circuit_size()); - - // Compile the circuit - let (pk, vk) = white_list_apps_vp.compile::(pp).unwrap(); - - // Prover - let (proof, public_input) = white_list_apps_vp.gen_proof::(pp, pk, b"Test").unwrap(); - - // Verifier - let verifier_data = VerifierData::new(vk, public_input); - verify_proof::(pp, verifier_data.key, &proof, &verifier_data.pi, b"Test").unwrap(); -} diff --git a/taiga_zk_garage/src/circuit/vp_examples/white_list_senders.rs b/taiga_zk_garage/src/circuit/vp_examples/white_list_senders.rs deleted file mode 100644 index d3b95195..00000000 --- a/taiga_zk_garage/src/circuit/vp_examples/white_list_senders.rs +++ /dev/null @@ -1,163 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::circuit::gadgets::merkle_tree::merkle_tree_gadget; -use crate::circuit::integrity::{ - ValidityPredicateInputNoteVariables, ValidityPredicateOutputNoteVariables, -}; -use crate::circuit::validity_predicate::{ValidityPredicate, NUM_NOTE}; -use crate::merkle_tree::{MerklePath, Node}; -use crate::note::Note; -use crate::poseidon::WIDTH_3; -use crate::user::User; -use plonk_core::{circuit::Circuit, constraint_system::StandardComposer, prelude::Error}; -use plonk_hashing::poseidon::constants::PoseidonConstants; - -// WhiteListSendersValidityPredicate have a custom constraint checking that the received notes come from known senders. -pub struct WhiteListSendersValidityPredicate { - // basic "private" inputs to the VP - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], - // custom "private" inputs to the VP - white_list_senders: Vec>, - mk_root: Node>, - paths: Vec>>, -} - -impl ValidityPredicate for WhiteListSendersValidityPredicate -where - CP: CircuitParameters, -{ - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes - } - - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes - } - - fn custom_constraints( - &self, - composer: &mut StandardComposer, - _input_note_variables: &[ValidityPredicateInputNoteVariables], - output_note_variables: &[ValidityPredicateOutputNoteVariables], - ) -> Result<(), Error> { - let expected_var = composer.add_input(self.mk_root.inner()); - let poseidon_hash_param_bls12_381_new_scalar_arity2 = - PoseidonConstants::generate::(); - for (output_note_variable, path) in output_note_variables.iter().zip(self.paths.clone()) { - let owner_var = output_note_variable.recipient_addr; - let root_var = merkle_tree_gadget::< - CP::CurveScalarField, - CP::InnerCurve, - PoseidonConstants, - >( - composer, - &owner_var, - &path.get_path(), - &poseidon_hash_param_bls12_381_new_scalar_arity2, - ) - .unwrap(); - composer.assert_equal(expected_var, root_var); - } - Ok(()) - } -} - -impl Circuit for WhiteListSendersValidityPredicate -where - CP: CircuitParameters, -{ - const CIRCUIT_ID: [u8; 32] = [0x00; 32]; - - // Default implementation - fn gadget( - &mut self, - composer: &mut StandardComposer, - ) -> Result<(), Error> { - self.gadget_vp(composer) - } - - fn padded_circuit_size(&self) -> usize { - 1 << 17 - } -} - -#[ignore] -#[test] -fn test_white_list_senders_vp_example() { - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use crate::merkle_tree::MerkleTreeLeafs; - use crate::poseidon::WIDTH_3; - use ark_std::test_rng; - use plonk_core::circuit::{verify_proof, VerifierData}; - - type Fr = ::CurveScalarField; - type P = ::InnerCurve; - type PC = ::CurvePC; - - let mut rng = test_rng(); - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - - // white list is a list of user addresses, containing the output notes addresses. - let white_list_senders: Vec> = vec![ - User::::dummy(&mut rng), - output_notes[1].user.clone(), - User::::dummy(&mut rng), - User::::dummy(&mut rng), - output_notes[3].user.clone(), - output_notes[2].user.clone(), - User::::dummy(&mut rng), - output_notes[0].user.clone(), - User::::dummy(&mut rng), - User::::dummy(&mut rng), - User::::dummy(&mut rng), - ]; - - let white_list_senders_to_fields: Vec = white_list_senders - .iter() - .map(|v| v.address().unwrap()) - .collect(); - - let poseidon_hash_param_bls12_381_new_scalar_arity2 = PoseidonConstants::generate::(); - let mk_root = - MerkleTreeLeafs::>::new(white_list_senders_to_fields.to_vec()) - .root(&poseidon_hash_param_bls12_381_new_scalar_arity2); - - let paths: Vec>> = vec![ - MerklePath::build_merkle_path(&white_list_senders_to_fields, 7), - MerklePath::build_merkle_path(&white_list_senders_to_fields, 1), - MerklePath::build_merkle_path(&white_list_senders_to_fields, 5), - MerklePath::build_merkle_path(&white_list_senders_to_fields, 4), - ]; - - let mut white_list_senders_vp = WhiteListSendersValidityPredicate { - input_notes, - output_notes, - white_list_senders, - mk_root, - paths, - }; - - let mut composer = StandardComposer::::new(); - white_list_senders_vp.gadget(&mut composer).unwrap(); - composer.check_circuit_satisfied(); - println!( - "circuit size of white_list_senders_vp: {}", - composer.circuit_bound() - ); - - // Generate CRS - let pp = CP::get_pc_setup_params(white_list_senders_vp.padded_circuit_size()); - - // Compile the circuit - let (pk, vk) = white_list_senders_vp.compile::(pp).unwrap(); - - // Prover - let (proof, public_input) = white_list_senders_vp - .gen_proof::(pp, pk, b"Test") - .unwrap(); - - // Verifier - let verifier_data = VerifierData::new(vk, public_input); - verify_proof::(pp, verifier_data.key, &proof, &verifier_data.pi, b"Test").unwrap(); -} diff --git a/taiga_zk_garage/src/constant.rs b/taiga_zk_garage/src/constant.rs deleted file mode 100644 index 8afca05d..00000000 --- a/taiga_zk_garage/src/constant.rs +++ /dev/null @@ -1,82 +0,0 @@ -use crate::action::ActionInfo; -use crate::circuit::blinding_circuit::BlindingCircuit; -use crate::circuit::circuit_parameters::PairingCircuitParameters; -use ark_poly::univariate::DensePolynomial; -use ark_poly_commit::PolynomialCommitment; -use lazy_static::lazy_static; -use plonk_core::circuit::Circuit; -use plonk_core::commitment::KZG10; -use plonk_core::proof_system::{ProverKey, VerifierKey}; -use rand_core::OsRng; -use std::collections::HashMap; - -pub const CIRCUIT_SIZE_2_15: usize = 1 << 15; -pub const CIRCUIT_SIZE_2_16: usize = 1 << 16; -pub const CIRCUIT_SIZE_2_17: usize = 1 << 17; -pub const BLINDING_CIRCUIT_SIZE: usize = CIRCUIT_SIZE_2_15; -pub const ACTION_CIRCUIT_SIZE: usize = CIRCUIT_SIZE_2_15; -pub const ACTION_PUBLIC_INPUT_NF_INDEX: usize = 10781; -pub const ACTION_PUBLIC_INPUT_ROOT_INDEX: usize = 24766; -pub const ACTION_PUBLIC_INPUT_CM_INDEX: usize = 31822; - -lazy_static! { - pub static ref PC_SETUP_MAP: HashMap< - usize, - as PolynomialCommitment< - ark_bls12_381_new::Fr, - DensePolynomial, - >>::UniversalParams, - > = { - let mut m = HashMap::new(); - for circuit_size in &[CIRCUIT_SIZE_2_15, CIRCUIT_SIZE_2_16, CIRCUIT_SIZE_2_17] { - let setup = - KZG10::::setup(*circuit_size, None, &mut OsRng) - .unwrap(); - m.insert(*circuit_size, setup); - } - m - }; -} - -lazy_static! { - pub static ref OPC_SETUP_MAP: HashMap< - usize, - as PolynomialCommitment< - ark_bw6_764_new::Fr, - DensePolynomial, - >>::UniversalParams, - > = { - let mut m = HashMap::new(); - // for circuit_size in &[CIRCUIT_SIZE_2_15] { - let setup = - KZG10::::setup(CIRCUIT_SIZE_2_15, None, &mut OsRng).unwrap(); - m.insert(CIRCUIT_SIZE_2_15, setup); - // } - m - }; -} - -lazy_static! { - pub static ref ACTION_KEY: (ProverKey, VerifierKey>) = { - let action_info = ActionInfo::::dummy(&mut OsRng); - let (_action, mut action_circuit) = action_info.build(&mut OsRng).unwrap(); - - // Generate CRS - let pp = PC_SETUP_MAP.get(&ACTION_CIRCUIT_SIZE).unwrap(); - - // Compile the circuit - action_circuit.compile::>(pp).unwrap() - }; -} - -lazy_static! { - pub static ref BLIND_VP_KEY: (ProverKey, VerifierKey>) = { - let mut blinding_circuit = BlindingCircuit::::dummy(&mut OsRng); - - // Generate CRS - let pp = OPC_SETUP_MAP.get(&BLINDING_CIRCUIT_SIZE).unwrap(); - - // Compile the circuit - blinding_circuit.compile::>(pp).unwrap() - }; -} diff --git a/taiga_zk_garage/src/doc_examples.rs b/taiga_zk_garage/src/doc_examples.rs deleted file mode 100644 index 7e118c91..00000000 --- a/taiga_zk_garage/src/doc_examples.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod addition_circuit; -mod app; -mod blinding; -mod note; -mod transaction; -mod user; -mod validity_predicate; diff --git a/taiga_zk_garage/src/doc_examples/addition_circuit.rs b/taiga_zk_garage/src/doc_examples/addition_circuit.rs deleted file mode 100644 index 64a9d9f7..00000000 --- a/taiga_zk_garage/src/doc_examples/addition_circuit.rs +++ /dev/null @@ -1,191 +0,0 @@ -use ark_ec::TEModelParameters; -use ark_ff::PrimeField; -use plonk_core::prelude::{Circuit, Error, StandardComposer}; - -pub struct AdditionCircuit { - a: F, - b: F, - pub c: F, -} - -impl Circuit for AdditionCircuit -where - F: PrimeField, - P: TEModelParameters, -{ - const CIRCUIT_ID: [u8; 32] = [0x00; 32]; - - // Default implementation - fn gadget(&mut self, composer: &mut StandardComposer) -> Result<(), Error> { - let var_a = composer.add_input(self.a); - let var_b = composer.add_input(self.b); - // add a gate for the addition - let var_zero = composer.zero_var(); - // Make first constraint a + b = c (as public input) - composer.arithmetic_gate(|gate| { - gate.witness(var_a, var_b, Some(var_zero)) - .add(F::one(), F::one()) - .pi(-self.c) - }); - composer.check_circuit_satisfied(); - Ok(()) - } - - fn padded_circuit_size(&self) -> usize { - 1 << 3 - } -} - -#[ignore] -#[test] -fn test_circuit_example() { - use crate::circuit::circuit_parameters::CircuitParameters; - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - type F = ::CurveScalarField; - type P = ::InnerCurve; - type PC = ::CurvePC; - use ark_poly_commit::PolynomialCommitment; - use ark_std::{test_rng, UniformRand}; - use plonk_core::circuit::{verify_proof, VerifierData}; - - let mut rng = test_rng(); - let a = F::rand(&mut rng); - let b = F::rand(&mut rng); - let c = a + b; - - // Circuit - let mut circuit = AdditionCircuit:: { a, b, c }; - // Setup - let setup = PC::setup( - Circuit::::padded_circuit_size(&circuit), - None, - &mut rng, - ) - .unwrap(); - // Prover and verifier key - let (pk, vk) = Circuit::::compile::(&mut circuit, &setup).unwrap(); - // Proof computation - let (proof, public_inputs) = - Circuit::::gen_proof::(&mut circuit, &setup, pk, b"Test").unwrap(); - // Proof verification - let verifier_data = VerifierData::new(vk, public_inputs); - verify_proof::( - &setup, - verifier_data.key, - &proof, - &verifier_data.pi, - b"Test", - ) - .unwrap(); -} - -#[ignore] -#[test] -fn test_app_creation() { - use crate::app::App; - use crate::circuit::circuit_parameters::CircuitParameters; - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use crate::circuit::validity_predicate::NUM_NOTE; - use crate::doc_examples::validity_predicate::TrivialValidityPredicate; - use crate::note::Note; - use crate::vp_description::ValidityPredicateDescription; - use ark_std::test_rng; - - type Fr = ::CurveScalarField; - type PC = ::CurvePC; - - let mut rng = test_rng(); - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - - let mut vp = TrivialValidityPredicate::::new(input_notes, output_notes); - - let vp_setup = CP::get_pc_setup_params(vp.padded_circuit_size()); - let desc_vp = ValidityPredicateDescription::from_vp(&mut vp, vp_setup).unwrap(); - - let app = App::::new(desc_vp); - - let _tok_addr = app.address().unwrap(); -} - -/////////////////////////////////////////////////////////////////////// - -#[ignore] -#[test] -fn test_user_creation() { - use crate::circuit::circuit_parameters::CircuitParameters; - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use crate::circuit::validity_predicate::NUM_NOTE; - use crate::doc_examples::validity_predicate::TrivialValidityPredicate; - use crate::note::Note; - use crate::user::NullifierDerivingKey; - use crate::user::User; - use crate::vp_description::ValidityPredicateDescription; - use ark_std::test_rng; - - type Fr = ::CurveScalarField; - type PC = ::CurvePC; - - let mut rng = test_rng(); - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - - let mut vp = TrivialValidityPredicate::::new(input_notes, output_notes); - - let vp_setup = CP::get_pc_setup_params(vp.padded_circuit_size()); - - let desc_vp_send = ValidityPredicateDescription::from_vp(&mut vp, vp_setup).unwrap(); - let desc_vp_recv = desc_vp_send.clone(); - - let alice = User::::new( - desc_vp_send, - desc_vp_recv, - NullifierDerivingKey::::rand(&mut rng), - ); - let _alice_addr = alice.address().unwrap(); -} - -#[ignore] -#[test] -fn test_note_creation() { - use crate::app::App; - use crate::circuit::circuit_parameters::CircuitParameters; - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use crate::circuit::validity_predicate::NUM_NOTE; - use crate::doc_examples::validity_predicate::TrivialValidityPredicate; - use crate::note::Note; - use crate::nullifier::Nullifier; - use crate::user::NullifierDerivingKey; - use crate::user::User; - use crate::vp_description::ValidityPredicateDescription; - use ark_ff::UniformRand; - use ark_std::test_rng; - - type Fr = ::CurveScalarField; - type PC = ::CurvePC; - - let mut rng = test_rng(); - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - - let mut vp = TrivialValidityPredicate::::new(input_notes, output_notes); - - let vp_setup = CP::get_pc_setup_params(vp.padded_circuit_size()); - - // app and user - let desc_vp_app = ValidityPredicateDescription::from_vp(&mut vp, vp_setup).unwrap(); - let desc_vp_send = desc_vp_app.clone(); - let desc_vp_recv = desc_vp_send.clone(); - - let app = App::::new(desc_vp_app); - let alice = User::::new( - desc_vp_send, - desc_vp_recv, - NullifierDerivingKey::::rand(&mut rng), - ); - // note - let nf = Nullifier::::new(Fr::rand(&mut rng)); - let note = Note::::new(alice, app, 12, nf, Fr::rand(&mut rng), Fr::rand(&mut rng)); - - let _note_commitment = note.commitment(); -} diff --git a/taiga_zk_garage/src/doc_examples/app.rs b/taiga_zk_garage/src/doc_examples/app.rs deleted file mode 100644 index 566acfac..00000000 --- a/taiga_zk_garage/src/doc_examples/app.rs +++ /dev/null @@ -1,30 +0,0 @@ -#[ignore] -#[test] -fn test_app_creation() { - use ark_std::test_rng; - use plonk_core::prelude::Circuit; - - use crate::app::App; - use crate::circuit::circuit_parameters::CircuitParameters; - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use crate::circuit::validity_predicate::NUM_NOTE; - use crate::doc_examples::validity_predicate::TrivialValidityPredicate; - use crate::note::Note; - use crate::vp_description::ValidityPredicateDescription; - - type Fr = ::CurveScalarField; - type PC = ::CurvePC; - - let mut rng = test_rng(); - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - - let mut vp = TrivialValidityPredicate::::new(input_notes, output_notes); - - let vp_setup = CP::get_pc_setup_params(vp.padded_circuit_size()); - let desc_vp = ValidityPredicateDescription::from_vp(&mut vp, vp_setup).unwrap(); - - let app = App::::new(desc_vp); - - let _tok_addr = app.address().unwrap(); -} diff --git a/taiga_zk_garage/src/doc_examples/blinding.rs b/taiga_zk_garage/src/doc_examples/blinding.rs deleted file mode 100644 index 39db1c9b..00000000 --- a/taiga_zk_garage/src/doc_examples/blinding.rs +++ /dev/null @@ -1,89 +0,0 @@ -#[ignore] -#[test] -fn test_blinding_circuit_example() { - use crate::circuit::blinding_circuit::BlindingCircuit; - use crate::circuit::circuit_parameters::CircuitParameters; - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use crate::circuit::validity_predicate::NUM_NOTE; - use crate::note::Note; - use crate::utils::ws_to_te; - use crate::vp_description::ValidityPredicateDescription; - use plonk_core::prelude::Circuit; - use plonk_core::prelude::{verify_proof, VerifierData}; - use plonk_core::proof_system::pi::PublicInputs; - type Fr = ::CurveScalarField; - type Fq = ::CurveBaseField; - type P = ::InnerCurve; - type OP = ::Curve; - type PC = ::CurvePC; - type Opc = ::OuterCurvePC; - use crate::doc_examples::validity_predicate::TrivialValidityPredicate; - use ark_std::test_rng; - - let mut rng = test_rng(); - - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let output_notes = input_notes.clone(); - - // Create a trivial vp - let mut vp = TrivialValidityPredicate::::new(input_notes, output_notes); - - // we blind the VP desc - let pp = CP::get_pc_setup_params(vp.padded_circuit_size()); - let vp_desc = ValidityPredicateDescription::from_vp(&mut vp, pp).unwrap(); - let vp_desc_compressed = vp_desc.get_compressed(); - - // the blinding circuit, containing the random values used to blind - let mut blinding_circuit = - BlindingCircuit::::new(&mut rng, vp_desc, pp, vp.padded_circuit_size()).unwrap(); - - // vp verifying key with the blinding - let (_, vk_blinded) = vp - .compile_with_blinding::(pp, &blinding_circuit.get_blinding()) - .unwrap(); - - let pp_blind = CP::get_opc_setup_params(blinding_circuit.padded_circuit_size()); - - // prover and verifier key for the blinding proof - let (pk_blinding, vk_blinding) = blinding_circuit.compile::(pp_blind).unwrap(); - - // Blinding Prover - let (proof, public_inputs) = blinding_circuit - .gen_proof::(pp_blind, pk_blinding, b"Test") - .unwrap(); - - // Expecting vk_blind(out of circuit) - let mut expected_public_inputs = PublicInputs::new(); - let q_m = ws_to_te(vk_blinded.arithmetic.q_m.0); - expected_public_inputs.insert(392, q_m.x); - expected_public_inputs.insert(393, q_m.y); - let q_l = ws_to_te(vk_blinded.arithmetic.q_l.0); - expected_public_inputs.insert(782, q_l.x); - expected_public_inputs.insert(783, q_l.y); - let q_r = ws_to_te(vk_blinded.arithmetic.q_r.0); - expected_public_inputs.insert(1172, q_r.x); - expected_public_inputs.insert(1173, q_r.y); - let q_o = ws_to_te(vk_blinded.arithmetic.q_o.0); - expected_public_inputs.insert(1562, q_o.x); - expected_public_inputs.insert(1563, q_o.y); - let q_4 = ws_to_te(vk_blinded.arithmetic.q_4.0); - expected_public_inputs.insert(1952, q_4.x); - expected_public_inputs.insert(1953, q_4.y); - let q_c = ws_to_te(vk_blinded.arithmetic.q_c.0); - expected_public_inputs.insert(2342, q_c.x); - expected_public_inputs.insert(2343, q_c.y); - expected_public_inputs.insert(21388, vp_desc_compressed); - - assert_eq!(public_inputs, expected_public_inputs); - - // Blinding Verifier - let verifier_data = VerifierData::new(vk_blinding, public_inputs); - verify_proof::( - pp_blind, - verifier_data.key, - &proof, - &verifier_data.pi, - b"Test", - ) - .unwrap(); -} diff --git a/taiga_zk_garage/src/doc_examples/note.rs b/taiga_zk_garage/src/doc_examples/note.rs deleted file mode 100644 index a3ac4c8c..00000000 --- a/taiga_zk_garage/src/doc_examples/note.rs +++ /dev/null @@ -1,45 +0,0 @@ -#[ignore] -#[test] -fn test_note_creation() { - use crate::app::App; - use crate::circuit::circuit_parameters::CircuitParameters; - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use crate::circuit::validity_predicate::NUM_NOTE; - use crate::doc_examples::validity_predicate::TrivialValidityPredicate; - use crate::note::Note; - use crate::nullifier::Nullifier; - use crate::user::NullifierDerivingKey; - use crate::user::User; - use crate::vp_description::ValidityPredicateDescription; - use ark_ff::UniformRand; - use ark_std::test_rng; - use plonk_core::prelude::Circuit; - - type Fr = ::CurveScalarField; - type PC = ::CurvePC; - - let mut rng = test_rng(); - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - - let mut vp = TrivialValidityPredicate::::new(input_notes, output_notes); - - let vp_setup = CP::get_pc_setup_params(vp.padded_circuit_size()); - - // app and user - let desc_vp_app = ValidityPredicateDescription::from_vp(&mut vp, vp_setup).unwrap(); - let desc_vp_send = desc_vp_app.clone(); - let desc_vp_recv = desc_vp_send.clone(); - - let app = App::::new(desc_vp_app); - let alice = User::::new( - desc_vp_send, - desc_vp_recv, - NullifierDerivingKey::::rand(&mut rng), - ); - // note - let nf = Nullifier::::new(Fr::rand(&mut rng)); - let note = Note::::new(alice, app, 12, nf, Fr::rand(&mut rng), Fr::rand(&mut rng)); - - let _note_commitment = note.commitment(); -} diff --git a/taiga_zk_garage/src/doc_examples/transaction.rs b/taiga_zk_garage/src/doc_examples/transaction.rs deleted file mode 100644 index 7edb9f29..00000000 --- a/taiga_zk_garage/src/doc_examples/transaction.rs +++ /dev/null @@ -1,81 +0,0 @@ -#[ignore] -#[test] -fn test_tx_example() { - use crate::action::Action; - use crate::circuit::action_circuit::ActionCircuit; - use crate::circuit::circuit_parameters::CircuitParameters; - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use crate::circuit::validity_predicate::NUM_NOTE; - use crate::transaction::*; - type Fr = ::CurveScalarField; - type P = ::InnerCurve; - type PC = ::CurvePC; - type Fq = ::CurveBaseField; - type OP = ::Curve; - type Opc = ::OuterCurvePC; - use crate::action::ActionInfo; - use crate::doc_examples::validity_predicate::TrivialValidityPredicate; - use crate::note::Note; - use ark_std::test_rng; - - let mut rng = test_rng(); - - // Construct action infos - let mut actions: Vec<(Action, ActionCircuit)> = (0..NUM_TX_SLICE) - .map(|_| { - let action_info = ActionInfo::::dummy(&mut rng); - action_info.build(&mut rng).unwrap() - }) - .collect(); - - // Generate action proofs - let action_slices: Vec> = actions - .iter_mut() - .map(|action| ActionSlice::::build(action.0, &mut action.1).unwrap()) - .collect(); - - // Collect input notes from actions - let input_notes_vec: Vec> = actions - .iter() - .map(|action| action.1.spend_note.clone()) - .collect(); - let input_notes: [Note; NUM_NOTE] = input_notes_vec.try_into().unwrap(); - - // Collect output notes from actions - let output_notes_vec: Vec> = actions - .iter() - .map(|action| action.1.output_note.clone()) - .collect(); - let output_notes: [Note; NUM_NOTE] = output_notes_vec.try_into().unwrap(); - - // Construct VPs and generate VP proofs and blind VP proofs - let mut spend_slices = vec![]; - let mut output_slices = vec![]; - for _action_index in 0..NUM_TX_SLICE { - // Construct dummy spend slice - let mut spend_addr_vp = - TrivialValidityPredicate::::new(input_notes.clone(), output_notes.clone()); - let spend_addr_vp_check = VPCheck::build(&mut spend_addr_vp, &mut rng).unwrap(); - let mut spend_app_vp = - TrivialValidityPredicate::::new(input_notes.clone(), output_notes.clone()); - let spend_app_vp_check = VPCheck::build(&mut spend_app_vp, &mut rng).unwrap(); - let spend_slice = SpendSlice::new(spend_addr_vp_check, spend_app_vp_check); - spend_slices.push(spend_slice); - - // Construct dummy output vps - let mut output_addr_vp = - TrivialValidityPredicate::::new(input_notes.clone(), output_notes.clone()); - let output_addr_vp_check = VPCheck::build(&mut output_addr_vp, &mut rng).unwrap(); - let mut output_app_vp = - TrivialValidityPredicate::::new(input_notes.clone(), output_notes.clone()); - let output_app_vp_check = VPCheck::build(&mut output_app_vp, &mut rng).unwrap(); - let output_slice = OutputSlice::new(output_addr_vp_check, output_app_vp_check); - output_slices.push(output_slice); - } - - // Construct a tx - let tx = Transaction::::new(action_slices, spend_slices, output_slices); - - // Verify the tx - tx.verify().unwrap(); -} diff --git a/taiga_zk_garage/src/doc_examples/user.rs b/taiga_zk_garage/src/doc_examples/user.rs deleted file mode 100644 index 0be61d72..00000000 --- a/taiga_zk_garage/src/doc_examples/user.rs +++ /dev/null @@ -1,190 +0,0 @@ -use crate::app::App; -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::circuit::integrity::{ - app_integrity_circuit, ValidityPredicateInputNoteVariables, - ValidityPredicateOutputNoteVariables, -}; -use crate::circuit::validity_predicate::{ValidityPredicate, NUM_NOTE}; -use crate::note::Note; -use ark_std; -use plonk_core::{circuit::Circuit, constraint_system::StandardComposer, prelude::Error}; - -pub struct SendVP { - // basic "private" inputs to the VP - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], -} - -impl SendVP { - pub fn new(input_notes: [Note; NUM_NOTE], output_notes: [Note; NUM_NOTE]) -> Self { - SendVP { - input_notes, - output_notes, - } - } -} - -impl ValidityPredicate for SendVP -where - CP: CircuitParameters, -{ - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes - } - - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes - } - - fn custom_constraints( - &self, - composer: &mut StandardComposer, - input_note_variables: &[ValidityPredicateInputNoteVariables], - _output_note_variables: &[ValidityPredicateOutputNoteVariables], - ) -> Result<(), Error> { - // * Alice does not want to send more than 3 XAN at a time. - let mut rng = ark_std::test_rng(); - let xan_app = - App::::dummy(&mut rng); - - let (xan_address_var, _) = - app_integrity_circuit::(composer, &xan_app.app_vp.to_bits())?; - - // Check that the app of all the notes of app XAN are less than 3 XAN - for note_var in input_note_variables { - composer.assert_equal(note_var.app_addr, xan_address_var); - // TODO: Check that the note value is less than 3 - } - - Ok(()) - } -} - -impl Circuit for SendVP -where - CP: CircuitParameters, -{ - const CIRCUIT_ID: [u8; 32] = [0x00; 32]; - - // Default implementation - fn gadget( - &mut self, - composer: &mut StandardComposer, - ) -> Result<(), Error> { - self.gadget_vp(composer) - } - - fn padded_circuit_size(&self) -> usize { - 1 << 17 - } -} - -pub struct ReceiveVP { - // basic "private" inputs to the VP - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], -} - -impl ReceiveVP { - pub fn new(input_notes: [Note; NUM_NOTE], output_notes: [Note; NUM_NOTE]) -> Self { - ReceiveVP { - input_notes, - output_notes, - } - } -} - -impl ValidityPredicate for ReceiveVP -where - CP: CircuitParameters, -{ - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes - } - - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes - } - - fn custom_constraints( - &self, - composer: &mut StandardComposer, - input_note_variables: &[ValidityPredicateInputNoteVariables], - _output_note_variables: &[ValidityPredicateOutputNoteVariables], - ) -> Result<(), Error> { - // * Alice does not want to send more than 3 XAN at a time. - let mut rng = ark_std::test_rng(); - let xan_app = - App::::dummy(&mut rng); - - let (xan_address_var, _) = - app_integrity_circuit::(composer, &xan_app.app_vp.to_bits())?; - - // Check that the app of all the notes of app XAN are less than 3 XAN - for note_var in input_note_variables { - composer.assert_equal(note_var.app_addr, xan_address_var); - // TODO: Check that the note value is less than 3 - } - - Ok(()) - } -} - -impl Circuit for ReceiveVP -where - CP: CircuitParameters, -{ - const CIRCUIT_ID: [u8; 32] = [0x00; 32]; - - // Default implementation - fn gadget( - &mut self, - composer: &mut StandardComposer, - ) -> Result<(), Error> { - self.gadget_vp(composer) - } - - fn padded_circuit_size(&self) -> usize { - 1 << 17 - } -} - -#[ignore] -#[test] -fn test_user_creation() { - use plonk_core::prelude::Circuit; - - use crate::circuit::circuit_parameters::CircuitParameters; - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use crate::circuit::validity_predicate::NUM_NOTE; - use crate::note::Note; - use crate::user::NullifierDerivingKey; - use crate::user::User; - use crate::vp_description::ValidityPredicateDescription; - use ark_std::test_rng; - - type Fr = ::CurveScalarField; - type PC = ::CurvePC; - - let mut rng = test_rng(); - let send_input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let send_output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - - let mut send_vp = SendVP::::new(send_input_notes, send_output_notes); - - let receive_input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let receive_output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let mut receive_vp = ReceiveVP::::new(receive_input_notes, receive_output_notes); - - let vp_setup = CP::get_pc_setup_params(send_vp.padded_circuit_size()); - - let desc_vp_send = ValidityPredicateDescription::from_vp(&mut send_vp, vp_setup).unwrap(); - let desc_vp_recv = ValidityPredicateDescription::from_vp(&mut receive_vp, vp_setup).unwrap(); - - let alice = User::::new( - desc_vp_send, - desc_vp_recv, - NullifierDerivingKey::::rand(&mut rng), - ); - let _alice_addr = alice.address().unwrap(); -} diff --git a/taiga_zk_garage/src/doc_examples/validity_predicate.rs b/taiga_zk_garage/src/doc_examples/validity_predicate.rs deleted file mode 100644 index 5f43af10..00000000 --- a/taiga_zk_garage/src/doc_examples/validity_predicate.rs +++ /dev/null @@ -1,90 +0,0 @@ -use plonk_core::prelude::{Circuit, Error, StandardComposer}; - -use crate::circuit::circuit_parameters::CircuitParameters; - -use crate::circuit::validity_predicate::ValidityPredicate; -use crate::circuit::validity_predicate::NUM_NOTE; -use crate::note::Note; - -pub struct TrivialValidityPredicate { - input_notes: [Note; NUM_NOTE], - output_notes: [Note; NUM_NOTE], -} - -impl ValidityPredicate for TrivialValidityPredicate { - fn get_input_notes(&self) -> &[Note; NUM_NOTE] { - &self.input_notes - } - - fn get_output_notes(&self) -> &[Note; NUM_NOTE] { - &self.output_notes - } -} - -impl Circuit - for TrivialValidityPredicate -{ - const CIRCUIT_ID: [u8; 32] = [0x00; 32]; - - // Default implementation - fn gadget( - &mut self, - composer: &mut StandardComposer, - ) -> Result<(), Error> { - self.gadget_vp(composer) - } - - fn padded_circuit_size(&self) -> usize { - 1 << 17 - } -} - -impl TrivialValidityPredicate { - pub fn new(input_notes: [Note; NUM_NOTE], output_notes: [Note; NUM_NOTE]) -> Self { - Self { - input_notes, - output_notes, - } - } -} - -#[ignore] -#[test] -fn test_vp_creation() { - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - use crate::circuit::validity_predicate::NUM_NOTE; - use crate::note::Note; - use ark_std::test_rng; - use plonk_core::prelude::{verify_proof, VerifierData}; - - type Fr = ::CurveScalarField; - type PC = ::CurvePC; - type P = ::InnerCurve; - - let mut rng = test_rng(); - let input_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - let output_notes = [(); NUM_NOTE].map(|_| Note::::dummy(&mut rng)); - - // creation of the VP - let mut vp = TrivialValidityPredicate::::new(input_notes, output_notes); - - // setup of the proof system - let vp_setup = CP::get_pc_setup_params(vp.padded_circuit_size()); - - // proving and verifying keys - let (pk, vk) = vp.compile::(vp_setup).unwrap(); - - // proof - let (proof, public_inputs) = vp.gen_proof::(vp_setup, pk, b"Test").unwrap(); - - // verification - let verifier_data = VerifierData::new(vk, public_inputs); - verify_proof::( - vp_setup, - verifier_data.key, - &proof, - &verifier_data.pi, - b"Test", - ) - .unwrap(); -} diff --git a/taiga_zk_garage/src/error.rs b/taiga_zk_garage/src/error.rs deleted file mode 100644 index 55bcda73..00000000 --- a/taiga_zk_garage/src/error.rs +++ /dev/null @@ -1,27 +0,0 @@ -use plonk_core::error::Error; -use plonk_hashing::poseidon::PoseidonError; -use thiserror::Error; - -/// Represents errors. -#[derive(Error, Debug)] -pub enum TaigaError { - /// Occurs when poseidon hash operation failed. - #[error("Hash error")] - PoseidonHashError(PoseidonError), - - /// Occurs when plonk operation failed. - #[error("Plonk error")] - PlonkError(Error), -} - -impl From for TaigaError { - fn from(e: PoseidonError) -> TaigaError { - TaigaError::PoseidonHashError(e) - } -} - -impl From for TaigaError { - fn from(e: Error) -> TaigaError { - TaigaError::PlonkError(e) - } -} diff --git a/taiga_zk_garage/src/lib.rs b/taiga_zk_garage/src/lib.rs deleted file mode 100644 index 4b98386b..00000000 --- a/taiga_zk_garage/src/lib.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Temporary for annoying warning(unused implementation). -#![allow(dead_code)] -#![allow(clippy::type_complexity)] -#![allow(clippy::large_enum_variant)] - -pub mod action; -pub mod app; -pub mod circuit; -pub mod constant; -pub mod doc_examples; -pub mod error; -pub mod merkle_tree; -pub mod note; -pub mod nullifier; -pub mod poseidon; -pub mod transaction; -pub mod user; -pub mod utils; -pub mod vp_description; diff --git a/taiga_zk_garage/src/merkle_tree.rs b/taiga_zk_garage/src/merkle_tree.rs deleted file mode 100644 index 4602cc5e..00000000 --- a/taiga_zk_garage/src/merkle_tree.rs +++ /dev/null @@ -1,337 +0,0 @@ -//! Implementation of a Merkle tree of commitments used to prove the existence of notes. -//! -use crate::error::TaigaError; -use crate::poseidon::FieldHasher; -use crate::poseidon::WIDTH_3; -use ark_ff::{BigInteger, PrimeField}; -use plonk_hashing::poseidon::constants::PoseidonConstants; -use rand::{Rng, RngCore}; -use std::marker::PhantomData; - -pub const TAIGA_COMMITMENT_TREE_DEPTH: usize = 32; - -#[derive(Clone)] -pub struct MerkleTreeLeafs> { - leafs: Vec>, -} - -impl> MerkleTreeLeafs { - pub fn new(values: Vec) -> Self { - let nodes_vec = values - .iter() - .map(|x| Node::::new(*x)) - .collect::>(); - Self { leafs: nodes_vec } - } - - pub fn root(&mut self, hasher: &BH) -> Node { - // the list of leafs is extended with copies of elements so that its length is a power of 2. - let list = &mut self.leafs; - let n = list.len(); - let m = n.next_power_of_two(); - let mut ext = list.clone(); - ext.truncate(m - n); - list.extend(ext); - - let mut len = list.len(); - while len > 1 { - for i in 0..len / 2 { - list[i] = Node::::new( - hasher - .native_hash_two(&list[2 * i].repr, &list[2 * i + 1].repr) - .unwrap(), - ); - } - len /= 2; - } - list[0].clone() - } -} - -/// A path from a position in a particular commitment tree to the root of that tree. -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct MerklePath> { - auth_path: Vec<(Node, bool)>, -} - -impl> MerklePath { - /// Constructs a random dummy merkle path with depth. - pub fn dummy(rng: &mut impl RngCore, depth: usize) -> Self { - let auth_path = (0..depth).map(|_| (Node::rand(rng), rng.gen())).collect(); - Self::from_path(auth_path) - } - - /// Constructs a Merkle path directly from a path. - pub fn from_path(auth_path: Vec<(Node, bool)>) -> Self { - MerklePath { auth_path } - } - - pub fn find_sibling(leaf_hashes: &[F], position: usize) -> (usize, F) { - let pos = if position % 2 == 0 { - position + 1 - } else { - position - 1 - }; - (pos, leaf_hashes[pos]) - } - - fn build_auth_path(leaf_hashes: Vec, position: usize, path: &mut Vec<(Node, bool)>) { - let mut new_leaves = vec![]; - if leaf_hashes.len() > 1 { - let (sibling_pos, sibling) = Self::find_sibling(&leaf_hashes, position); - path.push((Node::new(sibling), sibling_pos % 2 == 0)); - - let hasher = PoseidonConstants::generate::(); - for pair in leaf_hashes.chunks(2) { - let hash_pair = hasher.native_hash_two(&pair[0], &pair[1]).unwrap(); - - new_leaves.push(hash_pair); - } - - Self::build_auth_path(new_leaves, position / 2, path); - } - } - - pub fn build_merkle_path(leaf_hashes: &[F], position: usize) -> Self { - let mut auth_path = vec![]; - let completed_leaf_hashes = add_remaining_addresses(leaf_hashes); - Self::build_auth_path(completed_leaf_hashes, position, &mut auth_path); - MerklePath { auth_path } - } - - /// Returns the root of the tree corresponding to this path applied to `leaf`. - pub fn root(&self, leaf: Node, hasher: &BH) -> Result, TaigaError> { - let mut root = leaf; - for val in self.auth_path.iter() { - root = match val.1 { - false => Node::combine(&root, &val.0, hasher)?, - true => Node::combine(&val.0, &root, hasher)?, - } - } - Ok(root) - } - - /// Returns the input parameters for merkle tree gadget. - pub fn get_path(&self) -> Vec<(F, bool)> { - self.auth_path - .iter() - .map(|(node, b)| (node.inner(), *b)) - .collect() - } -} - -/// A node within the Sapling commitment tree. -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct Node> { - repr: F, - _hasher: PhantomData, -} - -impl> Node { - pub fn new(repr: F) -> Self { - Node { - repr, - _hasher: PhantomData::default(), - } - } - - pub fn rand(rng: &mut impl RngCore) -> Self { - Self::new(F::rand(rng)) - } - - // TODO: add new from commitment - // pub fn new_from_cm(note: &Note)-> Self {} - - pub(crate) fn inner(&self) -> F { - self.repr - } - - pub fn to_bytes(&self) -> Vec { - self.repr.into_repr().to_bytes_le() - } - - pub fn from_bytes(bytes: &[u8]) -> Self { - Self::new(F::from_le_bytes_mod_order(bytes)) - } - - /// Returns the hash result of left node, right node and the hash function. - fn combine(lhs: &Self, rhs: &Self, hasher: &BH) -> Result { - let hash = hasher.native_hash_two(&lhs.repr, &rhs.repr)?; - Ok(Self::new(hash)) - } -} - -fn add_remaining_addresses(addresses: &[F]) -> Vec { - let number_of_elems = addresses.len(); - let next_power_of_two = number_of_elems.next_power_of_two(); - let remaining = next_power_of_two - number_of_elems; - let slice = &addresses[..remaining]; - let mut added = slice.to_vec(); - let mut new_addresses = addresses.to_owned(); - new_addresses.append(&mut added); - new_addresses -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::circuit::circuit_parameters::{CircuitParameters, PairingCircuitParameters as CP}; - use crate::merkle_tree::Node; - use crate::poseidon::FieldHasher; - use crate::user::User; - use plonk_hashing::poseidon::constants::PoseidonConstants; - - type F = ::CurveScalarField; - type P = ::InnerCurve; - - #[test] - // Test a Merkle tree with 4 leaves - fn test_auth_path_4() { - let mut rng = rand::thread_rng(); - // user addresses - let addresses: Vec = (0..4) - .map(|_| User::::dummy(&mut rng).address().unwrap()) - .collect(); - - let position = 1; - - let hasher = PoseidonConstants::generate::(); - let hash_2_3 = hasher - .native_hash_two(&addresses[2], &addresses[3]) - .unwrap(); - - let auth_path = &[ - (Node::>::new(addresses[0]), true), - (Node::>::new(hash_2_3), false), - ]; - - let merkle_path = MerklePath::from_path(auth_path.to_vec()); - - let merkle_path_2: MerklePath> = - MerklePath::build_merkle_path(&addresses, position); - - assert_eq!(merkle_path, merkle_path_2); - } - - #[test] - // Test a Merkle tree with 8 leaves - fn test_auth_path_8() { - let mut rng = rand::thread_rng(); - // user addresses - let addresses: Vec = (0..8) - .map(|_| User::::dummy(&mut rng).address().unwrap()) - .collect(); - - let position = 4; - - let hasher = PoseidonConstants::generate::(); - let hash_0_1 = hasher - .native_hash_two(&addresses[0], &addresses[1]) - .unwrap(); - let hash_2_3 = hasher - .native_hash_two(&addresses[2], &addresses[3]) - .unwrap(); - let hash_0_1_2_3 = hasher.native_hash_two(&hash_0_1, &hash_2_3).unwrap(); - let hash_6_7 = hasher - .native_hash_two(&addresses[6], &addresses[7]) - .unwrap(); - - let auth_path = &[ - (Node::>::new(addresses[5]), false), - (Node::>::new(hash_6_7), false), - (Node::>::new(hash_0_1_2_3), true), - ]; - - let merkle_path = MerklePath::from_path(auth_path.to_vec()); - - let merkle_path_2: MerklePath> = - MerklePath::build_merkle_path(&addresses, position); - - assert_eq!(merkle_path, merkle_path_2); - } - - #[test] - // Test power of two - fn test_power_of_two_5() { - let mut rng = rand::thread_rng(); - // user addresses - let addresses: Vec = (0..5) - .map(|_| User::::dummy(&mut rng).address().unwrap()) - .collect(); - - let pow2_addresses = add_remaining_addresses(&addresses); - - assert_eq!(pow2_addresses.len(), 8); - assert_eq!(pow2_addresses[5..8], addresses[0..3]); - } - - #[test] - fn test_power_of_two_9() { - let mut rng = rand::thread_rng(); - // user addresses - let addresses: Vec = (0..9) - .map(|_| User::::dummy(&mut rng).address().unwrap()) - .collect(); - - let pow2_addresses = add_remaining_addresses(&addresses); - - assert_eq!(pow2_addresses.len(), 16); - assert_eq!(pow2_addresses[9..16], addresses[0..7]); - } - - #[test] - // Test that a vector with 2^n elements stays the same - fn test_power_of_two_8() { - let mut rng = rand::thread_rng(); - // user addresses - let addresses: Vec = (0..8) - .map(|_| User::::dummy(&mut rng).address().unwrap()) - .collect(); - - let pow2_addresses = add_remaining_addresses(&addresses); - - assert_eq!(pow2_addresses, addresses); - } - - #[test] - // Test a Merkle tree with 5 leaves (not a power of 2) - fn test_auth_path_5() { - let mut rng = rand::thread_rng(); - // user addresses - let addresses: Vec = (0..5) - .map(|_| User::::dummy(&mut rng).address().unwrap()) - .collect(); - - let completed_addresses = add_remaining_addresses(&addresses); - - let position = 4; - - let hasher = PoseidonConstants::generate::(); - let hash_0_1 = hasher - .native_hash_two(&addresses[0], &completed_addresses[1]) - .unwrap(); - let hash_2_3 = hasher - .native_hash_two(&addresses[2], &completed_addresses[3]) - .unwrap(); - let hash_0_1_2_3 = hasher.native_hash_two(&hash_0_1, &hash_2_3).unwrap(); - let hash_6_7 = hasher - .native_hash_two(&completed_addresses[6], &completed_addresses[7]) - .unwrap(); - - let auth_path = &[ - ( - Node::>::new(completed_addresses[5]), - false, - ), - (Node::>::new(hash_6_7), false), - (Node::>::new(hash_0_1_2_3), true), - ]; - - let merkle_path = MerklePath::from_path(auth_path.to_vec()); - - let merkle_path_2: MerklePath> = - MerklePath::build_merkle_path(&addresses, position); - - assert_eq!(merkle_path, merkle_path_2); - } -} diff --git a/taiga_zk_garage/src/note.rs b/taiga_zk_garage/src/note.rs deleted file mode 100644 index 5dedf2dc..00000000 --- a/taiga_zk_garage/src/note.rs +++ /dev/null @@ -1,175 +0,0 @@ -use crate::app::App; -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::error::TaigaError; -use crate::nullifier::Nullifier; -use crate::poseidon::{FieldHasher, WIDTH_3, WIDTH_9}; -use crate::user::User; -use ark_ff::{BigInteger, PrimeField}; -use plonk_hashing::poseidon::{ - constants::PoseidonConstants, - poseidon::{NativeSpec, Poseidon}, -}; -use rand::RngCore; - -/// A note -#[derive(Debug, Clone)] -pub struct Note { - /// Owner of the note - pub user: User, - pub app: App, - pub value: u64, - /// for NFT or whatever. TODO: to be decided the value format. - pub data: CP::CurveScalarField, - /// old nullifier. Nonce which is a deterministically computed, unique nonce - pub rho: Nullifier, - /// computed from spent_note_nf using a PRF - pub psi: CP::CurveScalarField, - pub rcm: CP::CurveScalarField, -} - -/// A commitment to a note. -#[derive(Copy, Debug, Clone)] -pub struct NoteCommitment(CP::CurveScalarField); - -impl Note { - pub fn new( - user: User, - app: App, - value: u64, - rho: Nullifier, - data: CP::CurveScalarField, - rcm: CP::CurveScalarField, - ) -> Self { - // Init poseidon param. - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - let psi = poseidon_param.native_hash_two(&rho.inner(), &rcm).unwrap(); - Self { - user, - app, - value, - data, - rho, - psi, - rcm, - } - } - - pub fn dummy(rng: &mut impl RngCore) -> Self { - use ark_ff::UniformRand; - use rand::Rng; - - let user = User::::dummy(rng); - let app = App::::dummy(rng); - let value: u64 = rng.gen(); - let data = CP::CurveScalarField::rand(rng); - let rho = Nullifier::new(CP::CurveScalarField::rand(rng)); - let rcm = CP::CurveScalarField::rand(rng); - - // Init poseidon param. - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - let psi = poseidon_param.native_hash_two(&rho.inner(), &rcm).unwrap(); - Self { - user, - app, - value, - data, - rho, - psi, - rcm, - } - } - - pub fn dummy_from_app(app: App, rng: &mut impl RngCore) -> Note { - use ark_ff::UniformRand; - use rand::Rng; - - let user = User::::dummy(rng); - let value: u64 = rng.gen(); - let data = CP::CurveScalarField::rand(rng); - let rho = Nullifier::new(CP::CurveScalarField::rand(rng)); - let rcm = CP::CurveScalarField::rand(rng); - - // Init poseidon param. - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - let psi = poseidon_param.native_hash_two(&rho.inner(), &rcm).unwrap(); - Self { - user, - app, - value, - data, - rho, - psi, - rcm, - } - } - - pub fn dummy_from_user(user: User, rng: &mut impl RngCore) -> Note { - use ark_ff::UniformRand; - use rand::Rng; - - let app = App::::dummy(rng); - let value: u64 = rng.gen(); - let data = CP::CurveScalarField::rand(rng); - let rho = Nullifier::new(CP::CurveScalarField::rand(rng)); - let rcm = CP::CurveScalarField::rand(rng); - - // Init poseidon param. - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - let psi = poseidon_param.native_hash_two(&rho.inner(), &rcm).unwrap(); - Self { - user, - app, - value, - data, - rho, - psi, - rcm, - } - } - - // To simplify implementation, can we use NoteCommit from VERI-ZEXE(P26 Commitment). - // Commit(m, r) = CRH(m||r||0), m is a n filed elements vector, CRH is an algebraic hash function(poseidon here). - // If the Commit can't provide enough hiding security(to be verified, we have the same problem in - // address commit and vp commit), consider using hash_to_curve(pedersen_hash_to_curve used in sapling - // or Sinsemilla_hash_to_curve used in Orchard) and adding rcm*fixed_generator, which based on DL assumption. - pub fn commitment(&self) -> Result, TaigaError> { - let user_address = self.user.address()?; - let app_address = self.app.address()?; - let value_filed = CP::CurveScalarField::from(self.value); - - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - let mut poseidon = Poseidon::<(), NativeSpec, WIDTH_9>::new( - &mut (), - &poseidon_param, - ); - poseidon.input(user_address).unwrap(); - poseidon.input(app_address).unwrap(); - poseidon.input(value_filed).unwrap(); - poseidon.input(self.data).unwrap(); - poseidon.input(self.rho.inner()).unwrap(); - poseidon.input(self.psi).unwrap(); - poseidon.input(self.rcm).unwrap(); - Ok(NoteCommitment(poseidon.output_hash(&mut ()))) - } - - // temporary interface, remove it after adding the Serialize - pub fn to_bytes(&self) -> Vec { - let cm = self.commitment().unwrap(); - cm.to_bytes() - } -} - -impl NoteCommitment { - pub fn inner(&self) -> CP::CurveScalarField { - self.0 - } - - pub fn to_bytes(&self) -> Vec { - self.inner().into_repr().to_bytes_le() - } -} diff --git a/taiga_zk_garage/src/nullifier.rs b/taiga_zk_garage/src/nullifier.rs deleted file mode 100644 index 7bd56783..00000000 --- a/taiga_zk_garage/src/nullifier.rs +++ /dev/null @@ -1,70 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::note::NoteCommitment; -use crate::poseidon::{FieldHasher, WIDTH_5}; -use crate::user::NullifierDerivingKey; -use ark_ff::{BigInteger, PrimeField}; -use plonk_hashing::poseidon::constants::PoseidonConstants; - -/// The unique nullifier. -#[derive(Copy, Debug, Clone)] -pub struct Nullifier(CP::CurveScalarField); - -impl Nullifier { - // for test - pub fn new(nf: CP::CurveScalarField) -> Self { - Self(nf) - } - - // cm is a point - // // $nf =Extract_P([PRF_{nk}(\rho) = \psi \ mod \ q] * K + cm)$ - // pub fn derive_native( - // nk: &NullifierDerivingKey, - // rho: &CP::CurveScalarField, - // psi: &CP::CurveScalarField, - // cm: &TEGroupAffine, - // ) -> Self { - // // Init poseidon param. - // let poseidon_param: PoseidonConstants = - // PoseidonConstants::generate::(); - // let prf_nk_rho = poseidon_param.native_hash_two(&nk.inner(), rho).unwrap(); - // // This requires CP::CurveScalarField is smaller than CP::InnerCurveScalarField - // let scalar_repr = (prf_nk_rho + psi).into_repr(); - // let scalar = CP::InnerCurveScalarField::from_le_bytes_mod_order(&scalar_repr.to_bytes_le()); - - // let ret = TEGroupAffine::prime_subgroup_generator() - // .mul(scalar) - // .into_affine() - // + cm; - - // Nullifier(ret.x) - // } - - // cm is a scalar - // nf = CRH(nk, rho, psi, cm) - pub fn derive_native( - nk: &NullifierDerivingKey, - rho: &Nullifier, // Old nullifier - psi: &CP::CurveScalarField, - cm: &NoteCommitment, - ) -> Self { - // Init poseidon param. - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - let scalar_vec = vec![nk.inner(), rho.inner(), *psi, cm.inner()]; - let nf = poseidon_param.native_hash(&scalar_vec).unwrap(); - - Nullifier(nf) - } - - pub fn to_bytes(&self) -> Vec { - self.0.into_repr().to_bytes_le() - } - - pub fn from_bytes(bytes: &[u8]) -> Self { - Self(CP::CurveScalarField::from_le_bytes_mod_order(bytes)) - } - - pub fn inner(&self) -> CP::CurveScalarField { - self.0 - } -} diff --git a/taiga_zk_garage/src/poseidon.rs b/taiga_zk_garage/src/poseidon.rs deleted file mode 100644 index ad27323e..00000000 --- a/taiga_zk_garage/src/poseidon.rs +++ /dev/null @@ -1,102 +0,0 @@ -use crate::error::TaigaError; -use ark_ff::PrimeField; -use lazy_static::lazy_static; -use plonk_hashing::poseidon::{ - constants::PoseidonConstants, - poseidon::{NativeSpec, Poseidon}, -}; - -// ARITY: input number of hash -// WIDTH_3 = ARITY + 1 -pub const WIDTH_3: usize = 3; -pub const WIDTH_5: usize = 5; -pub const WIDTH_9: usize = 9; -lazy_static! { - pub static ref POSEIDON_HASH_PARAM_BLS12_381_NEW_SCALAR_ARITY2: PoseidonConstants = - PoseidonConstants::generate::(); - pub static ref POSEIDON_HASH_PARAM_BLS12_381_NEW_SCALAR_ARITY4: PoseidonConstants = - PoseidonConstants::generate::(); - - // Hashes of bls12_381_new::BaseField are generated automatically, not tested yet. - // Especially we need to check the round number generation from the paper. - pub static ref POSEIDON_HASH_PARAM_BLS12_381_NEW_BASE_ARITY2: PoseidonConstants = - PoseidonConstants::generate::(); - pub static ref POSEIDON_HASH_PARAM_BLS12_381_NEW_BASE_ARITY4: PoseidonConstants = - PoseidonConstants::generate::(); -} - -/// A FieldHasher over prime field takes field elements as input and -/// outputs one field element. `native_hash_two` takes two field elements; -/// `native_hash` takes at most four field elements. -pub trait FieldHasher: Clone { - fn native_hash_two(&self, left: &F, right: &F) -> Result; - fn native_hash(&self, inputs: &[F]) -> Result; -} - -/// A FieldHasher implementation for Poseidon Hash. -impl FieldHasher for PoseidonConstants { - fn native_hash_two(&self, left: &F, right: &F) -> Result { - let mut poseidon = Poseidon::<(), NativeSpec, WIDTH_3>::new(&mut (), self); - poseidon.input(*left)?; - poseidon.input(*right)?; - Ok(poseidon.output_hash(&mut ())) - } - - fn native_hash(&self, inputs: &[F]) -> Result { - assert!(inputs.len() < WIDTH_5); - let mut poseidon = Poseidon::<(), NativeSpec, WIDTH_5>::new(&mut (), self); - // Default padding zero - inputs.iter().for_each(|f| { - poseidon.input(*f).unwrap(); - }); - Ok(poseidon.output_hash(&mut ())) - } -} - -#[test] -fn test_poseidon_circuit_example() { - use ark_ec::PairingEngine; - use ark_std::{test_rng, UniformRand}; - use plonk_hashing::poseidon::poseidon::{NativeSpec, PlonkSpec, Poseidon}; - type E = ark_bls12_381_new::Bls12_381New; - type P = ark_ed_on_bls12_381_new::Parameters; - type Fr = ::Fr; - use plonk_core::constraint_system::StandardComposer; - - let mut rng = test_rng(); - let mut poseidon_native = Poseidon::<(), NativeSpec, WIDTH_3>::new( - &mut (), - &POSEIDON_HASH_PARAM_BLS12_381_NEW_SCALAR_ARITY2, - ); - let inputs = (0..(WIDTH_3 - 1)) - .map(|_| Fr::rand(&mut rng)) - .collect::>(); - - inputs.iter().for_each(|x| { - let _ = poseidon_native.input(*x).unwrap(); - }); - let native_hash: Fr = poseidon_native.output_hash(&mut ()); - - let mut c = StandardComposer::::new(); - let inputs_var = inputs.iter().map(|x| c.add_input(*x)).collect::>(); - let mut poseidon_circuit = Poseidon::<_, PlonkSpec, WIDTH_3>::new( - &mut c, - &POSEIDON_HASH_PARAM_BLS12_381_NEW_SCALAR_ARITY2, - ); - inputs_var.iter().for_each(|x| { - let _ = poseidon_circuit.input(*x).unwrap(); - }); - let plonk_hash = poseidon_circuit.output_hash(&mut c); - - c.check_circuit_satisfied(); - - let expected = c.add_input(native_hash); - c.assert_equal(expected, plonk_hash); - - c.check_circuit_satisfied(); - println!( - "circuit size for WIDTH_3 {} poseidon: {}", - WIDTH_3, - c.circuit_bound() - ) -} diff --git a/taiga_zk_garage/src/transaction.rs b/taiga_zk_garage/src/transaction.rs deleted file mode 100644 index 494efe48..00000000 --- a/taiga_zk_garage/src/transaction.rs +++ /dev/null @@ -1,357 +0,0 @@ -use crate::action::Action; -use crate::circuit::action_circuit::ActionCircuit; -use crate::circuit::blinding_circuit::BlindingCircuit; -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::circuit::validity_predicate::{ValidityPredicate, NUM_NOTE}; -use crate::constant::{ - ACTION_CIRCUIT_SIZE, ACTION_PUBLIC_INPUT_CM_INDEX, ACTION_PUBLIC_INPUT_NF_INDEX, - ACTION_PUBLIC_INPUT_ROOT_INDEX, BLINDING_CIRCUIT_SIZE, -}; -use crate::error::TaigaError; -use crate::vp_description::ValidityPredicateDescription; -use plonk_core::circuit::Circuit; -use plonk_core::circuit::{verify_proof, VerifierData}; -use plonk_core::proof_system::{pi::PublicInputs, Proof, VerifierKey}; -use rand::RngCore; - -pub const NUM_TX_SLICE: usize = NUM_NOTE; - -pub struct Transaction { - pub action_slices: [ActionSlice; NUM_TX_SLICE], - pub spend_slices: [SpendSlice; NUM_TX_SLICE], - pub output_slices: [OutputSlice; NUM_TX_SLICE], -} - -pub struct ActionSlice { - pub action_proof: Proof, - pub action_public: Action, -} - -pub struct SpendSlice { - spend_addr_vp: VPCheck, - spend_app_vp: VPCheck, -} - -pub struct OutputSlice { - output_addr_vp: VPCheck, - output_app_vp: VPCheck, -} - -pub struct VPCheck { - // VP circuit size - pub vp_circuit_size: usize, - // VP proof - pub vp_proof: Proof, - // The public inputs for vp proof - // TODO: maybe the PublicInputs should be serialized from Vec, like the action_public in ActionSlice? - pub vp_public_inputs: PublicInputs, - // The vk of vp is blinded partially, blinded parts can be constructed from blinded_vp_public_inputs. - // The unblinded_vp_vk is the unblinded parts. - // TODO: - pub unblinded_vp_vk: VerifierKey, - // blind vp proof - pub blind_vp_proof: Proof, - // The public inputs for blind vp proof - pub blinded_vp_public_inputs: PublicInputs, - // TODO: - // pub vp_com - // pub vp_param - // pub vp_memo -} - -impl SpendSlice { - pub fn new(spend_addr_vp: VPCheck, spend_app_vp: VPCheck) -> Self { - Self { - spend_addr_vp, - spend_app_vp, - } - } -} - -impl OutputSlice { - pub fn new(output_addr_vp: VPCheck, output_app_vp: VPCheck) -> Self { - Self { - output_addr_vp, - output_app_vp, - } - } -} - -impl ActionSlice { - pub fn build( - action_public: Action, - action_circuit: &mut ActionCircuit, - ) -> Result { - let setup = CP::get_pc_setup_params(ACTION_CIRCUIT_SIZE); - // Compile the circuit - let pk = CP::get_action_pk(); - let vk = CP::get_action_vk(); - - // Prover - let (action_proof, action_public_input) = - action_circuit.gen_proof::(setup, pk.clone(), b"Test")?; - - // Verifier - let verifier_data = VerifierData::new(vk.clone(), action_public_input); - verify_proof::( - setup, - verifier_data.key, - &action_proof, - &verifier_data.pi, - b"Test", - )?; - - Ok(Self { - action_public, - action_proof, - }) - } - - pub fn verify(&self) -> Result<(), TaigaError> { - let mut action_pi = PublicInputs::new(); - action_pi.insert(ACTION_PUBLIC_INPUT_NF_INDEX, self.action_public.nf.inner()); - action_pi.insert(ACTION_PUBLIC_INPUT_ROOT_INDEX, self.action_public.root); - action_pi.insert(ACTION_PUBLIC_INPUT_CM_INDEX, self.action_public.cm.inner()); - - let action_vk = CP::get_action_vk(); - let verifier_data = VerifierData::new(action_vk.clone(), action_pi); - let action_setup = CP::get_pc_setup_params(ACTION_CIRCUIT_SIZE); - verify_proof::( - action_setup, - verifier_data.key, - &self.action_proof, - &verifier_data.pi, - b"Test", - )?; - Ok(()) - } -} - -impl VPCheck { - pub fn build(vp: &mut VP, rng: &mut impl RngCore) -> Result - where - VP: ValidityPredicate, - { - let vp_circuit_size = vp.padded_circuit_size(); - // Get vp proof setup - let vp_setup = CP::get_pc_setup_params(vp_circuit_size); - // Generate blinding circuit for vp - let vp_desc = ValidityPredicateDescription::from_vp(vp, vp_setup)?; - // let vp_desc_compressed = vp_desc.get_compressed(); - let mut blinding_circuit = - BlindingCircuit::::new(rng, vp_desc, vp_setup, vp_circuit_size)?; - - // Compile vp(must use compile_with_blinding) - let (pk, vk_blind) = - vp.compile_with_blinding::(vp_setup, &blinding_circuit.get_blinding())?; - - // VP Prover - let (vp_proof, vp_public_input) = vp.gen_proof::(vp_setup, pk, b"Test")?; - - // VP verifier - let vp_verifier_data = VerifierData::new(vk_blind.clone(), vp_public_input); - verify_proof::( - vp_setup, - vp_verifier_data.key, - &vp_proof, - &vp_verifier_data.pi, - b"Test", - )?; - - // Generate blinding circuit CRS - let blinding_setup = CP::get_opc_setup_params(BLINDING_CIRCUIT_SIZE); - let pk = CP::get_blind_vp_pk(); - let vk = CP::get_blind_vp_vk(); - - // Blinding Prover - let (blind_vp_proof, blind_vp_public_input) = - blinding_circuit.gen_proof::(blinding_setup, pk.clone(), b"Test")?; - - // Blinding Verifier - let blinding_verifier_data = VerifierData::new(vk.clone(), blind_vp_public_input); - verify_proof::( - blinding_setup, - blinding_verifier_data.key, - &blind_vp_proof, - &blinding_verifier_data.pi, - b"Test", - )?; - - Ok(Self { - vp_circuit_size, - vp_proof, - vp_public_inputs: vp_verifier_data.pi, - unblinded_vp_vk: vk_blind, - blind_vp_proof, - blinded_vp_public_inputs: blinding_verifier_data.pi, - }) - } - - pub fn verify(&self) -> Result<(), TaigaError> { - // verify vp proof - let vp_setup = CP::get_pc_setup_params(self.vp_circuit_size); - let vp_verifier_data = - VerifierData::new(self.unblinded_vp_vk.clone(), self.vp_public_inputs.clone()); - verify_proof::( - vp_setup, - vp_verifier_data.key, - &self.vp_proof, - &vp_verifier_data.pi, - b"Test", - )?; - - // verify blind proof - let blind_vp_setup = CP::get_opc_setup_params(BLINDING_CIRCUIT_SIZE); - let blind_vp_vk = CP::get_blind_vp_vk(); - let blinding_verifier_data = - VerifierData::new(blind_vp_vk.clone(), self.blinded_vp_public_inputs.clone()); - verify_proof::( - blind_vp_setup, - blinding_verifier_data.key, - &self.blind_vp_proof, - &blinding_verifier_data.pi, - b"Test", - )?; - Ok(()) - } -} - -impl Transaction { - pub fn new( - action_slices: Vec>, - spend_slices: Vec>, - output_slices: Vec>, - ) -> Self { - assert_eq!(action_slices.len(), NUM_TX_SLICE); - assert_eq!(spend_slices.len(), NUM_TX_SLICE); - assert_eq!(output_slices.len(), NUM_TX_SLICE); - - Self { - action_slices: action_slices - .try_into() - .unwrap_or_else(|_| panic!("slice with incorrect length")), - spend_slices: spend_slices - .try_into() - .unwrap_or_else(|_| panic!("slice with incorrect length")), - output_slices: output_slices - .try_into() - .unwrap_or_else(|_| panic!("slice with incorrect length")), - } - } - pub fn verify( - &self, - // ledger state - // ledger: &Ledger, - ) -> Result<(), TaigaError> { - // verify action proof - for action in self.action_slices.iter() { - action.verify()? - } - - // verify spend vp proof and blind proof - for spend in self.spend_slices.iter() { - spend.spend_addr_vp.verify()?; - spend.spend_app_vp.verify()?; - } - - // verify output vp proof and blind proof - for output in self.output_slices.iter() { - output.output_addr_vp.verify()?; - output.output_app_vp.verify()?; - } - - // check public input consistency(nf, output_cm, com_vp) among action, vp, vp blind. - - // check ledger state - // check root existence, nf non-existence, etc. - - Ok(()) - } -} - -#[ignore] -#[test] -fn test_tx() { - use crate::circuit::circuit_parameters::PairingCircuitParameters as CP; - type Fr = ::CurveScalarField; - type P = ::InnerCurve; - type PC = ::CurvePC; - type Fq = ::CurveBaseField; - type OP = ::Curve; - type Opc = ::OuterCurvePC; - use crate::action::ActionInfo; - use crate::circuit::vp_examples::field_addition::FieldAdditionValidityPredicate; - use crate::note::Note; - use ark_std::test_rng; - - let mut rng = test_rng(); - - // Construct action infos - let mut actions: Vec<(Action, ActionCircuit)> = (0..NUM_TX_SLICE) - .map(|_| { - let action_info = ActionInfo::::dummy(&mut rng); - action_info.build(&mut rng).unwrap() - }) - .collect(); - - // Generate action proofs - let action_slices: Vec> = actions - .iter_mut() - .map(|action| ActionSlice::::build(action.0, &mut action.1).unwrap()) - .collect(); - - // Collect input notes from actions - let input_notes_vec: Vec> = actions - .iter() - .map(|action| action.1.spend_note.clone()) - .collect(); - let input_notes: [Note; NUM_NOTE] = input_notes_vec.try_into().unwrap(); - - // Collect output notes from actions - let output_notes_vec: Vec> = actions - .iter() - .map(|action| action.1.output_note.clone()) - .collect(); - let output_notes: [Note; NUM_NOTE] = output_notes_vec.try_into().unwrap(); - - // Construct VPs and generate VP proofs and blind VP proofs - let mut spend_slices = vec![]; - let mut output_slices = vec![]; - for _action_index in 0..NUM_TX_SLICE { - // Construct dummy spend slice - let mut spend_addr_vp = FieldAdditionValidityPredicate::::new( - input_notes.clone(), - output_notes.clone(), - &mut rng, - ); - let spend_addr_vp_check = VPCheck::build(&mut spend_addr_vp, &mut rng).unwrap(); - let mut spend_app_vp = FieldAdditionValidityPredicate::::new( - input_notes.clone(), - output_notes.clone(), - &mut rng, - ); - let spend_app_vp_check = VPCheck::build(&mut spend_app_vp, &mut rng).unwrap(); - let spend_slice = SpendSlice::new(spend_addr_vp_check, spend_app_vp_check); - spend_slices.push(spend_slice); - - // Construct dummy output vps - let mut output_addr_vp = FieldAdditionValidityPredicate::::new( - input_notes.clone(), - output_notes.clone(), - &mut rng, - ); - let output_addr_vp_check = VPCheck::build(&mut output_addr_vp, &mut rng).unwrap(); - let mut output_app_vp = FieldAdditionValidityPredicate::::new( - input_notes.clone(), - output_notes.clone(), - &mut rng, - ); - let output_app_vp_check = VPCheck::build(&mut output_app_vp, &mut rng).unwrap(); - let output_slice = OutputSlice::new(output_addr_vp_check, output_app_vp_check); - output_slices.push(output_slice); - } - - // Construct a tx - let tx = Transaction::::new(action_slices, spend_slices, output_slices); - tx.verify().unwrap(); -} diff --git a/taiga_zk_garage/src/user.rs b/taiga_zk_garage/src/user.rs deleted file mode 100644 index 14108333..00000000 --- a/taiga_zk_garage/src/user.rs +++ /dev/null @@ -1,152 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::error::TaigaError; -use crate::poseidon::{FieldHasher, WIDTH_5}; -use crate::utils::bits_to_fields; -use crate::vp_description::ValidityPredicateDescription; -use ark_ff::{BigInteger, PrimeField}; -use blake2b_simd::Params; -use plonk_hashing::poseidon::constants::PoseidonConstants; -use rand::RngCore; - -const PRF_NK_PERSONALIZATION: &[u8; 12] = b"Taiga_PRF_NK"; - -/// The nullifier key for note spending. -#[derive(Copy, Debug, Clone)] -pub struct NullifierDerivingKey(F); - -/// The user address binded with send vp and received vp. -#[derive(Debug, Clone)] -pub struct User { - pub send_com: UserSendAddress, - pub recv_vp: ValidityPredicateDescription, -} - -#[derive(Debug, Clone)] -pub enum UserSendAddress { - Closed(CP::CurveScalarField), - Open( - NullifierDerivingKey, - ValidityPredicateDescription, - ), -} - -impl NullifierDerivingKey { - pub fn rand(rng: &mut impl RngCore) -> Self { - let mut bytes = [0; 32]; - rng.fill_bytes(&mut bytes); - Self::prf_nk(&bytes) - } - - pub fn new_from(rng_bytes: &[u8; 32]) -> Self { - Self::prf_nk(rng_bytes) - } - - fn prf_nk(random: &[u8]) -> Self { - let mut h = Params::new() - .hash_length(64) - .personal(PRF_NK_PERSONALIZATION) - .to_state(); - h.update(random); - Self::from_bytes(h.finalize().as_bytes()) - } - - pub fn inner(&self) -> F { - self.0 - } - - pub fn to_bytes(self) -> Vec { - self.0.into_repr().to_bytes_le() - } - - pub fn from_bytes(bytes: &[u8]) -> Self { - Self(F::from_le_bytes_mod_order(bytes)) - } -} - -impl User { - pub fn new( - send_vp: ValidityPredicateDescription, - recv_vp: ValidityPredicateDescription, - nk: NullifierDerivingKey, - ) -> Self { - let send_com = UserSendAddress::::from_open(nk, send_vp); - Self { send_com, recv_vp } - } - - pub fn dummy(rng: &mut impl RngCore) -> Self { - let nk = NullifierDerivingKey::::rand(rng); - let send_vp = ValidityPredicateDescription::dummy(rng); - let send_com = UserSendAddress::::from_open(nk, send_vp); - Self { - send_com, - recv_vp: ValidityPredicateDescription::dummy(rng), - } - } - - pub fn address(&self) -> Result { - // send_com = Com_r( Com_q(send_vp_hash) || nk ) - let send_com = self.send_com.get_closed()?; - - // address = Com_r(send_com || recv_vp_hash) - - // Init poseidon param. - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - let mut address_fields = vec![send_com]; - let recv_fields = bits_to_fields::(&self.recv_vp.to_bits()); - address_fields.extend(recv_fields); - poseidon_param.native_hash(&address_fields) - } -} - -impl UserSendAddress { - /// Creates an open user send address. - pub fn from_open( - nk: NullifierDerivingKey, - send_vp: ValidityPredicateDescription, - ) -> Self { - UserSendAddress::Open(nk, send_vp) - } - - /// Creates a closed user send address. - pub fn from_closed(x: CP::CurveScalarField) -> Self { - UserSendAddress::Closed(x) - } - - pub fn get_nk(&self) -> Option> { - match self { - UserSendAddress::Closed(_) => None, - UserSendAddress::Open(nk, _) => Some(*nk), - } - } - - pub fn get_send_vp(&self) -> Option<&ValidityPredicateDescription> { - match self { - UserSendAddress::Closed(_) => None, - UserSendAddress::Open(_, send_vp) => Some(send_vp), - } - } - - pub fn get_closed(&self) -> Result { - match self { - UserSendAddress::Closed(v) => Ok(*v), - UserSendAddress::Open(nk, send_vp) => { - // Init poseidon param. - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - - // send_part = Com_r( Com_q(desc_vp_addr_send) || nk ) - let mut send_fields = bits_to_fields::(&send_vp.to_bits()); - send_fields.push(nk.inner()); - poseidon_param.native_hash(&send_fields) - } - } - } -} - -#[test] -fn test_user_address_computation() { - let mut rng = ark_std::test_rng(); - let u = User::::dummy(&mut rng); - u.address().unwrap(); -} diff --git a/taiga_zk_garage/src/utils.rs b/taiga_zk_garage/src/utils.rs deleted file mode 100644 index 464d493d..00000000 --- a/taiga_zk_garage/src/utils.rs +++ /dev/null @@ -1,69 +0,0 @@ -use ark_bls12_381_new::Fq; -use ark_ec::{ - short_weierstrass_jacobian::GroupAffine as SWGroupAffine, - twisted_edwards_extended::GroupAffine as TEGroupAffine, -}; -use ark_ff::{field_new, BigInteger, One, PrimeField}; - -pub fn bits_to_fields(bits: &[bool]) -> Vec { - bits.chunks(F::size_in_bits() - 1) - .map(|elt| F::from_repr(::BigInt::from_bits_le(elt)).unwrap()) - .collect() -} - -// warning! Works only for bls12_381_new -pub fn ws_to_te( - p: SWGroupAffine, -) -> TEGroupAffine { - /* - Wikipedia provides a WS->M and M->TE conversion. - Here we provide the WS -> TE conversion with few simpliciations. - - (a and b are coefficients of the curve) - α = sqrt(x**3+a*x+b) - s1 = sqrt(3*α**2+a) - s2 = sqrt(-3*α-2*s1) - coeff = -(3*α-2*s1)/(3*α+2*s1) - - u = (x-α) * s2 / y - v = (x-α-s1) / (x-α+s1) - (u,v) satisfies -u**2 + v**2 == 1 + coeff * u**2 * v**2 - - - In the case of bls12_381_new: - α = -1 - s1 = sqrt(3) - s2 = sqrt(-3+2*sqrt(3)) - coeff = (-3-2*sqrt(3)) / (-3+2*sqrt(3)) - u = (x+1) * s2 / y - v = (x+1-s1) / (x+1+s1) - */ - let alpha = -Fq::one(); - let s1 = field_new!(Fq, "611336158540232733028115263714465872671465435137168183916056024884978835858365189946006184892099852878171309395862"); - // assert_eq!(s1*s1, Fq::from(3)); - let s2 = field_new!(Fq, "1064881461568443305175032400733120695040834941031583268014086210056237636385831065297199936964360836443404508126238"); - // assert_eq!(-s2*s2, s1+s1-Fq::from(3)); - TEGroupAffine::::new( - (p.x - alpha) * s2 / p.y, - (p.x - alpha - s1) / (p.x - alpha + s1), - ) -} - -#[test] -fn test_ws_to_te() { - use ark_bls12_381_new::g1; - use ark_bls12_381_new::g1::G1Projective; - use ark_ec::ProjectiveCurve; - use ark_ec::TEModelParameters; - use ark_std::UniformRand; - let mut rng = ark_std::test_rng(); - for _ in 0..100 { - let p_ws: SWGroupAffine = G1Projective::rand(&mut rng).into_affine(); - let p_te = ws_to_te(p_ws); - let x = p_te.x; - let y = p_te.y; - let a = ::COEFF_A; - let d = ::COEFF_D; - assert_eq!(a * x * x + y * y, Fq::one() + d * x * x * y * y); - } -} diff --git a/taiga_zk_garage/src/vp_description.rs b/taiga_zk_garage/src/vp_description.rs deleted file mode 100644 index f23db0b4..00000000 --- a/taiga_zk_garage/src/vp_description.rs +++ /dev/null @@ -1,89 +0,0 @@ -use crate::circuit::circuit_parameters::CircuitParameters; -use crate::circuit::validity_predicate::ValidityPredicate; -use crate::poseidon::WIDTH_9; -use ark_ff::{BigInteger, PrimeField, UniformRand}; -use ark_poly::univariate::DensePolynomial; -use ark_poly_commit::PolynomialCommitment; -use plonk_core::{prelude::Error, proof_system::VerifierKey}; -use plonk_hashing::poseidon::{ - constants::PoseidonConstants, - poseidon::{NativeSpec, Poseidon}, -}; -use rand::RngCore; - -// TODO: add vp_param in future. -#[derive(Debug, Clone)] -pub enum ValidityPredicateDescription { - // Pack vk into CurveBaseField array. - Uncompressed(Vec), - // Compress(Com_q) vk into one CurveBaseField element. - Compressed(CP::CurveBaseField), -} - -impl ValidityPredicateDescription { - pub fn from_vp( - vp: &mut VP, - vp_setup: &, - >>::UniversalParams, - ) -> Result - where - VP: ValidityPredicate, - { - let vk = vp.get_desc_vp(vp_setup)?; - Ok(Self::from_vk(&vk)) - } - - pub fn from_vk(vk: &VerifierKey) -> Self { - let vp_desc = CP::pack_vk(vk); - Self::Uncompressed(vp_desc) - } - - pub fn get_pack(&self) -> Option> { - match self { - ValidityPredicateDescription::Uncompressed(v) => Some(v.clone()), - ValidityPredicateDescription::Compressed(_) => None, - } - } - - pub fn get_compressed(&self) -> CP::CurveBaseField { - match self { - ValidityPredicateDescription::Uncompressed(v) => { - assert_eq!(v.len(), 40); - let poseidon_param: PoseidonConstants = - PoseidonConstants::generate::(); - let mut poseidon = - Poseidon::<(), NativeSpec, WIDTH_9>::new( - &mut (), - &poseidon_param, - ); - let hash_vec = v - .chunks_exact(8) - .map(|chunk| { - poseidon.reset(&mut ()); - for x in chunk.iter() { - poseidon.input(*x).unwrap(); - } - poseidon.output_hash(&mut ()) - }) - .collect::>(); - - poseidon.reset(&mut ()); - for x in hash_vec.iter() { - poseidon.input(*x).unwrap(); - } - poseidon.output_hash(&mut ()) - } - ValidityPredicateDescription::Compressed(v) => *v, - } - } - - pub fn dummy(rng: &mut impl RngCore) -> Self { - Self::Compressed(CP::CurveBaseField::rand(rng)) - } - - pub fn to_bits(&self) -> Vec { - self.get_compressed().into_repr().to_bits_le() - } -}