diff --git a/merkle-tree-example/Cargo.toml b/merkle-tree-example/Cargo.toml index 45c772a..8075780 100644 --- a/merkle-tree-example/Cargo.toml +++ b/merkle-tree-example/Cargo.toml @@ -1,22 +1,21 @@ [package] name = "merkle-tree-example" -version = "0.3.0" +version = "0.5.0" authors = ["arkworks contributors"] edition = "2018" [dependencies] -ark-ff = { version = "^0.3.0", default-features = false } -ark-ec = { version = "^0.3.0", default-features = false } -ark-ed-on-bls12-381 = { version = "^0.3.0", features = ["r1cs"] } -ark-bls12-381 = { version = "^0.3.0", default-features = false } -ark-std = { version = "^0.3.0", default-features = false } -ark-relations = { version = "^0.3.0", default-features = false } +ark-ff = { version = "^0.5.0", default-features = false } +ark-ec = { version = "^0.5.0", default-features = false } +ark-ed-on-bls12-381 = { version = "^0.5.0", features = ["r1cs"] } +ark-bls12-381 = { version = "^0.5.0", default-features = false } +ark-std = { version = "^0.5.0", default-features = false } +ark-relations = { version = "^0.5.0", default-features = false } -ark-r1cs-std = { version = "^0.3.0", default-features = false } -ark-snark = { version = "^0.3.0", default-features = false } +ark-r1cs-std = { version = "^0.5.0", default-features = false } +ark-snark = { version = "^0.5.0", default-features = false } -ark-serialize = { version = "^0.3.0", default-features = false } - -ark-crypto-primitives = { version = "^0.3.0", default-features = true, features = [ "r1cs" ] } +ark-serialize = { version = "^0.5.0", default-features = false } +ark-crypto-primitives = { version = "^0.5.0", default-features = true, features = [ "r1cs" , "crh", "merkle_tree"] } tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } tracing-subscriber = { version = "0.2" } diff --git a/merkle-tree-example/src/common.rs b/merkle-tree-example/src/common.rs index 9e7c978..5278e75 100644 --- a/merkle-tree-example/src/common.rs +++ b/merkle-tree-example/src/common.rs @@ -1,14 +1,16 @@ -use ark_crypto_primitives::crh::constraints::{CRHGadget, TwoToOneCRHGadget}; use ark_crypto_primitives::crh::injective_map::constraints::{ - PedersenCRHCompressorGadget, TECompressorGadget, + PedersenCRHCompressorGadget, PedersenTwoToOneCRHCompressorGadget, TECompressorGadget, }; +use ark_crypto_primitives::crh::injective_map::PedersenTwoToOneCRHCompressor; use ark_crypto_primitives::crh::{ injective_map::{PedersenCRHCompressor, TECompressor}, pedersen, }; +use ark_crypto_primitives::crh::{CRHSchemeGadget, TwoToOneCRHSchemeGadget}; use ark_ed_on_bls12_381::{constraints::EdwardsVar, EdwardsProjective}; -pub type TwoToOneHash = PedersenCRHCompressor; +pub type TwoToOneHash = + PedersenTwoToOneCRHCompressor; #[derive(Clone, PartialEq, Eq, Hash)] pub struct TwoToOneWindow; @@ -19,7 +21,6 @@ impl pedersen::Window for TwoToOneWindow { } pub type LeafHash = PedersenCRHCompressor; - #[derive(Clone, PartialEq, Eq, Hash)] pub struct LeafWindow; @@ -29,7 +30,7 @@ impl pedersen::Window for LeafWindow { const NUM_WINDOWS: usize = 144; } -pub type TwoToOneHashGadget = PedersenCRHCompressorGadget< +pub type TwoToOneHashGadget = PedersenTwoToOneCRHCompressorGadget< EdwardsProjective, TECompressor, TwoToOneWindow, @@ -45,8 +46,9 @@ pub type LeafHashGadget = PedersenCRHCompressorGadget< TECompressorGadget, >; -pub type LeafHashParamsVar = >::ParametersVar; +pub type LeafHashParamsVar = + >::ParametersVar; pub type TwoToOneHashParamsVar = - >::ParametersVar; + >::ParametersVar; pub type ConstraintF = ark_ed_on_bls12_381::Fq; diff --git a/merkle-tree-example/src/constraints.rs b/merkle-tree-example/src/constraints.rs index d81e2b1..e33641d 100644 --- a/merkle-tree-example/src/constraints.rs +++ b/merkle-tree-example/src/constraints.rs @@ -1,6 +1,6 @@ -use crate::common::*; +use crate::{common::*, MerkleConfig, MerkleConfigVar}; use crate::{Root, SimplePath}; -use ark_crypto_primitives::crh::{TwoToOneCRH, TwoToOneCRHGadget, CRH}; +use ark_crypto_primitives::crh::{CRHScheme, TwoToOneCRHScheme, TwoToOneCRHSchemeGadget}; use ark_crypto_primitives::merkle_tree::constraints::PathVar; use ark_r1cs_std::prelude::*; use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}; @@ -9,18 +9,18 @@ use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisE // just know that these are types that you can use.) /// The R1CS equivalent of the the Merkle tree root. -pub type RootVar = >::OutputVar; +pub type RootVar = + >::OutputVar; /// The R1CS equivalent of the the Merkle tree path. -pub type SimplePathVar = - PathVar; +pub type SimplePathVar = PathVar; //////////////////////////////////////////////////////////////////////////////// pub struct MerkleTreeVerification { // These are constants that will be embedded into the circuit - pub leaf_crh_params: ::Parameters, - pub two_to_one_crh_params: ::Parameters, + pub leaf_crh_params: ::Parameters, + pub two_to_one_crh_params: ::Parameters, // These are the public inputs to the circuit. pub root: Root, @@ -75,15 +75,24 @@ fn merkle_tree_constraints_correctness() { let mut rng = ark_std::test_rng(); // First, let's sample the public parameters for the hash functions: - let leaf_crh_params = ::setup(&mut rng).unwrap(); - let two_to_one_crh_params = ::setup(&mut rng).unwrap(); + let leaf_crh_params = ::setup(&mut rng).unwrap(); + let two_to_one_crh_params = ::setup(&mut rng).unwrap(); // Next, let's construct our tree. // This follows the API in https://github.com/arkworks-rs/crypto-primitives/blob/6be606259eab0aec010015e2cfd45e4f134cd9bf/src/merkle_tree/mod.rs#L156 let tree = crate::SimpleMerkleTree::new( &leaf_crh_params, &two_to_one_crh_params, - &[1u8, 2u8, 3u8, 10u8, 9u8, 17u8, 70u8, 45u8], // the i-th entry is the i-th leaf. + &[ + &[1u8][..], + &[2u8][..], + &[3u8][..], + &[10u8][..], + &[9u8][..], + &[17u8][..], + &[70u8][..], + &[45u8][..], + ], // the i-th entry is the i-th leaf. ) .unwrap(); @@ -136,15 +145,24 @@ fn merkle_tree_constraints_soundness() { let mut rng = ark_std::test_rng(); // First, let's sample the public parameters for the hash functions: - let leaf_crh_params = ::setup(&mut rng).unwrap(); - let two_to_one_crh_params = ::setup(&mut rng).unwrap(); + let leaf_crh_params = ::setup(&mut rng).unwrap(); + let two_to_one_crh_params = ::setup(&mut rng).unwrap(); // Next, let's construct our tree. // This follows the API in https://github.com/arkworks-rs/crypto-primitives/blob/6be606259eab0aec010015e2cfd45e4f134cd9bf/src/merkle_tree/mod.rs#L156 let tree = crate::SimpleMerkleTree::new( &leaf_crh_params, &two_to_one_crh_params, - &[1u8, 2u8, 3u8, 10u8, 9u8, 17u8, 70u8, 45u8], // the i-th entry is the i-th leaf. + &[ + &[1u8][..], + &[2u8][..], + &[3u8][..], + &[10u8][..], + &[9u8][..], + &[17u8][..], + &[70u8][..], + &[45u8][..], + ], // the i-th entry is the i-th leaf. ) .unwrap(); @@ -152,7 +170,16 @@ fn merkle_tree_constraints_soundness() { let second_tree = crate::SimpleMerkleTree::new( &leaf_crh_params, &two_to_one_crh_params, - &[4u8, 2u8, 3u8, 10u8, 9u8, 17u8, 70u8, 45u8], // the i-th entry is the i-th leaf. + &[ + &[4u8][..], + &[2u8][..], + &[3u8][..], + &[10u8][..], + &[9u8][..], + &[17u8][..], + &[70u8][..], + &[45u8][..], + ], // the i-th entry is the i-th leaf. ) .unwrap(); diff --git a/merkle-tree-example/src/lib.rs b/merkle-tree-example/src/lib.rs index f9f5341..3427636 100644 --- a/merkle-tree-example/src/lib.rs +++ b/merkle-tree-example/src/lib.rs @@ -1,7 +1,11 @@ -use ark_crypto_primitives::crh::TwoToOneCRH; -use ark_crypto_primitives::merkle_tree::{Config, MerkleTree, Path}; +use ark_crypto_primitives::crh::{ + CRHScheme, CRHSchemeGadget, TwoToOneCRHScheme, TwoToOneCRHSchemeGadget, +}; +use ark_crypto_primitives::merkle_tree::constraints::{BytesVarDigestConverter, ConfigGadget}; +use ark_crypto_primitives::merkle_tree::{ByteDigestConverter, Config, MerkleTree, Path}; pub mod common; +use ark_r1cs_std::uint8::UInt8; use common::*; mod constraints; @@ -12,35 +16,61 @@ pub struct MerkleConfig; impl Config for MerkleConfig { // Our Merkle tree relies on two hashes: one to hash leaves, and one to hash pairs // of internal nodes. + type Leaf = [u8]; type LeafHash = LeafHash; type TwoToOneHash = TwoToOneHash; + type LeafDigest = ::Output; + type LeafInnerDigestConverter = ByteDigestConverter; + type InnerDigest = ::Output; } +struct MerkleConfigVar; +impl ConfigGadget for MerkleConfigVar { + type Leaf = LeafVar; + type LeafDigest = >::OutputVar; + type LeafInnerConverter = BytesVarDigestConverter; + type InnerDigest = + >::OutputVar; + type LeafHash = LeafHashGadget; + type TwoToOneHash = TwoToOneHashGadget; +} + +type LeafVar = [UInt8]; + /// A Merkle tree containing account information. pub type SimpleMerkleTree = MerkleTree; /// The root of the account Merkle tree. -pub type Root = ::Output; +pub type Root = ::Output; /// A membership proof for a given account. pub type SimplePath = Path; // Run this test via `cargo test --release test_merkle_tree`. #[test] fn test_merkle_tree() { - use ark_crypto_primitives::crh::CRH; + use ark_crypto_primitives::crh::CRHScheme; // Let's set up an RNG for use within tests. Note that this is *not* safe // for any production use. let mut rng = ark_std::test_rng(); // First, let's sample the public parameters for the hash functions: - let leaf_crh_params = ::setup(&mut rng).unwrap(); - let two_to_one_crh_params = ::setup(&mut rng).unwrap(); + let leaf_crh_params = ::setup(&mut rng).unwrap(); + let two_to_one_crh_params = ::setup(&mut rng).unwrap(); // Next, let's construct our tree. // This follows the API in https://github.com/arkworks-rs/crypto-primitives/blob/6be606259eab0aec010015e2cfd45e4f134cd9bf/src/merkle_tree/mod.rs#L156 let tree = SimpleMerkleTree::new( &leaf_crh_params, &two_to_one_crh_params, - &[1u8, 2u8, 3u8, 10u8, 9u8, 17u8, 70u8, 45u8], // the i-th entry is the i-th leaf. + &[ + &[1u8][..], + &[2u8][..], + &[3u8][..], + &[10u8][..], + &[9u8][..], + &[17u8][..], + &[70u8][..], + &[45u8][..], + ], // the i-th entry is the i-th leaf. ) .unwrap(); @@ -56,7 +86,7 @@ fn test_merkle_tree() { &leaf_crh_params, &two_to_one_crh_params, &root, - &[9u8], // The claimed leaf + &[9u8][..], // The claimed leaf ) .unwrap(); assert!(result); diff --git a/rollup/Cargo.toml b/rollup/Cargo.toml index 159c831..7710830 100644 --- a/rollup/Cargo.toml +++ b/rollup/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ark-rollup" -version = "0.3.0" +version = "0.5.0" authors = [ "arkworks contributors" ] description = "A SNARK-based rollup for a simple payments system" repository = "https://github.com/arkworks-rs/r1cs-tutorial" @@ -11,21 +11,22 @@ license = "MIT/Apache-2.0" edition = "2018" [dependencies] -ark-ff = { version = "^0.3.0", default-features = false } -ark-ec = { version = "^0.3.0", default-features = false } -ark-ed-on-bls12-381 = { version = "^0.3.0", features = ["r1cs"] } -ark-bls12-381 = { version = "^0.3.0" } -ark-std = { version = "^0.3.0", default-features = false } -ark-relations = { version = "^0.3.0", default-features = false, optional = true } +ark-ff = { version = "^0.5.0", default-features = false } +ark-ec = { version = "^0.5.0", default-features = false } +ark-ed-on-bls12-381 = { version = "^0.5.0", features = ["r1cs"] } +ark-bls12-381 = { version = "^0.5.0" } -ark-r1cs-std = { version = "^0.3.0", optional = true, default-features = false } -ark-snark = { version = "^0.3.0", default-features = false } -ark-groth16 = { version = "^0.3.0" } -ark-gm17 = { version = "^0.3.0" } +ark-std = { version = "^0.5.0", default-features = false } +ark-relations = { version = "^0.5.0", default-features = false, optional = true } -ark-serialize = { version = "^0.3.0", default-features = false } +ark-r1cs-std = { version = "^0.5.0", optional = true, default-features = false } +ark-snark = { version = "^0.5.0", default-features = false } +ark-groth16 = { version = "^0.5.0" } -ark-crypto-primitives = { version = "^0.3.0", default-features = true } + +ark-serialize = { version = "^0.5.0", default-features = false } + +ark-crypto-primitives = { version = "^0.5.0", default-features = true } ark-simple-payments = { path = "../simple-payments", default-features = true } blake2 = { version = "0.9" } digest = "0.9" diff --git a/rollup/src/account.rs b/rollup/src/account.rs index 3c4d996..b2ea12e 100644 --- a/rollup/src/account.rs +++ b/rollup/src/account.rs @@ -1,8 +1,8 @@ use crate::ledger::*; use crate::ConstraintF; use ark_ed_on_bls12_381::{constraints::EdwardsVar, EdwardsProjective}; -use ark_r1cs_std::bits::{uint8::UInt8, ToBytesGadget}; use ark_r1cs_std::prelude::*; +use ark_r1cs_std::uint8::UInt8; use ark_relations::r1cs::{Namespace, SynthesisError}; use ark_simple_payments::account::*; use ark_simple_payments::signature::schnorr::constraints::*; @@ -47,12 +47,9 @@ impl AccountInformationVar { /// Convert the account information to bytes. #[tracing::instrument(target = "r1cs", skip(self))] pub fn to_bytes_le(&self) -> Vec> { - self.public_key - .to_bytes() - .unwrap() - .into_iter() - .chain(self.balance.to_bytes_le()) - .collect() + let mut result = self.public_key.to_bytes_le().unwrap(); + result.extend_from_slice(&self.balance.to_bytes_le()); + result } } diff --git a/rollup/src/ledger.rs b/rollup/src/ledger.rs index abcb5bb..0299028 100644 --- a/rollup/src/ledger.rs +++ b/rollup/src/ledger.rs @@ -1,14 +1,8 @@ use crate::ConstraintF; -use ark_crypto_primitives::crh::injective_map::constraints::{ - PedersenCRHCompressorGadget, TECompressorGadget, -}; -use ark_crypto_primitives::crh::{ - constraints::{CRHGadget, TwoToOneCRHGadget}, - injective_map::TECompressor, -}; + +use ark_crypto_primitives::crh::{CRHSchemeGadget, TwoToOneCRHSchemeGadget}; use ark_crypto_primitives::merkle_tree::constraints::PathVar; use ark_ed_on_bls12_381::{constraints::EdwardsVar, EdwardsProjective}; -use ark_r1cs_std::bits::uint64::UInt64; use ark_r1cs_std::prelude::*; use ark_relations::r1cs::{Namespace, SynthesisError}; use ark_simple_payments::ledger::*; @@ -22,7 +16,7 @@ pub struct AmountVar(pub UInt64); impl AmountVar { #[tracing::instrument(target = "r1cs", skip(self))] pub fn to_bytes_le(&self) -> Vec> { - self.0.to_bytes().unwrap() + self.0.to_bytes_le().unwrap() } #[tracing::instrument(target = "r1cs", skip(self, other))] @@ -33,17 +27,17 @@ impl AmountVar { // converting the field elements to bits // and then checking if the 65th bit is 0. // TODO: Demonstrate via circuit profiling if this needs optimization. - let self_bits = self.0.to_bits_le(); - let self_fe = Boolean::le_bits_to_fp_var(&self_bits)?; - let other_bits = other.0.to_bits_le(); - let other_fe = Boolean::le_bits_to_fp_var(&other_bits)?; + let self_bits = self.0.to_bits_le().unwrap(); + let self_fe = Boolean::le_bits_to_fp(&self_bits)?; + let other_bits = other.0.to_bits_le().unwrap(); + let other_fe = Boolean::le_bits_to_fp(&other_bits)?; let res_fe = self_fe + other_fe; - let res_bz = res_fe.to_bytes()?; + let res_bz = res_fe.to_bytes_le()?; // Ensure 65th bit is 0 // implies 8th word (0-indexed) is 0 res_bz[8].enforce_equal(&UInt8::::constant(0))?; // Add sum - let result = UInt64::addmany(&[self.0.clone(), other.0.clone()])?; + let result = UInt64::wrapping_add_many(&[self.0.clone(), other.0.clone()])?; Ok(AmountVar(result)) } @@ -54,12 +48,12 @@ impl AmountVar { // We then cast the field element to bits, and ensure the top bits are 0. // We then convert these bits to a field element // TODO: Demonstrate via circuit profiling if this needs optimization. - let self_bits = self.0.to_bits_le(); - let self_fe = Boolean::le_bits_to_fp_var(&self_bits)?; - let other_bits = other.0.to_bits_le(); - let other_fe = Boolean::le_bits_to_fp_var(&other_bits)?; + let self_bits = self.0.to_bits_le().unwrap(); + let self_fe = Boolean::le_bits_to_fp(&self_bits)?; + let other_bits = other.0.to_bits_le().unwrap(); + let other_fe = Boolean::le_bits_to_fp(&other_bits)?; let res_fe = self_fe - other_fe; - let res_bz = res_fe.to_bytes()?; + let res_bz = res_fe.to_bytes_le()?; // Ensure top bit is 0 res_bz[res_bz.len() - 1].enforce_equal(&UInt8::::constant(0))?; // Convert to UInt64 @@ -79,28 +73,14 @@ impl AllocVar for AmountVar { } } -pub type TwoToOneHashGadget = PedersenCRHCompressorGadget< - EdwardsProjective, - TECompressor, - TwoToOneWindow, - EdwardsVar, - TECompressorGadget, ->; - -pub type LeafHashGadget = PedersenCRHCompressorGadget< - EdwardsProjective, - TECompressor, - LeafWindow, - EdwardsVar, - TECompressorGadget, ->; - pub type AccRootVar = - >::OutputVar; -pub type AccPathVar = PathVar; -pub type LeafHashParamsVar = >::ParametersVar; + >::OutputVar; + +pub type AccPathVar = PathVar; +pub type LeafHashParamsVar = + >::ParametersVar; pub type TwoToOneHashParamsVar = - >::ParametersVar; + >::ParametersVar; /// The parameters that are used in transaction creation and validation. pub struct ParametersVar { diff --git a/rollup/src/lib.rs b/rollup/src/lib.rs index 49c85de..f64b462 100644 --- a/rollup/src/lib.rs +++ b/rollup/src/lib.rs @@ -1,4 +1,4 @@ -pub type ConstraintF = ark_bls12_381::Fr; +pub type ConstraintF = ark_ed_on_bls12_381::Fq; pub mod account; pub mod ledger; diff --git a/rollup/src/rollup.rs b/rollup/src/rollup.rs index 3cd5c82..08fa79b 100644 --- a/rollup/src/rollup.rs +++ b/rollup/src/rollup.rs @@ -265,6 +265,7 @@ mod test { use ark_simple_payments::account::AccountId; use ark_simple_payments::ledger::{Amount, Parameters, State}; use ark_simple_payments::transaction::Transaction; + use ark_std::rand::SeedableRng; use tracing_subscriber::layer::SubscriberExt; fn test_cs(rollup: Rollup) -> bool { @@ -424,7 +425,7 @@ mod test { .update_balance(alice_id, Amount(1000)) .expect("Alice's account should exist"); // Let's make an account for Bob. - let (bob_id, _bob_pk, bob_sk) = state.sample_keys_and_register(&pp, &mut rng).unwrap(); + let (bob_id, _bob_pk, _bob_sk) = state.sample_keys_and_register(&pp, &mut rng).unwrap(); let amount_to_send = rng.gen_range(0..200); @@ -456,7 +457,7 @@ mod test { // Use a circuit just to generate the circuit let circuit_defining_cs = build_two_tx_circuit(); - let mut rng = ark_std::test_rng(); + let mut rng = ark_std::rand::rngs::StdRng::from_seed([1; 32]); let (pk, vk) = Groth16::::circuit_specific_setup(circuit_defining_cs, &mut rng).unwrap(); @@ -468,8 +469,8 @@ mod test { circuit_to_verify_against.final_root.unwrap(), ]; - let proof = Groth16::prove(&pk, circuit_to_verify_against, &mut rng).unwrap(); - let valid_proof = Groth16::verify(&vk, &public_input, &proof).unwrap(); + let proof = Groth16::::prove(&pk, circuit_to_verify_against, &mut rng).unwrap(); + let valid_proof = Groth16::::verify(&vk, &public_input, &proof).unwrap(); assert!(valid_proof); // Use the same circuit but with different inputs to verify against @@ -481,8 +482,8 @@ mod test { circuit_to_verify_against.final_root.unwrap(), ]; - let proof = Groth16::prove(&pk, circuit_to_verify_against, &mut rng).unwrap(); - let valid_proof = Groth16::verify(&vk, &public_input, &proof).unwrap(); + let proof = Groth16::::prove(&pk, circuit_to_verify_against, &mut rng).unwrap(); + let valid_proof = Groth16::::verify(&vk, &public_input, &proof).unwrap(); assert!(!valid_proof); } } diff --git a/rollup/src/transaction.rs b/rollup/src/transaction.rs index 6e124b3..2305138 100644 --- a/rollup/src/transaction.rs +++ b/rollup/src/transaction.rs @@ -105,14 +105,15 @@ impl TransactionVar { // TODO: FILL IN THE FOLLOWING // let recipient_exists = ??? - // let recipient_updated_correctly = ??? - // TODO: Uncomment the following // sender_exists - // .and(&sender_updated_correctly)? - // .and(&recipient_exists)? - // .and(&recipient_updated_correctly)? - // .and(&sig_verifies) + // & sender_updated_correctly + // & recipient_exists + // & recipient_updated_correctly + // & sig_verifies + // Ok(val) + + // TODO: Comment the following Err(SynthesisError::Unsatisfiable) } } @@ -238,6 +239,7 @@ impl ConstraintSynthesizer for UnaryRollup { let initial_root = AccRootVar::new_input(ark_relations::ns!(cs, "Initial root"), || { Ok(self.initial_root) })?; + // Declare the final root as a public input. let final_root = AccRootVar::new_input(ark_relations::ns!(cs, "Final root"), || Ok(self.final_root))?; @@ -301,6 +303,7 @@ mod test { use ark_relations::r1cs::{ ConstraintLayer, ConstraintSynthesizer, ConstraintSystem, TracingMode::OnlyConstraints, }; + use ark_simple_payments::ledger::{Amount, Parameters, State}; use ark_simple_payments::transaction::Transaction; use tracing_subscriber::layer::SubscriberExt; @@ -312,11 +315,7 @@ mod test { let _guard = tracing::subscriber::set_default(subscriber); let cs = ConstraintSystem::new_ref(); rollup.generate_constraints(cs.clone()).unwrap(); - let result = cs.is_satisfied().unwrap(); - if !result { - println!("{:?}", cs.which_is_unsatisfied()); - } - result + cs.is_satisfied().unwrap() } #[test] @@ -324,6 +323,7 @@ mod test { let mut rng = ark_std::test_rng(); let pp = Parameters::sample(&mut rng); let mut state = State::new(32, &pp); + // Let's make an account for Alice. let (alice_id, _alice_pk, alice_sk) = state.sample_keys_and_register(&pp, &mut rng).unwrap(); @@ -341,6 +341,7 @@ mod test { let rollup = UnaryRollup::with_state_and_transaction(pp.clone(), tx1, &mut temp_state, true) .unwrap(); + assert!(test_cs(rollup)); let mut temp_state = state.clone(); @@ -350,6 +351,7 @@ mod test { let rollup = UnaryRollup::with_state_and_transaction(pp.clone(), bad_tx, &mut temp_state, false) .unwrap(); + assert!(!test_cs(rollup)); } } diff --git a/simple-payments/Cargo.toml b/simple-payments/Cargo.toml index 1a9dd99..b5c1234 100644 --- a/simple-payments/Cargo.toml +++ b/simple-payments/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ark-simple-payments" -version = "0.3.0" +version = "0.5.0" authors = [ "arkworks contributors" ] description = "A simple payments system" repository = "https://github.com/arkworks-rs/r1cs-tutorial" @@ -10,24 +10,28 @@ include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] license = "MIT/Apache-2.0" edition = "2018" +[toolchain] +channel = "nightly" + [dependencies] -ark-ff = { version = "^0.3.0", default-features = false } -ark-ec = { version = "^0.3.0", default-features = false } -ark-ed-on-bls12-381 = { version = "^0.3.0", features = ["r1cs"] } -ark-bls12-381 = { version = "^0.3.0", default-features = false } -ark-std = { version = "^0.3.0", default-features = false } -ark-relations = { version = "^0.3.0", default-features = false, optional = true } +ark-ff = { version = "^0.5.0", default-features = false } +ark-ec = { version = "^0.5.0", default-features = false } +ark-ed-on-bls12-381 = { version = "^0.5.0", features = ["r1cs"] } +ark-bls12-381 = { version = "^0.5.0", default-features = false } +ark-std = { version = "^0.5.0", default-features = false } +ark-relations = { version = "^0.5.0", default-features = false, optional = true } -ark-r1cs-std = { version = "^0.3.0", optional = true, default-features = false } -ark-snark = { version = "^0.3.0", default-features = false } +ark-r1cs-std = { version = "^0.5.0", optional = true, default-features = false } +ark-snark = { version = "^0.5.0", default-features = false } -ark-serialize = { version = "^0.3.0", default-features = false } +ark-serialize = { version = "^0.5.0", default-features = false } -ark-crypto-primitives = { version = "^0.3.0", default-features = true } +ark-crypto-primitives = { version = "^0.5.0", default-features = true, features=["prf", "crh", "merkle_tree"] } blake2 = { version = "0.9" } digest = "0.9" derivative = { version = "2.0", features = ["use_core"] } -tracing = { version = "0.1", default-features = false, features = [ "attributes" ], optional = true } +tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } +tracing-subscriber = { version = "0.2" } [features] default = [ "std", "parallel", "r1cs" ] diff --git a/simple-payments/src/account.rs b/simple-payments/src/account.rs index 1d95dee..23dbc2c 100644 --- a/simple-payments/src/account.rs +++ b/simple-payments/src/account.rs @@ -1,6 +1,7 @@ use crate::ledger::*; use crate::signature::schnorr; use ark_ed_on_bls12_381::EdwardsProjective; +use ark_serialize::CanonicalSerialize; /// Account public key used to verify transaction signatures. pub type AccountPublicKey = schnorr::PublicKey; @@ -37,6 +38,12 @@ pub struct AccountInformation { impl AccountInformation { /// Convert the account information to bytes. pub fn to_bytes_le(&self) -> Vec { - ark_ff::to_bytes![self.public_key, self.balance.to_bytes_le()].unwrap() + let mut public_key_bytes = Vec::new(); + self.public_key + .serialize_uncompressed(&mut public_key_bytes) + .unwrap(); + + public_key_bytes.extend_from_slice(&self.balance.to_bytes_le()); + public_key_bytes } } diff --git a/simple-payments/src/ledger.rs b/simple-payments/src/ledger.rs index 7ce590e..13ad948 100644 --- a/simple-payments/src/ledger.rs +++ b/simple-payments/src/ledger.rs @@ -1,12 +1,20 @@ use crate::account::{AccountId, AccountInformation, AccountPublicKey, AccountSecretKey}; use crate::signature::{schnorr, SignatureScheme}; use crate::transaction::Transaction; +use ark_crypto_primitives::crh::injective_map::constraints::{ + PedersenCRHCompressorGadget, PedersenTwoToOneCRHCompressorGadget, TECompressorGadget, +}; +use ark_crypto_primitives::crh::injective_map::PedersenTwoToOneCRHCompressor; use ark_crypto_primitives::crh::{ injective_map::{PedersenCRHCompressor, TECompressor}, - pedersen, TwoToOneCRH, CRH, + pedersen, CRHScheme, TwoToOneCRHScheme, }; -use ark_crypto_primitives::merkle_tree::{self, MerkleTree, Path}; +use ark_crypto_primitives::crh::{CRHSchemeGadget, TwoToOneCRHSchemeGadget}; +use ark_crypto_primitives::merkle_tree::constraints::{BytesVarDigestConverter, ConfigGadget}; +use ark_crypto_primitives::merkle_tree::{self, ByteDigestConverter, MerkleTree, Path}; +use ark_ed_on_bls12_381::constraints::EdwardsVar; use ark_ed_on_bls12_381::EdwardsProjective; +use ark_r1cs_std::uint8::UInt8; use ark_std::rand::Rng; use std::collections::HashMap; @@ -32,15 +40,15 @@ impl Amount { #[derive(Clone)] pub struct Parameters { pub sig_params: schnorr::Parameters, - pub leaf_crh_params: ::Parameters, - pub two_to_one_crh_params: ::Parameters, + pub leaf_crh_params: ::Parameters, + pub two_to_one_crh_params: ::Parameters, } impl Parameters { pub fn sample(rng: &mut R) -> Self { let sig_params = schnorr::Schnorr::setup(rng).unwrap(); - let leaf_crh_params = ::setup(rng).unwrap(); - let two_to_one_crh_params = ::setup(rng).unwrap(); + let leaf_crh_params = ::setup(rng).unwrap(); + let two_to_one_crh_params = ::setup(rng).unwrap(); Self { sig_params, leaf_crh_params, @@ -49,39 +57,72 @@ impl Parameters { } } -pub type TwoToOneHash = PedersenCRHCompressor; +pub type TwoToOneHash = + PedersenTwoToOneCRHCompressor; + +pub type TwoToOneHashGadget = PedersenTwoToOneCRHCompressorGadget< + EdwardsProjective, + TECompressor, + TwoToOneWindow, + EdwardsVar, + TECompressorGadget, +>; #[derive(Clone, PartialEq, Eq, Hash)] pub struct TwoToOneWindow; // `WINDOW_SIZE * NUM_WINDOWS` = 2 * 256 bits = enough for hashing two outputs. impl pedersen::Window for TwoToOneWindow { - const WINDOW_SIZE: usize = 128; - const NUM_WINDOWS: usize = 4; + const WINDOW_SIZE: usize = 4; + const NUM_WINDOWS: usize = 128; } pub type LeafHash = PedersenCRHCompressor; +pub type LeafHashGadget = PedersenCRHCompressorGadget< + EdwardsProjective, + TECompressor, + LeafWindow, + EdwardsVar, + TECompressorGadget, +>; #[derive(Clone, PartialEq, Eq, Hash)] pub struct LeafWindow; // `WINDOW_SIZE * NUM_WINDOWS` = 2 * 256 bits = enough for hashing two outputs. impl pedersen::Window for LeafWindow { - const WINDOW_SIZE: usize = 144; - const NUM_WINDOWS: usize = 4; + const WINDOW_SIZE: usize = 4; + const NUM_WINDOWS: usize = 144; } +pub type ConstraintF = ark_ed_on_bls12_381::Fq; +type LeafVar = [UInt8]; #[derive(Clone)] pub struct MerkleConfig; impl merkle_tree::Config for MerkleConfig { + type Leaf = [u8]; type LeafHash = LeafHash; type TwoToOneHash = TwoToOneHash; + type LeafDigest = ::Output; + type LeafInnerDigestConverter = ByteDigestConverter; + type InnerDigest = ::Output; +} + +pub struct MerkleConfigVar; +impl ConfigGadget for MerkleConfigVar { + type Leaf = LeafVar; + type LeafDigest = >::OutputVar; + type LeafInnerConverter = BytesVarDigestConverter; + type InnerDigest = + >::OutputVar; + type LeafHash = LeafHashGadget; + type TwoToOneHash = TwoToOneHashGadget; } /// A Merkle tree containing account information. pub type AccMerkleTree = MerkleTree; /// The root of the account Merkle tree. -pub type AccRoot = ::Output; +pub type AccRoot = ::Output; /// A membership proof for a given account. pub type AccPath = Path; diff --git a/simple-payments/src/random_oracle/blake2s/constraints.rs b/simple-payments/src/random_oracle/blake2s/constraints.rs index 6e9a198..f853d07 100644 --- a/simple-payments/src/random_oracle/blake2s/constraints.rs +++ b/simple-payments/src/random_oracle/blake2s/constraints.rs @@ -26,8 +26,8 @@ impl RandomOracleGadget for ROGadget { input_bits.extend_from_slice(&byte.to_bits_le()?); } let mut result = Vec::new(); - for int in evaluate_blake2s(&input_bits)?.into_iter() { - let chunk = int.to_bytes()?; + for int in evaluate_blake2s(&input_bits)?.iter() { + let chunk = int.to_bytes_le().unwrap(); result.extend_from_slice(&chunk); } Ok(OutputVar(result)) diff --git a/simple-payments/src/random_oracle/mod.rs b/simple-payments/src/random_oracle/mod.rs index 200ac2e..dea53fa 100644 --- a/simple-payments/src/random_oracle/mod.rs +++ b/simple-payments/src/random_oracle/mod.rs @@ -1,4 +1,3 @@ -use ark_ff::bytes::ToBytes; use ark_std::hash::Hash; use ark_std::rand::Rng; @@ -13,7 +12,7 @@ pub use constraints::*; /// Interface to a RandomOracle pub trait RandomOracle { - type Output: ToBytes + Clone + Eq + core::fmt::Debug + Hash + Default; + type Output: Clone + Eq + core::fmt::Debug + Hash + Default; type Parameters: Clone + Default; fn setup(r: &mut R) -> Result; diff --git a/simple-payments/src/signature/constraints.rs b/simple-payments/src/signature/constraints.rs index 5fc6f36..068599c 100644 --- a/simple-payments/src/signature/constraints.rs +++ b/simple-payments/src/signature/constraints.rs @@ -1,9 +1,8 @@ +use crate::signature::SignatureScheme; use ark_ff::Field; use ark_r1cs_std::prelude::*; use ark_relations::r1cs::SynthesisError; -use crate::signature::SignatureScheme; - pub trait SigVerifyGadget { type ParametersVar: AllocVar + Clone; @@ -38,13 +37,15 @@ pub trait SigRandomizePkGadget { #[cfg(test)] mod test { use crate::signature::{schnorr, schnorr::constraints::*, *}; - use ark_ec::ProjectiveCurve; + + use ark_ec::CurveGroup; use ark_ed_on_bls12_381::constraints::EdwardsVar as JubJubVar; use ark_ed_on_bls12_381::EdwardsProjective as JubJub; use ark_ff::PrimeField; use ark_r1cs_std::prelude::*; - use ark_relations::r1cs::ConstraintSystem; + use ark_relations::r1cs::{ConstraintLayer, ConstraintSystem, TracingMode}; use ark_std::test_rng; + use tracing_subscriber::layer::SubscriberExt; fn sign_and_verify>( message: &[u8], @@ -55,6 +56,11 @@ mod test { let sig = S::sign(¶meters, &sk, &message, rng).unwrap(); assert!(S::verify(¶meters, &pk, &message, &sig).unwrap()); + // let mut layer = ConstraintLayer::default(); + // layer.mode = TracingMode::All; + // let subscriber = tracing_subscriber::Registry::default().with(layer); + // let _guard = tracing::subscriber::set_default(subscriber); + let cs = ConstraintSystem::::new_ref(); let parameters_var = SG::ParametersVar::new_constant(cs.clone(), parameters).unwrap(); @@ -67,6 +73,7 @@ mod test { let valid_sig_var = SG::verify(¶meters_var, &pk_var, &msg_var, &signature_var).unwrap(); valid_sig_var.enforce_equal(&Boolean::::TRUE).unwrap(); + assert!(cs.is_satisfied().unwrap()); } @@ -79,14 +86,15 @@ mod test { } #[test] - fn schnorr_signature_test() { - type F = ::BaseField; + fn schnorr_signature_test_constraints() { + type F = ::BaseField; let message = "Hi, I am a Schnorr signature!"; sign_and_verify::< F, schnorr::Schnorr, SchnorrSignatureVerifyGadget, >(message.as_bytes()); + failed_verification::>( message.as_bytes(), "Bad message".as_bytes(), diff --git a/simple-payments/src/signature/mod.rs b/simple-payments/src/signature/mod.rs index f380713..07be106 100644 --- a/simple-payments/src/signature/mod.rs +++ b/simple-payments/src/signature/mod.rs @@ -1,5 +1,4 @@ use ark_crypto_primitives::Error; -use ark_ff::bytes::ToBytes; use ark_std::hash::Hash; use ark_std::rand::Rng; @@ -12,8 +11,8 @@ pub mod schnorr; pub trait SignatureScheme { type Parameters: Clone + Send + Sync; - type PublicKey: ToBytes + Hash + Eq + Clone + Default + Send + Sync; - type SecretKey: ToBytes + Clone + Default; + type PublicKey: Hash + Eq + Clone + Default + Send + Sync; + type SecretKey: Clone + Default; type Signature: Clone + Default + Send + Sync; fn setup(rng: &mut R) -> Result; diff --git a/simple-payments/src/signature/schnorr/constraints.rs b/simple-payments/src/signature/schnorr/constraints.rs index b8ee4cc..6e44f6f 100644 --- a/simple-payments/src/signature/schnorr/constraints.rs +++ b/simple-payments/src/signature/schnorr/constraints.rs @@ -1,8 +1,8 @@ -use ark_ec::ProjectiveCurve; -use ark_ff::{to_bytes, Field}; -use ark_r1cs_std::{bits::uint8::UInt8, prelude::*}; -use ark_relations::r1cs::ConstraintSystemRef; +use ark_ec::CurveGroup; +use ark_ff::Field; +use ark_r1cs_std::prelude::*; use ark_relations::r1cs::{Namespace, SynthesisError}; +use ark_serialize::CanonicalSerialize; use ark_std::vec::Vec; use crate::random_oracle::blake2s::constraints::{ParametersVar as B2SParamsVar, ROGadget}; @@ -15,10 +15,10 @@ use core::{borrow::Borrow, marker::PhantomData}; use crate::signature::schnorr::{Parameters, PublicKey, Schnorr, Signature}; -type ConstraintF = <::BaseField as Field>::BasePrimeField; +type ConstraintF = <::BaseField as Field>::BasePrimeField; #[derive(Clone)] -pub struct ParametersVar>> +pub struct ParametersVar>> where for<'a> &'a GC: GroupOpsBounds<'a, C, GC>, { @@ -29,10 +29,10 @@ where #[derive(Derivative)] #[derivative( - Debug(bound = "C: ProjectiveCurve, GC: CurveVar>"), - Clone(bound = "C: ProjectiveCurve, GC: CurveVar>") + Debug(bound = "C: CurveGroup, GC: CurveVar>"), + Clone(bound = "C: CurveGroup, GC: CurveVar>") )] -pub struct PublicKeyVar>> +pub struct PublicKeyVar>> where for<'a> &'a GC: GroupOpsBounds<'a, C, GC>, { @@ -43,10 +43,10 @@ where #[derive(Derivative)] #[derivative( - Debug(bound = "C: ProjectiveCurve, GC: CurveVar>"), - Clone(bound = "C: ProjectiveCurve, GC: CurveVar>") + Debug(bound = "C: CurveGroup, GC: CurveVar>"), + Clone(bound = "C: CurveGroup, GC: CurveVar>") )] -pub struct SignatureVar>> +pub struct SignatureVar>> where for<'a> &'a GC: GroupOpsBounds<'a, C, GC>, { @@ -56,7 +56,7 @@ where _group: PhantomData, } -pub struct SchnorrSignatureVerifyGadget>> +pub struct SchnorrSignatureVerifyGadget>> where for<'a> &'a GC: GroupOpsBounds<'a, C, GC>, { @@ -68,7 +68,7 @@ where impl SigVerifyGadget, ConstraintF> for SchnorrSignatureVerifyGadget where - C: ProjectiveCurve, + C: CurveGroup, GC: CurveVar>, for<'a> &'a GC: GroupOpsBounds<'a, C, GC>, { @@ -84,9 +84,11 @@ where ) -> Result>, SynthesisError> { let prover_response = signature.prover_response.clone(); let verifier_challenge = signature.verifier_challenge.clone(); + let mut claimed_prover_commitment = parameters .generator .scalar_mul_le(prover_response.to_bits_le()?.iter())?; + let public_key_times_verifier_challenge = public_key .pub_key .scalar_mul_le(verifier_challenge.to_bits_le()?.iter())?; @@ -96,14 +98,14 @@ where if parameters.salt.is_some() { hash_input.extend_from_slice(parameters.salt.as_ref().unwrap()); } - hash_input.extend_from_slice(&public_key.pub_key.to_bytes()?); - hash_input.extend_from_slice(&claimed_prover_commitment.to_bytes()?); + + let pub_key_bytes = public_key.pub_key.to_bytes_le().unwrap(); + + hash_input.extend_from_slice(pub_key_bytes.as_slice()); + hash_input.extend_from_slice(claimed_prover_commitment.to_bytes_le().unwrap().as_slice()); hash_input.extend_from_slice(message); - let b2s_params = >>::new_constant( - ConstraintSystemRef::None, - (), - )?; + let b2s_params = B2SParamsVar; let obtained_verifier_challenge = ROGadget::evaluate(&b2s_params, &hash_input)?.0; obtained_verifier_challenge.is_eq(&verifier_challenge.to_vec()) @@ -112,7 +114,7 @@ where impl AllocVar, ConstraintF> for ParametersVar where - C: ProjectiveCurve, + C: CurveGroup, GC: CurveVar>, for<'a> &'a GC: GroupOpsBounds<'a, C, GC>, { @@ -152,7 +154,7 @@ where impl AllocVar, ConstraintF> for PublicKeyVar where - C: ProjectiveCurve, + C: CurveGroup, GC: CurveVar>, for<'a> &'a GC: GroupOpsBounds<'a, C, GC>, { @@ -171,7 +173,8 @@ where impl AllocVar, ConstraintF> for SignatureVar where - C: ProjectiveCurve, + C: CurveGroup, + C::ScalarField: CanonicalSerialize, GC: CurveVar>, for<'a> &'a GC: GroupOpsBounds<'a, C, GC>, { @@ -182,7 +185,11 @@ where ) -> Result { f().and_then(|val| { let cs = cs.into(); - let response_bytes = to_bytes![val.borrow().prover_response].unwrap(); + let mut response_bytes = Vec::new(); + val.borrow() + .prover_response + .serialize_uncompressed(&mut response_bytes) + .unwrap(); let challenge_bytes = val.borrow().verifier_challenge; let mut prover_response = Vec::>>::new(); let mut verifier_challenge = Vec::>>::new(); @@ -211,7 +218,7 @@ where impl EqGadget> for PublicKeyVar where - C: ProjectiveCurve, + C: CurveGroup, GC: CurveVar>, for<'a> &'a GC: GroupOpsBounds<'a, C, GC>, { @@ -243,11 +250,11 @@ where impl ToBytesGadget> for PublicKeyVar where - C: ProjectiveCurve, + C: CurveGroup, GC: CurveVar>, for<'a> &'a GC: GroupOpsBounds<'a, C, GC>, { - fn to_bytes(&self) -> Result>>, SynthesisError> { - self.pub_key.to_bytes() + fn to_bytes_le(&self) -> Result>>, SynthesisError> { + self.pub_key.to_bytes_le() } } diff --git a/simple-payments/src/signature/schnorr/mod.rs b/simple-payments/src/signature/schnorr/mod.rs index c6ccbe1..a58417a 100644 --- a/simple-payments/src/signature/schnorr/mod.rs +++ b/simple-payments/src/signature/schnorr/mod.rs @@ -1,12 +1,11 @@ use super::SignatureScheme; use ark_crypto_primitives::Error; -use ark_ec::{AffineCurve, ProjectiveCurve}; +use ark_ec::{AffineRepr, CurveGroup}; use ark_ff::{ - bytes::ToBytes, fields::{Field, PrimeField}, - to_bytes, ToConstraintField, UniformRand, + ToConstraintField, UniformRand, }; -use ark_std::io::{Result as IoResult, Write}; +use ark_serialize::CanonicalSerialize; use ark_std::rand::Rng; use ark_std::{hash::Hash, marker::PhantomData, vec::Vec}; use blake2::Blake2s; @@ -16,39 +15,32 @@ use derivative::Derivative; #[cfg(feature = "r1cs")] pub mod constraints; -pub struct Schnorr { +pub struct Schnorr { _group: PhantomData, } #[derive(Derivative)] -#[derivative(Clone(bound = "C: ProjectiveCurve"), Debug)] -pub struct Parameters { +#[derivative(Clone(bound = "C: CurveGroup"), Debug)] +pub struct Parameters { pub generator: C::Affine, pub salt: Option<[u8; 32]>, } -pub type PublicKey = ::Affine; +pub type PublicKey = ::Affine; #[derive(Clone, Default, Debug)] -pub struct SecretKey { +pub struct SecretKey { pub secret_key: C::ScalarField, pub public_key: PublicKey, } -impl ToBytes for SecretKey { - #[inline] - fn write(&self, writer: W) -> IoResult<()> { - self.secret_key.write(writer) - } -} - #[derive(Clone, Default, Debug)] -pub struct Signature { +pub struct Signature { pub prover_response: C::ScalarField, pub verifier_challenge: [u8; 32], } -impl SignatureScheme for Schnorr +impl SignatureScheme for Schnorr where C::ScalarField: PrimeField, { @@ -61,7 +53,7 @@ where // let setup_time = start_timer!(|| "SchnorrSig::Setup"); let salt = None; - let generator = C::prime_subgroup_generator().into(); + let generator = C::generator().into(); // end_timer!(setup_time); Ok(Parameters { generator, salt }) @@ -76,7 +68,10 @@ where // Secret is a random scalar x // the pubkey is y = xG let secret_key = C::ScalarField::rand(rng); - let public_key = parameters.generator.mul(secret_key).into(); + let public_key = parameters + .generator + .mul_bigint(secret_key.into_bigint()) + .into(); // end_timer!(keygen_time); Ok(( @@ -101,7 +96,10 @@ where let random_scalar: C::ScalarField = C::ScalarField::rand(rng); // Commit to the random scalar via r := k ยท G. // This is the prover's first msg in the Sigma protocol. - let prover_commitment = parameters.generator.mul(random_scalar).into_affine(); + let prover_commitment = parameters + .generator + .mul_bigint(random_scalar.into_bigint()) + .into_affine(); // Hash everything to get verifier challenge. // e := H(salt || pubkey || r || msg); @@ -109,8 +107,16 @@ where if parameters.salt != None { hash_input.extend_from_slice(¶meters.salt.unwrap()); } - hash_input.extend_from_slice(&to_bytes![sk.public_key]?); - hash_input.extend_from_slice(&to_bytes![prover_commitment]?); + + let mut pk_bytes = Vec::new(); + sk.public_key.serialize_uncompressed(&mut pk_bytes).unwrap(); + + hash_input.extend_from_slice(&pk_bytes); + let mut prover_commitment_bytes = Vec::new(); + prover_commitment + .serialize_uncompressed(&mut prover_commitment_bytes) + .unwrap(); + hash_input.extend_from_slice(&prover_commitment_bytes); hash_input.extend_from_slice(message); let hash_digest = Blake2s::digest(&hash_input); @@ -150,8 +156,11 @@ where // sG = kG - eY // kG = sG + eY // so we first solve for kG. - let mut claimed_prover_commitment = parameters.generator.mul(*prover_response); - let public_key_times_verifier_challenge = pk.mul(verifier_challenge_fe); + let mut claimed_prover_commitment = parameters + .generator + .mul_bigint(prover_response.into_bigint()); + let public_key_times_verifier_challenge = + pk.mul_bigint(verifier_challenge_fe.into_bigint()); claimed_prover_commitment += &public_key_times_verifier_challenge; let claimed_prover_commitment = claimed_prover_commitment.into_affine(); @@ -160,8 +169,14 @@ where if parameters.salt != None { hash_input.extend_from_slice(¶meters.salt.unwrap()); } - hash_input.extend_from_slice(&to_bytes![pk]?); - hash_input.extend_from_slice(&to_bytes![claimed_prover_commitment]?); + let mut pk_bytes = Vec::new(); + pk.serialize_uncompressed(&mut pk_bytes).unwrap(); + hash_input.extend_from_slice(&pk_bytes); + let mut prover_commitment_bytes = Vec::new(); + claimed_prover_commitment + .serialize_uncompressed(&mut prover_commitment_bytes) + .unwrap(); + hash_input.extend_from_slice(&prover_commitment_bytes); hash_input.extend_from_slice(message); // cast the hash output to get e @@ -184,11 +199,13 @@ pub fn bytes_to_bits(bytes: &[u8]) -> Vec { bits } -impl> +impl> ToConstraintField for Parameters +where + C::Affine: ToConstraintField, { #[inline] fn to_field_elements(&self) -> Option> { - self.generator.into_projective().to_field_elements() + self.generator.to_field_elements() } } diff --git a/simple-payments/src/transaction.rs b/simple-payments/src/transaction.rs index 0a7afc8..ee3791c 100644 --- a/simple-payments/src/transaction.rs +++ b/simple-payments/src/transaction.rs @@ -53,11 +53,12 @@ impl Transaction { .account_merkle_tree .generate_proof(self.sender.0 as usize) .expect("path should exist"); + path.verify( ¶meters.leaf_crh_params, ¶meters.two_to_one_crh_params, &state.account_merkle_tree.root(), - &sender_acc_info.to_bytes_le(), + sender_acc_info.to_bytes_le(), ) .unwrap() };