From 880210c5dcb55d29437a68c11913406704a0eb71 Mon Sep 17 00:00:00 2001 From: Tom French Date: Wed, 26 Apr 2023 22:35:30 +0100 Subject: [PATCH 1/5] feat!: migrate to ACVM 0.10.0 --- Cargo.lock | 12 ++++------ Cargo.toml | 4 +++- src/acvm_interop/proof_system.rs | 2 +- src/acvm_interop/pwg.rs | 37 ++++++++++++----------------- src/barretenberg_structures.rs | 40 +++++++++++++------------------- 5 files changed, 39 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5abcba22..0017bec0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,8 +5,7 @@ version = 3 [[package]] name = "acir" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "018148d69bf14422b1c1d62909a241af2a7f51fec064feb2b01de88fb02b11b8" +source = "git+https://github.com/noir-lang/acvm?rev=15d3c5a9be2dd92f266fcb7e672da17cada9fec5#15d3c5a9be2dd92f266fcb7e672da17cada9fec5" dependencies = [ "acir_field", "flate2", @@ -17,8 +16,7 @@ dependencies = [ [[package]] name = "acir_field" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d40dac25cf6be6335dd86286caeac859afd0dc74a4a75c64eed041b0f00a278" +source = "git+https://github.com/noir-lang/acvm?rev=15d3c5a9be2dd92f266fcb7e672da17cada9fec5#15d3c5a9be2dd92f266fcb7e672da17cada9fec5" dependencies = [ "ark-bn254", "ark-ff", @@ -31,8 +29,7 @@ dependencies = [ [[package]] name = "acvm" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17b7bc8f2b2215075b8e080ba3a0b8b7d759f04bc44b27e5bb8d845f4c77f20" +source = "git+https://github.com/noir-lang/acvm?rev=15d3c5a9be2dd92f266fcb7e672da17cada9fec5#15d3c5a9be2dd92f266fcb7e672da17cada9fec5" dependencies = [ "acir", "acvm_stdlib", @@ -69,8 +66,7 @@ dependencies = [ [[package]] name = "acvm_stdlib" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ce2d19a9d1e7ff1bf415ed909b43031e33ef6df21be70e470bb1817b3e6989" +source = "git+https://github.com/noir-lang/acvm?rev=15d3c5a9be2dd92f266fcb7e672da17cada9fec5#15d3c5a9be2dd92f266fcb7e672da17cada9fec5" dependencies = [ "acir", ] diff --git a/Cargo.toml b/Cargo.toml index 5e0086c0..988507f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,9 @@ license = "MIT OR Apache-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -acvm = { version = "0.9.0", features = ["bn254"] } +#acvm = { version = "0.9.0", features = ["bn254"] } +acvm = { git = "https://github.com/noir-lang/acvm", rev = "15d3c5a9be2dd92f266fcb7e672da17cada9fec5", features = ["bn254"] } + blake2 = "0.9.1" dirs = { version = "3.0", optional = true } reqwest = { version = "0.11.16", optional = true, default-features = false, features = ["stream", "rustls-tls"] } diff --git a/src/acvm_interop/proof_system.rs b/src/acvm_interop/proof_system.rs index d69cbd28..f798b448 100644 --- a/src/acvm_interop/proof_system.rs +++ b/src/acvm_interop/proof_system.rs @@ -23,7 +23,7 @@ impl ProofSystemCompiler for Barretenberg { | BlackBoxFunc::RANGE | BlackBoxFunc::SHA256 | BlackBoxFunc::Blake2s - | BlackBoxFunc::MerkleMembership + | BlackBoxFunc::ComputeMerkleRoot | BlackBoxFunc::SchnorrVerify | BlackBoxFunc::Pedersen | BlackBoxFunc::HashToField128Security diff --git a/src/acvm_interop/pwg.rs b/src/acvm_interop/pwg.rs index 7d9ab7a3..2826232a 100644 --- a/src/acvm_interop/pwg.rs +++ b/src/acvm_interop/pwg.rs @@ -25,19 +25,19 @@ impl PartialWitnessGenerator for Barretenberg { BlackBoxFunc::SHA256 => hash::sha256(initial_witness, func_call), BlackBoxFunc::Blake2s => hash::blake2s(initial_witness, func_call), BlackBoxFunc::EcdsaSecp256k1 => { - signature::ecdsa::secp256k1_prehashed(initial_witness, func_call)? + signature::ecdsa::secp256k1_prehashed(initial_witness, func_call) } - BlackBoxFunc::AES | BlackBoxFunc::Keccak256 => { - return Err(OpcodeResolutionError::UnsupportedBlackBoxFunc( - func_call.name, - )) + + BlackBoxFunc::AND | BlackBoxFunc::XOR => { + logic::solve_logic_opcode(initial_witness, func_call) } - BlackBoxFunc::MerkleMembership => { + BlackBoxFunc::RANGE => range::solve_range_opcode(initial_witness, func_call), + BlackBoxFunc::AES | BlackBoxFunc::Keccak256 => Err( + OpcodeResolutionError::UnsupportedBlackBoxFunc(func_call.name), + ), + BlackBoxFunc::ComputeMerkleRoot => { let mut inputs_iter = func_call.inputs.iter(); - let _root = inputs_iter.next().expect("expected a root"); - let root = witness_to_value(initial_witness, _root.witness)?; - let _leaf = inputs_iter.next().expect("expected a leaf"); let leaf = witness_to_value(initial_witness, _leaf.witness)?; @@ -55,13 +55,8 @@ impl PartialWitnessGenerator for Barretenberg { leaf, ); - let result = if &computed_merkle_root == root { - FieldElement::one() - } else { - FieldElement::zero() - }; - - initial_witness.insert(func_call.outputs[0], result); + initial_witness.insert(func_call.outputs[0], computed_merkle_root); + Ok(OpcodeResolution::Solved) } BlackBoxFunc::SchnorrVerify => { // In barretenberg, if the signature fails, then the whole thing fails. @@ -116,6 +111,7 @@ impl PartialWitnessGenerator for Barretenberg { }; initial_witness.insert(func_call.outputs[0], result); + Ok(OpcodeResolution::Solved) } BlackBoxFunc::Pedersen => { let inputs_iter = func_call.inputs.iter(); @@ -128,6 +124,7 @@ impl PartialWitnessGenerator for Barretenberg { let (res_x, res_y) = self.encrypt(scalars); initial_witness.insert(func_call.outputs[0], res_x); initial_witness.insert(func_call.outputs[1], res_y); + Ok(OpcodeResolution::Solved) } BlackBoxFunc::HashToField128Security => { let mut hasher = ::new(); @@ -149,6 +146,7 @@ impl PartialWitnessGenerator for Barretenberg { assert_eq!(func_call.outputs.len(), 1); initial_witness.insert(func_call.outputs[0], reduced_res); + Ok(OpcodeResolution::Solved) } BlackBoxFunc::FixedBaseScalarMul => { let scalar = witness_to_value(initial_witness, func_call.inputs[0].witness)?; @@ -157,13 +155,8 @@ impl PartialWitnessGenerator for Barretenberg { initial_witness.insert(func_call.outputs[0], pub_x); initial_witness.insert(func_call.outputs[1], pub_y); + Ok(OpcodeResolution::Solved) } - BlackBoxFunc::AND | BlackBoxFunc::XOR => { - logic::solve_logic_opcode(initial_witness, func_call)? - } - BlackBoxFunc::RANGE => range::solve_range_opcode(initial_witness, func_call)?, } - - Ok(OpcodeResolution::Solved) } } diff --git a/src/barretenberg_structures.rs b/src/barretenberg_structures.rs index 29d666a9..9f41ecb3 100644 --- a/src/barretenberg_structures.rs +++ b/src/barretenberg_structures.rs @@ -170,15 +170,14 @@ impl SchnorrConstraint { } } #[derive(Clone, Hash, Debug)] -pub(crate) struct MerkleMembershipConstraint { +pub(crate) struct ComputeMerkleRootConstraint { pub(crate) hash_path: Vec, - pub(crate) root: i32, pub(crate) leaf: i32, pub(crate) index: i32, pub(crate) result: i32, } -impl MerkleMembershipConstraint { +impl ComputeMerkleRootConstraint { fn to_bytes(&self) -> Vec { let mut buffer = Vec::new(); @@ -189,7 +188,6 @@ impl MerkleMembershipConstraint { buffer.extend_from_slice(&constraint.to_be_bytes()); } - buffer.extend_from_slice(&self.root.to_be_bytes()); buffer.extend_from_slice(&self.leaf.to_be_bytes()); buffer.extend_from_slice(&self.result.to_be_bytes()); buffer.extend_from_slice(&self.index.to_be_bytes()); @@ -364,7 +362,7 @@ pub(crate) struct ConstraintSystem { logic_constraints: Vec, range_constraints: Vec, sha256_constraints: Vec, - merkle_membership_constraints: Vec, + compute_merkle_root_constraints: Vec, schnorr_constraints: Vec, ecdsa_secp256k1_constraints: Vec, blake2s_constraints: Vec, @@ -411,11 +409,11 @@ impl ConstraintSystem { self } - pub(crate) fn merkle_membership_constraints( + pub(crate) fn compute_merkle_root_constraints( mut self, - merkle_membership_constraints: Vec, + compute_merkle_root_constraints: Vec, ) -> Self { - self.merkle_membership_constraints = merkle_membership_constraints; + self.compute_merkle_root_constraints = compute_merkle_root_constraints; self } @@ -511,10 +509,10 @@ impl ConstraintSystem { buffer.extend(&constraint.to_bytes()); } - // Serialize each Merkle Membership constraint - let merkle_membership_constraints_len = self.merkle_membership_constraints.len() as u32; - buffer.extend_from_slice(&merkle_membership_constraints_len.to_be_bytes()); - for constraint in self.merkle_membership_constraints.iter() { + // Serialize each Compute Merkle Root constraint + let compute_merkle_root_constraints = self.compute_merkle_root_constraints.len() as u32; + buffer.extend_from_slice(&compute_merkle_root_constraints.to_be_bytes()); + for constraint in self.compute_merkle_root_constraints.iter() { buffer.extend(&constraint.to_bytes()); } @@ -581,7 +579,7 @@ impl From<&Circuit> for ConstraintSystem { let mut sha256_constraints: Vec = Vec::new(); let mut blake2s_constraints: Vec = Vec::new(); let mut pedersen_constraints: Vec = Vec::new(); - let mut merkle_membership_constraints: Vec = Vec::new(); + let mut compute_merkle_root_constraints: Vec = Vec::new(); let mut schnorr_constraints: Vec = Vec::new(); let mut ecdsa_secp256k1_constraints: Vec = Vec::new(); let mut fixed_base_scalar_mul_constraints: Vec = Vec::new(); @@ -702,14 +700,9 @@ impl From<&Circuit> for ConstraintSystem { blake2s_constraints.push(blake2s_constraint); } - BlackBoxFunc::MerkleMembership => { + BlackBoxFunc::ComputeMerkleRoot => { let mut inputs_iter = gadget_call.inputs.iter().peekable(); - // root - let root = { - let root_input = inputs_iter.next().expect("missing Merkle root"); - root_input.witness.witness_index() as i32 - }; // leaf let leaf = { let leaf_input = inputs_iter @@ -735,18 +728,17 @@ impl From<&Circuit> for ConstraintSystem { hash_path.push(path_elem_index); } - // result + // computed root let result = gadget_call.outputs[0].witness_index() as i32; - let constraint = MerkleMembershipConstraint { + let constraint = ComputeMerkleRootConstraint { hash_path, - root, leaf, index, result, }; - merkle_membership_constraints.push(constraint); + compute_merkle_root_constraints.push(constraint); } BlackBoxFunc::SchnorrVerify => { let mut inputs_iter = gadget_call.inputs.iter(); @@ -921,7 +913,7 @@ impl From<&Circuit> for ConstraintSystem { logic_constraints, range_constraints, sha256_constraints, - merkle_membership_constraints, + compute_merkle_root_constraints, pedersen_constraints, schnorr_constraints, ecdsa_secp256k1_constraints, From e7c4a2cc68c9d14b083290a3715e97ab05d163e7 Mon Sep 17 00:00:00 2001 From: Tom French Date: Thu, 27 Apr 2023 19:28:22 +0100 Subject: [PATCH 2/5] chore: update barretenberg commit --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 7c01326f..87d1d24c 100644 --- a/flake.lock +++ b/flake.lock @@ -10,11 +10,11 @@ ] }, "locked": { - "lastModified": 1682345890, - "narHash": "sha256-ZsInK9Iy81MaCugouU3ifa5Vw2GKlJK9MxCU/LF8bIw=", + "lastModified": 1682617186, + "narHash": "sha256-CpkYOfcFSQ7Gv1N5jlho//i0JbIpXF18lqXfQYxx4LY=", "owner": "AztecProtocol", "repo": "barretenberg", - "rev": "87aeb375d7b434e0faf47abb79f97753ab760987", + "rev": "74dbce5dfa126ecd6dbda7b758581752f7b6a389", "type": "github" }, "original": { From f148f4b57a0efb57d8e8faf255fe0fce2bbc441e Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 27 Apr 2023 21:16:27 +0100 Subject: [PATCH 3/5] Update barretenberg_structures.rs --- src/barretenberg_structures.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/barretenberg_structures.rs b/src/barretenberg_structures.rs index 9f41ecb3..bbce13bb 100644 --- a/src/barretenberg_structures.rs +++ b/src/barretenberg_structures.rs @@ -510,8 +510,8 @@ impl ConstraintSystem { } // Serialize each Compute Merkle Root constraint - let compute_merkle_root_constraints = self.compute_merkle_root_constraints.len() as u32; - buffer.extend_from_slice(&compute_merkle_root_constraints.to_be_bytes()); + let compute_merkle_root_constraints_len = self.compute_merkle_root_constraints.len() as u32; + buffer.extend_from_slice(&compute_merkle_root_constraints_len.to_be_bytes()); for constraint in self.compute_merkle_root_constraints.iter() { buffer.extend(&constraint.to_bytes()); } From df894f70a719e6ce80b107e35c7ec7e9b8363b98 Mon Sep 17 00:00:00 2001 From: Tom French Date: Fri, 28 Apr 2023 13:01:42 +0100 Subject: [PATCH 4/5] feat: add test for `compute_merkle_root` constraint --- src/composer.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/src/composer.rs b/src/composer.rs index a066ec01..adf682ae 100644 --- a/src/composer.rs +++ b/src/composer.rs @@ -442,8 +442,12 @@ mod test { use acvm::FieldElement; use super::*; - use crate::barretenberg_structures::{ - Constraint, LogicConstraint, PedersenConstraint, RangeConstraint, SchnorrConstraint, + use crate::{ + barretenberg_structures::{ + ComputeMerkleRootConstraint, Constraint, LogicConstraint, PedersenConstraint, + RangeConstraint, SchnorrConstraint, + }, + merkle::{MerkleTree, MessageHasher}, }; #[test] @@ -761,6 +765,57 @@ mod test { test_composer_with_pk_vk(constraint_system, vec![case_1]); } + #[test] + fn test_compute_merkle_root_constraint() { + use tempfile::tempdir; + let temp_dir = tempdir().unwrap(); + let mut msg_hasher: blake2::Blake2s = MessageHasher::new(); + + let tree: MerkleTree = MerkleTree::new(3, &temp_dir); + + let empty_leaf = vec![0; 64]; + + let index = FieldElement::zero(); + let index_as_usize: usize = 0; + let mut index_bits = index.bits(); + index_bits.reverse(); + + let leaf = msg_hasher.hash(&empty_leaf); + + let root = tree.root(); + + let hash_path = tree.get_hash_path(index_as_usize); + let mut hash_path_ref = Vec::new(); + for (i, path_pair) in hash_path.into_iter().enumerate() { + let path_bit = index_bits[i]; + let hash = if !path_bit { path_pair.1 } else { path_pair.0 }; + hash_path_ref.push(hash); + } + let hash_path_ref: Vec = hash_path_ref.into_iter().collect(); + + let constraint = ComputeMerkleRootConstraint { + hash_path: (3..3 + hash_path_ref.len() as i32).collect(), + leaf: 0, + index: 1, + result: 2, + }; + + let constraint_system = ConstraintSystem::new() + .var_num(500) + .compute_merkle_root_constraints(vec![constraint]); + + let mut witness_values = vec![leaf, index, root]; + witness_values.extend(hash_path_ref); + + let case_1 = WitnessResult { + witness: witness_values.into(), + public_inputs: vec![].into(), + result: true, + }; + + test_composer_with_pk_vk(constraint_system, vec![case_1]); + } + #[test] fn test_logic_constraints() { /* From b8eab9b8348e3a761d434aab7724616ddc3c3b45 Mon Sep 17 00:00:00 2001 From: Tom French Date: Fri, 28 Apr 2023 16:03:18 +0100 Subject: [PATCH 5/5] chore: switch to crates.io version of ACVM --- Cargo.lock | 20 ++++++++++++-------- Cargo.toml | 3 +-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0017bec0..b24136f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,8 +4,9 @@ version = 3 [[package]] name = "acir" -version = "0.9.0" -source = "git+https://github.com/noir-lang/acvm?rev=15d3c5a9be2dd92f266fcb7e672da17cada9fec5#15d3c5a9be2dd92f266fcb7e672da17cada9fec5" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "510b65efd4d20bf266185ce0a5dc7d29bcdd196a6a1835c20908fd88040de76c" dependencies = [ "acir_field", "flate2", @@ -15,8 +16,9 @@ dependencies = [ [[package]] name = "acir_field" -version = "0.9.0" -source = "git+https://github.com/noir-lang/acvm?rev=15d3c5a9be2dd92f266fcb7e672da17cada9fec5#15d3c5a9be2dd92f266fcb7e672da17cada9fec5" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f032e710c67fd146caedc8fe1dea6e95f01ab59453e42d59b604a51fef3dfe" dependencies = [ "ark-bn254", "ark-ff", @@ -28,8 +30,9 @@ dependencies = [ [[package]] name = "acvm" -version = "0.9.0" -source = "git+https://github.com/noir-lang/acvm?rev=15d3c5a9be2dd92f266fcb7e672da17cada9fec5#15d3c5a9be2dd92f266fcb7e672da17cada9fec5" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2611266039740ffd1978f23258bd6ce3166c22cf15b8227685c2f3bb20ae2ee0" dependencies = [ "acir", "acvm_stdlib", @@ -65,8 +68,9 @@ dependencies = [ [[package]] name = "acvm_stdlib" -version = "0.9.0" -source = "git+https://github.com/noir-lang/acvm?rev=15d3c5a9be2dd92f266fcb7e672da17cada9fec5#15d3c5a9be2dd92f266fcb7e672da17cada9fec5" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ec51160c66eba75dc15a028a2391675386fd395b3897478d89a386c64a48dd" dependencies = [ "acir", ] diff --git a/Cargo.toml b/Cargo.toml index 988507f6..d7902141 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,7 @@ license = "MIT OR Apache-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -#acvm = { version = "0.9.0", features = ["bn254"] } -acvm = { git = "https://github.com/noir-lang/acvm", rev = "15d3c5a9be2dd92f266fcb7e672da17cada9fec5", features = ["bn254"] } +acvm = { version = "0.10.3", features = ["bn254"] } blake2 = "0.9.1" dirs = { version = "3.0", optional = true }