diff --git a/Cargo.toml b/Cargo.toml index 1a0778c..2991a37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,3 +37,4 @@ jsonschema = "0.30.0" [features] default = ["backend_plonky2"] backend_plonky2 = ["plonky2"] +metrics = [] diff --git a/src/backends/plonky2/circuits/mainpod.rs b/src/backends/plonky2/circuits/mainpod.rs index 8e7bce5..b3fc21b 100644 --- a/src/backends/plonky2/circuits/mainpod.rs +++ b/src/backends/plonky2/circuits/mainpod.rs @@ -28,6 +28,7 @@ use crate::{ }, signedpod::SignedPod, }, + measure_gates_begin, measure_gates_end, middleware::{ AnchoredKey, CustomPredicate, CustomPredicateBatch, CustomPredicateRef, NativeOperation, NativePredicate, Params, PodType, PredicatePrefix, Statement, StatementArg, ToFields, @@ -79,12 +80,14 @@ impl OperationVerifyGadget { merkle_claims: &[MerkleClaimTarget], custom_predicate_verification_table: &[HashOutTarget], ) -> Result<()> { + let measure = measure_gates_begin!(builder, "OperationVerify"); let _true = builder._true(); let _false = builder._false(); // Verify that the operation `op` correctly generates the statement `st`. The operation // can reference any of the `prev_statements`. // TODO: Clean this up. + let measure_resolve_op_args = measure_gates_begin!(builder, "ResolveOpArgs"); let resolved_op_args = if prev_statements.is_empty() { (0..self.params.max_operation_args) .map(|_| { @@ -98,6 +101,7 @@ impl OperationVerifyGadget { .map(|&i| builder.vec_ref(&self.params, prev_statements, i)) .collect::>() }; + measure_gates_end!(builder, measure_resolve_op_args); // TODO: Can we have a single table with merkel claims and verified custom predicates // together (with an identifying prefix) and then we only need one random access instead of // two? @@ -113,14 +117,19 @@ impl OperationVerifyGadget { // Certain operations (Contains/NotContains) will refer to one // of the provided Merkle proofs (if any). These proofs have already // been verified, so we need only look up the claim. + let measure_resolve_merkle_claim = measure_gates_begin!(builder, "ResolveMerkleClaim"); let resolved_merkle_claim = (!merkle_claims.is_empty()) .then(|| builder.vec_ref(&self.params, merkle_claims, op.aux[0])); + measure_gates_end!(builder, measure_resolve_merkle_claim); // Operations from custom statements will refer to one // of the provided custom predicates verifications (if any). These operations have already // been verified, so we need only look up the entry. + let measure_resolve_custom_pred_verification = + measure_gates_begin!(builder, "ResolveCustomPredVerification"); let resolved_custom_pred_verification = (!custom_predicate_verification_table.is_empty()) .then(|| builder.vec_ref(&self.params, custom_predicate_verification_table, op.aux[1])); + measure_gates_end!(builder, measure_resolve_custom_pred_verification); // The verification may require aux data which needs to be stored in the // `OperationVerifyTarget` so that we can set during witness generation. @@ -140,7 +149,7 @@ impl OperationVerifyGadget { vec![] } else { vec![ - self.eval_copy(builder, st, &op.op_type, &resolved_op_args)?, + self.eval_copy(builder, st, &op.op_type, &resolved_op_args), self.eval_eq_neq_from_entries(builder, st, &op.op_type, &resolved_op_args), self.eval_lt_lteq_from_entries(builder, st, &op.op_type, &resolved_op_args), self.eval_transitive_eq(builder, st, &op.op_type, &resolved_op_args), @@ -190,6 +199,7 @@ impl OperationVerifyGadget { let ok = builder.any(op_checks); builder.assert_one(ok.target); + measure_gates_end!(builder, measure); Ok(()) } @@ -201,6 +211,7 @@ impl OperationVerifyGadget { resolved_merkle_claim: MerkleClaimTarget, resolved_op_args: &[StatementTarget], ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpContainsFromEntries"); let op_code_ok = op_type.has_native(builder, NativeOperation::ContainsFromEntries); let (arg_types_ok, [merkle_root_value, key_value, value_value]) = @@ -235,7 +246,9 @@ impl OperationVerifyGadget { ); let st_ok = builder.is_equal_flattenable(st, &expected_statement); - builder.all([op_code_ok, arg_types_ok, merkle_proof_ok, st_ok]) + let ok = builder.all([op_code_ok, arg_types_ok, merkle_proof_ok, st_ok]); + measure_gates_end!(builder, measure); + ok } fn eval_not_contains_from_entries( @@ -246,6 +259,7 @@ impl OperationVerifyGadget { resolved_merkle_claim: MerkleClaimTarget, resolved_op_args: &[StatementTarget], ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpNotContainsFromEntries"); let op_code_ok = op_type.has_native(builder, NativeOperation::NotContainsFromEntries); let (arg_types_ok, [merkle_root_value, key_value]) = @@ -278,7 +292,9 @@ impl OperationVerifyGadget { ); let st_ok = builder.is_equal_flattenable(st, &expected_statement); - builder.all([op_code_ok, arg_types_ok, merkle_proof_ok, st_ok]) + let ok = builder.all([op_code_ok, arg_types_ok, merkle_proof_ok, st_ok]); + measure_gates_end!(builder, measure); + ok } fn eval_custom( @@ -289,16 +305,19 @@ impl OperationVerifyGadget { resolved_custom_pred_verification: HashOutTarget, resolved_op_args: &[StatementTarget], ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpCustom"); let query = CustomPredicateVerifyQueryTarget { statement: st.clone(), op_type: op_type.clone(), op_args: resolved_op_args.to_vec(), }; let out_query_hash = query.hash(builder); - builder.is_equal_slice( + let ok = builder.is_equal_slice( &resolved_custom_pred_verification.elements, &out_query_hash.elements, - ) + ); + measure_gates_end!(builder, measure); + ok } /// Carries out the checks necessary for EqualFromEntries and @@ -310,6 +329,7 @@ impl OperationVerifyGadget { op_type: &OperationTypeTarget, resolved_op_args: &[StatementTarget], ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpEqNeqFromEntries"); let eq_op_st_code_ok = { let op_code_ok = op_type.has_native(builder, NativeOperation::EqualFromEntries); let st_code_ok = st.has_native_type(builder, &self.params, NativePredicate::Equal); @@ -346,7 +366,9 @@ impl OperationVerifyGadget { .collect::>(), ); - builder.all([op_st_code_ok, arg_types_ok, op_args_ok, st_args_ok]) + let ok = builder.all([op_st_code_ok, arg_types_ok, op_args_ok, st_args_ok]); + measure_gates_end!(builder, measure); + ok } /// Carries out the checks necessary for LtFromEntries and @@ -358,6 +380,7 @@ impl OperationVerifyGadget { op_type: &OperationTypeTarget, resolved_op_args: &[StatementTarget], ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpLtLteqFromEntries"); let zero = ValueTarget::zero(builder); let one = ValueTarget::one(builder); @@ -414,7 +437,9 @@ impl OperationVerifyGadget { .collect::>(), ); - builder.all([op_st_code_ok, arg_types_ok, st_args_ok]) + let ok = builder.all([op_st_code_ok, arg_types_ok, st_args_ok]); + measure_gates_end!(builder, measure); + ok } fn eval_hash_of( @@ -424,6 +449,7 @@ impl OperationVerifyGadget { op_type: &OperationTypeTarget, resolved_op_args: &[StatementTarget], ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpHashOf"); let op_code_ok = op_type.has_native(builder, NativeOperation::HashOf); let (arg_types_ok, [arg1_value, arg2_value, arg3_value]) = @@ -445,7 +471,9 @@ impl OperationVerifyGadget { ); let st_ok = builder.is_equal_flattenable(st, &expected_statement); - builder.all([op_code_ok, arg_types_ok, hash_value_ok, st_ok]) + let ok = builder.all([op_code_ok, arg_types_ok, hash_value_ok, st_ok]); + measure_gates_end!(builder, measure); + ok } fn eval_sum_of( @@ -455,6 +483,7 @@ impl OperationVerifyGadget { op_type: &OperationTypeTarget, resolved_op_args: &[StatementTarget], ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpSumOf"); let value_zero = ValueTarget::zero(builder); let op_code_ok = op_type.has_native(builder, NativeOperation::SumOf); @@ -481,7 +510,9 @@ impl OperationVerifyGadget { ); let st_ok = builder.is_equal_flattenable(st, &expected_statement); - builder.all([op_code_ok, arg_types_ok, sum_ok, st_ok]) + let ok = builder.all([op_code_ok, arg_types_ok, sum_ok, st_ok]); + measure_gates_end!(builder, measure); + ok } fn eval_product_of( @@ -491,6 +522,7 @@ impl OperationVerifyGadget { op_type: &OperationTypeTarget, resolved_op_args: &[StatementTarget], ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpProductOf"); let value_zero = ValueTarget::zero(builder); let op_code_ok = op_type.has_native(builder, NativeOperation::ProductOf); @@ -517,7 +549,9 @@ impl OperationVerifyGadget { ); let st_ok = builder.is_equal_flattenable(st, &expected_statement); - builder.all([op_code_ok, arg_types_ok, product_ok, st_ok]) + let ok = builder.all([op_code_ok, arg_types_ok, product_ok, st_ok]); + measure_gates_end!(builder, measure); + ok } fn eval_max_of( @@ -527,6 +561,7 @@ impl OperationVerifyGadget { op_type: &OperationTypeTarget, resolved_op_args: &[StatementTarget], ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpMaxOf"); let op_code_ok = op_type.has_native(builder, NativeOperation::MaxOf); let (arg_types_ok, [arg1_value, arg2_value, arg3_value]) = @@ -560,7 +595,9 @@ impl OperationVerifyGadget { ); let st_ok = builder.is_equal_flattenable(st, &expected_statement); - builder.all([op_code_ok, arg_types_ok, arg1_check, st_ok]) + let ok = builder.all([op_code_ok, arg_types_ok, arg1_check, st_ok]); + measure_gates_end!(builder, measure); + ok } fn eval_transitive_eq( @@ -570,6 +607,7 @@ impl OperationVerifyGadget { op_type: &OperationTypeTarget, resolved_op_args: &[StatementTarget], ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpTransitiveEq"); let op_code_ok = op_type.has_native(builder, NativeOperation::TransitiveEqualFromStatements); @@ -594,7 +632,9 @@ impl OperationVerifyGadget { ); let st_ok = builder.is_equal_flattenable(st, &expected_statement); - builder.all([op_code_ok, arg_types_ok, inner_keys_match, st_ok]) + let ok = builder.all([op_code_ok, arg_types_ok, inner_keys_match, st_ok]); + measure_gates_end!(builder, measure); + ok } fn eval_none( &self, @@ -602,13 +642,16 @@ impl OperationVerifyGadget { st: &StatementTarget, op_type: &OperationTypeTarget, ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpNone"); let op_code_ok = op_type.has_native(builder, NativeOperation::None); let expected_statement = StatementTarget::new_native(builder, &self.params, NativePredicate::None, &[]); let st_ok = builder.is_equal_flattenable(st, &expected_statement); - builder.all([op_code_ok, st_ok]) + let ok = builder.all([op_code_ok, st_ok]); + measure_gates_end!(builder, measure); + ok } fn eval_new_entry( @@ -618,6 +661,7 @@ impl OperationVerifyGadget { op_type: &OperationTypeTarget, prev_statements: &[StatementTarget], ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpNewEntry"); let op_code_ok = op_type.has_native(builder, NativeOperation::NewEntry); let st_code_ok = st.has_native_type(builder, &self.params, NativePredicate::ValueOf); @@ -643,7 +687,9 @@ impl OperationVerifyGadget { let no_dupes_ok = builder.not(dupe_check); - builder.all([op_code_ok, st_code_ok, arg_prefix_ok, no_dupes_ok]) + let ok = builder.all([op_code_ok, st_code_ok, arg_prefix_ok, no_dupes_ok]); + measure_gates_end!(builder, measure); + ok } fn eval_lt_to_neq( @@ -653,6 +699,7 @@ impl OperationVerifyGadget { op_type: &OperationTypeTarget, resolved_op_args: &[StatementTarget], ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpLtToNeq"); let op_code_ok = op_type.has_native(builder, NativeOperation::LtToNotEqual); let arg_type_ok = @@ -669,7 +716,9 @@ impl OperationVerifyGadget { ); let st_ok = builder.is_equal_flattenable(st, &expected_statement); - builder.all([op_code_ok, arg_type_ok, st_ok]) + let ok = builder.all([op_code_ok, arg_type_ok, st_ok]); + measure_gates_end!(builder, measure); + ok } fn eval_copy( @@ -678,13 +727,16 @@ impl OperationVerifyGadget { st: &StatementTarget, op_type: &OperationTypeTarget, resolved_op_args: &[StatementTarget], - ) -> Result { + ) -> BoolTarget { + let measure = measure_gates_begin!(builder, "OpCopy"); let op_code_ok = op_type.has_native(builder, NativeOperation::CopyStatement); let expected_statement = &resolved_op_args[0]; let st_ok = builder.is_equal_flattenable(st, expected_statement); - Ok(builder.all([op_code_ok, st_ok])) + let ok = builder.all([op_code_ok, st_ok]); + measure_gates_end!(builder, measure); + ok } } @@ -751,11 +803,13 @@ impl CustomOperationVerifyGadget { st_tmpl: &StatementTmplTarget, args: &[ValueTarget], ) -> StatementTarget { + let measure = measure_gates_begin!(builder, "StatementArgFromTemplate"); let args = st_tmpl .args .iter() .map(|st_tmpl_arg| self.statement_arg_from_template(builder, st_tmpl_arg, args)) .collect(); + measure_gates_end!(builder, measure); StatementTarget { predicate: st_tmpl.pred.clone(), args, @@ -774,6 +828,7 @@ impl CustomOperationVerifyGadget { op_args: &[StatementTarget], args: &[ValueTarget], // arguments to the custom predicate, public and private ) -> Result<(StatementTarget, OperationTypeTarget)> { + let measure = measure_gates_begin!(builder, "CustomOperationVerify"); // Some sanity checks assert_eq!(self.params.max_operation_args, op_args.len()); assert_eq!(self.params.max_custom_predicate_wildcards, args.len()); @@ -828,6 +883,7 @@ impl CustomOperationVerifyGadget { )); builder.assert_one(is_op_args_ok.target); + measure_gates_end!(builder, measure); Ok((statement, op_type)) } } @@ -863,6 +919,7 @@ impl MainPodVerifyGadget { &self, builder: &mut CircuitBuilder, ) -> Result<(Vec, Vec)> { + let measure = measure_gates_begin!(builder, "BuildCustomPredicateTable"); let params = &self.params; let mut custom_predicate_table = Vec::with_capacity(params.max_custom_predicate_batches * params.max_custom_batch_size); @@ -892,6 +949,7 @@ impl MainPodVerifyGadget { } custom_predicate_batches.push(cpb); // We keep this for witness assignment } + measure_gates_end!(builder, measure); Ok((custom_predicate_table, custom_predicate_batches)) } @@ -903,6 +961,7 @@ impl MainPodVerifyGadget { builder: &mut CircuitBuilder, custom_predicate_table: &[HashOutTarget], ) -> Result<(Vec, Vec)> { + let measure = measure_gates_begin!(builder, "BuildCustomPredicateVerificationTable"); let params = &self.params; let mut custom_predicate_verifications = Vec::with_capacity(params.max_custom_predicate_verifications); @@ -944,6 +1003,7 @@ impl MainPodVerifyGadget { custom_predicate_verification_table.push(in_query_hash); custom_predicate_verifications.push(entry); // We keep this for witness assignment } + measure_gates_end!(builder, measure); Ok(( custom_predicate_verification_table, custom_predicate_verifications, @@ -951,6 +1011,7 @@ impl MainPodVerifyGadget { } fn eval(&self, builder: &mut CircuitBuilder) -> Result { + let measure = measure_gates_begin!(builder, "MainPodVerify"); let params = &self.params; // 1. Verify all input signed pods let mut signed_pods = Vec::new(); @@ -1022,8 +1083,10 @@ impl MainPodVerifyGadget { self.build_custom_predicate_verification_table(builder, &custom_predicate_table)?; // 2. Calculate the Pod Id from the public statements + let measure_calc_id = measure_gates_begin!(builder, "MainPodId"); let pub_statements_flattened = pub_statements.iter().flat_map(|s| s.flatten()).collect(); let id = builder.hash_n_to_hash_no_pad::(pub_statements_flattened); + measure_gates_end!(builder, measure_calc_id); // 4. Verify type let type_statement = &pub_statements[0]; @@ -1059,6 +1122,7 @@ impl MainPodVerifyGadget { )?; } + measure_gates_end!(builder, measure); Ok(MainPodVerifyTarget { params: params.clone(), id, diff --git a/src/backends/plonky2/circuits/metrics.rs b/src/backends/plonky2/circuits/metrics.rs new file mode 100644 index 0000000..15f896c --- /dev/null +++ b/src/backends/plonky2/circuits/metrics.rs @@ -0,0 +1,117 @@ +use std::{ + collections::HashMap, + sync::{LazyLock, Mutex}, +}; + +use plonky2::plonk::circuit_builder::CircuitBuilder; + +use crate::{backends::plonky2::basetypes::D, middleware::F}; + +pub static METRICS: LazyLock> = LazyLock::new(|| Mutex::new(Metrics::default())); + +#[derive(Default)] +pub struct Metrics { + gates: Vec<(String, usize)>, + stack: Vec, +} + +pub struct MetricsMeasure { + name: String, + start_num_gates: usize, + ended: bool, +} + +impl Drop for MetricsMeasure { + fn drop(&mut self) { + if !self.ended { + panic!("Measure \"{}\" not ended", self.name); + } + } +} + +impl Metrics { + #[must_use] + pub fn begin( + &mut self, + builder: &CircuitBuilder, + name: impl Into, + ) -> MetricsMeasure { + let name = name.into(); + self.stack.push(name); + MetricsMeasure { + name: self.stack.join("/"), + start_num_gates: builder.num_gates(), + ended: false, + } + } + pub fn end(&mut self, builder: &CircuitBuilder, mut measure: MetricsMeasure) { + self.stack.pop(); + measure.ended = true; + let num_gates = builder.num_gates(); + let delta_gates = num_gates - measure.start_num_gates; + self.gates.push((measure.name.clone(), delta_gates)); + } + pub fn print(&self) { + println!("Gate count:"); + let mut count = HashMap::new(); + for (name, num_gates) in &self.gates { + let n = count.entry(name).or_insert(0); + *n += 1; + println!("- {} [{}]: {}", name, *n, num_gates); + } + } +} + +#[cfg(feature = "metrics")] +pub mod measure_macros { + #[macro_export] + macro_rules! measure_gates_begin { + ($builder:expr, $name:expr) => {{ + use $crate::backends::plonky2::circuits::utils::METRICS; + let mut metrics = METRICS.lock().unwrap(); + metrics.begin($builder, $name) + }}; + } + + #[macro_export] + macro_rules! measure_gates_end { + ($builder:expr, $measure:expr) => {{ + use $crate::backends::plonky2::circuits::utils::METRICS; + let mut metrics = METRICS.lock().unwrap(); + metrics.end($builder, $measure); + }}; + } + + #[macro_export] + macro_rules! measure_gates_print { + () => {{ + use $crate::backends::plonky2::circuits::utils::METRICS; + let metrics = METRICS.lock().unwrap(); + metrics.print(); + }}; + } +} + +#[cfg(not(feature = "metrics"))] +pub mod measure_macros { + #[macro_export] + macro_rules! measure_gates_begin { + ($builder:expr, $name:expr) => { + () + }; + } + + #[macro_export] + macro_rules! measure_gates_end { + ($builder:expr, $measure:expr) => { + let _ = $measure; + }; + } + + #[macro_export] + macro_rules! measure_gates_print { + () => {{ + println!("Gate count disabled: \"metrics\" feature not enabled."); + }}; + } +} diff --git a/src/backends/plonky2/circuits/mod.rs b/src/backends/plonky2/circuits/mod.rs index ea1f498..a865b3c 100644 --- a/src/backends/plonky2/circuits/mod.rs +++ b/src/backends/plonky2/circuits/mod.rs @@ -1,4 +1,5 @@ pub mod common; pub mod mainpod; +pub mod metrics; pub mod signedpod; pub mod utils; diff --git a/src/backends/plonky2/circuits/signedpod.rs b/src/backends/plonky2/circuits/signedpod.rs index 52c66a0..7e460cd 100644 --- a/src/backends/plonky2/circuits/signedpod.rs +++ b/src/backends/plonky2/circuits/signedpod.rs @@ -22,6 +22,7 @@ use crate::{ }, signedpod::SignedPod, }, + measure_gates_begin, measure_gates_end, middleware::{ hash_str, Key, NativePredicate, Params, PodType, RawValue, Value, F, KEY_SIGNER, KEY_TYPE, SELF, @@ -34,6 +35,7 @@ pub struct SignedPodVerifyGadget { impl SignedPodVerifyGadget { pub fn eval(&self, builder: &mut CircuitBuilder) -> Result { + let measure = measure_gates_begin!(builder, "SignedPodVerify"); // 1. Verify id let id = builder.add_virtual_hash(); let mut mt_proofs = Vec::new(); @@ -65,6 +67,7 @@ impl SignedPodVerifyGadget { // 3.c. connect signed message to pod.id builder.connect_values(ValueTarget::from_slice(&id.elements), signature.msg); + measure_gates_end!(builder, measure); Ok(SignedPodVerifyTarget { params: self.params.clone(), id, diff --git a/src/backends/plonky2/mainpod/mod.rs b/src/backends/plonky2/mainpod/mod.rs index f30206b..251e9ff 100644 --- a/src/backends/plonky2/mainpod/mod.rs +++ b/src/backends/plonky2/mainpod/mod.rs @@ -623,9 +623,12 @@ pub mod tests { let params = middleware::Params { // Currently the circuit uses random access that only supports vectors of length 64. // With max_input_main_pods=3 we need random access to a vector of length 73. - max_input_main_pods: 1, + max_input_main_pods: 0, + max_custom_predicate_batches: 0, + max_custom_predicate_verifications: 0, ..Default::default() }; + println!("{:#?}", params); let (gov_id_builder, pay_stub_builder, sanction_list_builder) = zu_kyc_sign_pod_builders(¶ms); @@ -640,6 +643,7 @@ pub mod tests { let mut prover = Prover {}; let kyc_pod = kyc_builder.prove(&mut prover, ¶ms)?; + crate::measure_gates_print!(); let pod = (kyc_pod.pod as Box).downcast::().unwrap(); Ok(pod.verify()?) @@ -741,6 +745,7 @@ pub mod tests { max_custom_predicate_verifications: 8, ..Default::default() }; + println!("{:#?}", params); let mut alice = Signer(SecretKey(RawValue::from(1))); let bob = Signer(SecretKey(RawValue::from(2))); @@ -768,6 +773,7 @@ pub mod tests { let mut prover = Prover {}; let alice_bob_ethdos = alice_bob_ethdos_builder.prove(&mut prover, ¶ms)?; + crate::measure_gates_print!(); let pod = (alice_bob_ethdos.pod as Box) .downcast::() .unwrap(); @@ -790,6 +796,7 @@ pub mod tests { max_custom_predicate_verifications: 2, ..Default::default() }; + println!("{:#?}", params); let mut cpb_builder = CustomPredicateBatchBuilder::new(params.clone(), "cpb".into()); let stb0 = STB::new(NP::ValueOf) @@ -824,6 +831,7 @@ pub mod tests { let mut prover = Prover {}; let pod = pod_builder.prove(&mut prover, ¶ms)?; + crate::measure_gates_print!(); let pod = (pod.pod as Box).downcast::().unwrap(); diff --git a/src/backends/plonky2/primitives/merkletree/circuit.rs b/src/backends/plonky2/primitives/merkletree/circuit.rs index 6c096a2..0bcced8 100644 --- a/src/backends/plonky2/primitives/merkletree/circuit.rs +++ b/src/backends/plonky2/primitives/merkletree/circuit.rs @@ -30,6 +30,7 @@ use crate::{ error::Result, primitives::merkletree::MerkleClaimAndProof, }, + measure_gates_begin, measure_gates_end, middleware::{EMPTY_HASH, EMPTY_VALUE, F, HASH_SIZE}, }; @@ -59,6 +60,7 @@ pub struct MerkleClaimAndProofTarget { impl MerkleProofGadget { /// creates the targets and defines the logic of the circuit pub fn eval(&self, builder: &mut CircuitBuilder) -> Result { + let measure = measure_gates_begin!(builder, format!("MerkleProof_{}", self.max_depth)); let enabled = builder.add_virtual_bool_target_safe(); let root = builder.add_virtual_hash(); let key = builder.add_virtual_value(); @@ -139,6 +141,7 @@ impl MerkleProofGadget { for j in 0..HASH_SIZE { builder.connect(computed_root[j], expected_root[j]); } + measure_gates_end!(builder, measure); Ok(MerkleClaimAndProofTarget { max_depth: self.max_depth, @@ -221,6 +224,8 @@ pub struct MerkleProofExistenceTarget { impl MerkleProofExistenceGadget { /// creates the targets and defines the logic of the circuit pub fn eval(&self, builder: &mut CircuitBuilder) -> Result { + let measure = + measure_gates_begin!(builder, format!("MerkleProofExistence_{}", self.max_depth)); let enabled = builder.add_virtual_bool_target_safe(); let root = builder.add_virtual_hash(); let key = builder.add_virtual_value(); @@ -249,6 +254,7 @@ impl MerkleProofExistenceGadget { for j in 0..HASH_SIZE { builder.connect(computed_root[j], expected_root[j]); } + measure_gates_end!(builder, measure); Ok(MerkleProofExistenceTarget { max_depth: self.max_depth, @@ -494,6 +500,7 @@ pub mod tests { for max_depth in [10, 16, 32, 40, 64, 128, 130, 250, 256] { test_merkleproof_verify_opt(max_depth, true)?; } + crate::measure_gates_print!(); Ok(()) } diff --git a/src/backends/plonky2/primitives/signature/circuit.rs b/src/backends/plonky2/primitives/signature/circuit.rs index 914f697..3c2846b 100644 --- a/src/backends/plonky2/primitives/signature/circuit.rs +++ b/src/backends/plonky2/primitives/signature/circuit.rs @@ -30,6 +30,7 @@ use crate::{ PublicKey, SecretKey, Signature, DUMMY_PUBLIC_INPUTS, DUMMY_SIGNATURE, VP, }, }, + measure_gates_begin, measure_gates_end, middleware::{Hash, RawValue, EMPTY_HASH, EMPTY_VALUE, F, VALUE_SIZE}, }; @@ -65,6 +66,7 @@ impl SignatureVerifyGadget { impl SignatureVerifyGadget { /// creates the targets and defines the logic of the circuit pub fn eval(&self, builder: &mut CircuitBuilder) -> Result { + let measure = measure_gates_begin!(builder, "SignatureVerify"); let enabled = builder.add_virtual_bool_target_safe(); let common_data = VP.0.common.clone(); @@ -115,6 +117,7 @@ impl SignatureVerifyGadget { builder.verify_proof::(&proof_targ, &verifier_data_targ, &common_data); + measure_gates_end!(builder, measure); Ok(SignatureVerifyTarget { verifier_data_targ, enabled,