From 190c6063f52645cbcf4b915fd0b2d3c3b904430d Mon Sep 17 00:00:00 2001 From: M Alghazwi Date: Mon, 10 Mar 2025 14:53:59 +0100 Subject: [PATCH] impl compression and public input verification circuits. --- .../src/circuits/sample_cells.rs | 7 +- codex-plonky2-circuits/src/error.rs | 6 + .../src/recursion/uniform/compress.rs | 129 + .../src/recursion/uniform/leaf.rs | 1 - .../src/recursion/uniform/mod.rs | 4 +- .../src/recursion/uniform/node.rs | 3 +- .../src/recursion/uniform/pi_verifier.rs | 289 +++ .../src/recursion/uniform/tree.rs | 89 +- proof-input/Cargo.toml | 6 +- proof-input/src/recursion/uniform.rs | 101 +- workflow/benches/compression.rs | 111 + workflow/input.json | 2081 ----------------- 12 files changed, 726 insertions(+), 2101 deletions(-) create mode 100644 codex-plonky2-circuits/src/recursion/uniform/compress.rs create mode 100644 codex-plonky2-circuits/src/recursion/uniform/pi_verifier.rs create mode 100644 workflow/benches/compression.rs delete mode 100644 workflow/input.json diff --git a/codex-plonky2-circuits/src/circuits/sample_cells.rs b/codex-plonky2-circuits/src/circuits/sample_cells.rs index ff8c59b..5d4f454 100644 --- a/codex-plonky2-circuits/src/circuits/sample_cells.rs +++ b/codex-plonky2-circuits/src/circuits/sample_cells.rs @@ -19,7 +19,8 @@ use plonky2::{ }, plonk::circuit_builder::CircuitBuilder, }; -use plonky2::plonk::config::AlgebraicHasher; +use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData}; +use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; use plonky2_poseidon2::poseidon2_hash::poseidon2::Poseidon2; use crate::{ @@ -55,6 +56,7 @@ impl< phantom_data: Default::default(), } } + } /// struct of input to the circuit as targets @@ -350,10 +352,9 @@ impl< // circuit params let CircuitParams { max_depth, - max_log2_n_slots, - block_tree_depth, n_field_elems_per_cell, n_samples, + .. } = self.params; // assign n_cells_per_slot diff --git a/codex-plonky2-circuits/src/error.rs b/codex-plonky2-circuits/src/error.rs index 74ba35c..6d31718 100644 --- a/codex-plonky2-circuits/src/error.rs +++ b/codex-plonky2-circuits/src/error.rs @@ -68,4 +68,10 @@ pub enum CircuitError { #[error("Expected Option {0} to contain value")] OptionError(String), + + #[error("Public input length Error: Expected {0}, got {1}")] + PublicInputLengthError(usize, usize), + + #[error("{0}")] + InvalidArgument(String), } \ No newline at end of file diff --git a/codex-plonky2-circuits/src/recursion/uniform/compress.rs b/codex-plonky2-circuits/src/recursion/uniform/compress.rs new file mode 100644 index 0000000..1bdc8b6 --- /dev/null +++ b/codex-plonky2-circuits/src/recursion/uniform/compress.rs @@ -0,0 +1,129 @@ +use std::marker::PhantomData; +use plonky2::hash::hash_types::RichField; +use plonky2::iop::witness::{PartialWitness, WitnessWrite}; +use plonky2::plonk::circuit_builder::CircuitBuilder; +use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData, CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData}; +use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; +use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; +use plonky2_field::extension::Extendable; +use plonky2_poseidon2::poseidon2_hash::poseidon2::Poseidon2; +use crate::{error::CircuitError,Result}; + +/// recursion compression circuit - verifies 1 inner proof +#[derive(Clone, Debug)] +pub struct CompressionCircuit< + F: RichField + Extendable + Poseidon2, + const D: usize, + C: GenericConfig, + H: AlgebraicHasher, +> where + >::Hasher: AlgebraicHasher +{ + inner_common_data: CommonCircuitData, + phantom_data: PhantomData<(C,H)> +} + +#[derive(Clone, Debug)] +pub struct CompressionTargets< + const D: usize, +>{ + pub inner_proof: ProofWithPublicInputsTarget, + pub verifier_data: VerifierCircuitTarget, +} + +impl< + F: RichField + Extendable + Poseidon2, + const D: usize, + C: GenericConfig, + H: AlgebraicHasher, +> CompressionCircuit where + >::Hasher: AlgebraicHasher +{ + pub fn new(inner_common_data: CommonCircuitData) -> Self { + Self{ + inner_common_data, + phantom_data:PhantomData::default(), + } + } + + /// build the compression circuit + pub fn build(&self, builder: &mut CircuitBuilder) -> Result> { + + let inner_common = self.inner_common_data.clone(); + + // the proof virtual targets + let vir_proof = builder.add_virtual_proof_with_pis(&inner_common); + let inner_pub_input = vir_proof.public_inputs.clone(); + + // take the public input from inner proof & make it public + assert_eq!(inner_pub_input.len(), 8); + builder.register_public_inputs(&inner_pub_input[0..4]); + + // virtual target for the verifier data + let inner_verifier_data = builder.add_virtual_verifier_data(inner_common.config.fri_config.cap_height); + + // register verifier data hash as public input. + let mut vd_pub_input = vec![]; + vd_pub_input.extend_from_slice(&inner_verifier_data.circuit_digest.elements); + for i in 0..builder.config.fri_config.num_cap_elements() { + vd_pub_input.extend_from_slice(&inner_verifier_data.constants_sigmas_cap.0[i].elements); + } + let hash_inner_vd_pub_input = builder.hash_n_to_hash_no_pad::(vd_pub_input); + let mut vd_to_hash = vec![]; + vd_to_hash.extend_from_slice(&inner_pub_input[4..8]); + vd_to_hash.extend_from_slice(&hash_inner_vd_pub_input.elements); + let vd_hash = builder.hash_n_to_hash_no_pad::(vd_to_hash); + builder.register_public_inputs(&vd_hash.elements); + + // verify the proofs in-circuit + builder.verify_proof::(&vir_proof, &inner_verifier_data, &inner_common); + + // return targets + let t = CompressionTargets { + inner_proof: vir_proof, + verifier_data: inner_verifier_data, + }; + Ok(t) + + } + + /// assign the compression targets with given input + pub fn assign_targets( + &self, pw: &mut PartialWitness, + targets: &CompressionTargets, + inner_proof: ProofWithPublicInputs, + verifier_only_data: &VerifierOnlyCircuitData, + ) -> Result<()> { + // assign the proof + pw.set_proof_with_pis_target(&targets.inner_proof, &inner_proof) + .map_err(|e| { + CircuitError::ProofTargetAssignmentError("inner-proof".to_string(), e.to_string()) + })?; + + // assign the verifier data + pw.set_verifier_data_target(&targets.verifier_data, verifier_only_data) + .map_err(|e| { + CircuitError::VerifierDataTargetAssignmentError(e.to_string()) + })?; + + Ok(()) + } + + /// returns the compression circuit data + pub fn get_circuit_data (&self) -> Result> + where + >::Hasher: AlgebraicHasher + { + let config = CircuitConfig::standard_recursion_config(); + let mut builder = CircuitBuilder::::new(config.clone()); + + self.build(&mut builder)?; + + let circ_data = builder.build::(); + + Ok(circ_data) + } + +} + + diff --git a/codex-plonky2-circuits/src/recursion/uniform/leaf.rs b/codex-plonky2-circuits/src/recursion/uniform/leaf.rs index ff1fc49..6269fff 100644 --- a/codex-plonky2-circuits/src/recursion/uniform/leaf.rs +++ b/codex-plonky2-circuits/src/recursion/uniform/leaf.rs @@ -7,7 +7,6 @@ use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; use plonky2_field::extension::Extendable; use plonky2_poseidon2::poseidon2_hash::poseidon2::Poseidon2; -// use crate::recursion::circuits::inner_circuit::InnerCircuit; use crate::{error::CircuitError,Result}; /// recursion leaf circuit - verifies N inner proof diff --git a/codex-plonky2-circuits/src/recursion/uniform/mod.rs b/codex-plonky2-circuits/src/recursion/uniform/mod.rs index 6daaa29..08e3905 100644 --- a/codex-plonky2-circuits/src/recursion/uniform/mod.rs +++ b/codex-plonky2-circuits/src/recursion/uniform/mod.rs @@ -1,3 +1,5 @@ pub mod leaf; pub mod node; -pub mod tree; \ No newline at end of file +pub mod tree; +pub mod compress; +pub mod pi_verifier; \ No newline at end of file diff --git a/codex-plonky2-circuits/src/recursion/uniform/node.rs b/codex-plonky2-circuits/src/recursion/uniform/node.rs index 3ec302c..468bb3f 100644 --- a/codex-plonky2-circuits/src/recursion/uniform/node.rs +++ b/codex-plonky2-circuits/src/recursion/uniform/node.rs @@ -7,11 +7,10 @@ use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; use plonky2_field::extension::Extendable; use plonky2_poseidon2::poseidon2_hash::poseidon2::Poseidon2; -// use crate::recursion::circuits::inner_circuit::InnerCircuit; use crate::{error::CircuitError,Result}; use crate::circuits::utils::vec_to_array; -/// recursion node circuit - verifies 2 leaf proofs +/// recursion node circuit - verifies M leaf proofs #[derive(Clone, Debug)] pub struct NodeCircuit< F: RichField + Extendable + Poseidon2, diff --git a/codex-plonky2-circuits/src/recursion/uniform/pi_verifier.rs b/codex-plonky2-circuits/src/recursion/uniform/pi_verifier.rs new file mode 100644 index 0000000..2da9319 --- /dev/null +++ b/codex-plonky2-circuits/src/recursion/uniform/pi_verifier.rs @@ -0,0 +1,289 @@ +use std::marker::PhantomData; +use plonky2::hash::hash_types::{HashOut, HashOutTarget, RichField}; +use plonky2::iop::target::Target; +use plonky2::iop::witness::{PartialWitness, WitnessWrite}; +use plonky2::plonk::circuit_builder::{CircuitBuilder}; +use plonky2::plonk::circuit_data::{CommonCircuitData, VerifierCircuitData, VerifierCircuitTarget}; +use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; +use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; +use plonky2_field::extension::Extendable; +use plonky2_poseidon2::poseidon2_hash::poseidon2::Poseidon2; +use crate::{error::CircuitError, Result}; + +/// A circuit that verifies the aggregated public inputs from inner circuits. +/// +/// - `N`: Number of inner-proofs aggregated at the leaf level. +/// - `M`: Number of leaf proofs aggregated at the node level. +/// - `T`: Total Number of inner-proofs. +/// - `K`: Number of public input field elements per inner-proof (sampling proof). +pub struct PublicInputVerificationCircuit< + F: RichField + Extendable + Poseidon2, + const D: usize, + C: GenericConfig, + H: AlgebraicHasher, + const N: usize, + const M: usize, + const T: usize, + const K: usize, +> where + >::Hasher: AlgebraicHasher, +{ + pub node_common_data: CommonCircuitData, + phantom: PhantomData<(C, H)>, +} + +/// Holds the virtual targets for the circuit. +/// - `inner_proof`: the proof to be verified and contains the public input to be verified. +/// - `inner_pub_inputs`: A nested vector of targets with dimensions T×K. +/// - `node_verifier_data`: Verifier data for the node circuit. +/// - `leaf_verifier_data`: Verifier data for the leaf circuit. +/// - `inner_verifier_data`: Verifier data for the inner circuit. +pub struct PublicInputVerificationTargets { + pub inner_proof: ProofWithPublicInputsTarget, + pub node_verifier_data: VerifierCircuitTarget, + pub leaf_verifier_data: HashOutTarget, + pub inner_verifier_data: HashOutTarget, + pub inner_pub_inputs: Vec>, +} + +impl +PublicInputVerificationCircuit + where + F: RichField + Extendable + Poseidon2, + C: GenericConfig, + H: AlgebraicHasher, + >::Hasher: AlgebraicHasher, +{ + /// Create a new instance of the circuit. + pub fn new(node_common_data: CommonCircuitData) -> Self { + // we expect exactly 8 public inputs from the tree root proof + // 4 for the final aggregated public-input hash, 4 for the final aggregated verifier-data hash + assert_eq!(node_common_data.num_public_inputs, 8); + + Self { + node_common_data, + phantom: PhantomData, + } + } + + /// Builds the circuit by: + /// 1. Verifies a proof target with 8 public inputs (the final [pi_hash, vd_hash]). + /// 2. verifies correct tree hashing of all T×K targets to represent all inner public inputs. + /// 3. verifies correct tree hashing of node_verifier_date leaf_verifier_data and inner_verifier_data (each 4 field elements). + pub fn build(&self, builder: &mut CircuitBuilder) -> Result> { + // Add a virtual proof with 8 public inputs. This is the final root proof whose + // public inputs we want to check in-circuit. + let inner_proof = builder.add_virtual_proof_with_pis(&self.node_common_data); + + // Create a VerifierCircuitTarget for the node's verifier data (unhashed). + let node_verifier_data = builder.add_virtual_verifier_data( + self.node_common_data.config.fri_config.cap_height + ); + + // verify the proof + builder.verify_proof::(&inner_proof, &node_verifier_data, &self.node_common_data); + + // create T×K targets for all inner public inputs from the base level. + let mut inner_pub_inputs = Vec::with_capacity(T); + for _ in 0..T { + let mut row = Vec::with_capacity(K); + for _ in 0..K { + row.push(builder.add_virtual_public_input()); // public input + } + inner_pub_inputs.push(row); + } + + // ------------------------------------------------------------------ + // Summary of the logic: + // + // let final_pi = proof.public_inputs[0..4]; + // let final_vd = proof.public_inputs[4..8]; + // ... + // leaf-level pub inputs tree hashing: chunks of N -> hash -> combine with inner_verifier_data + // node-level pub inputs tree hashing: chunks of M -> hash -> combine with either leaf_hash (only level 0) or node_hash + // ... + // check final result matches final_pi, final_vd + // ------------------------------------------------------------------ + + // Extract the final 4 field elements for the public-input hash & next 4 for the verifier-data hash. + let final_pi_hash_t = &inner_proof.public_inputs[0..4]; + let final_vd_hash_t = &inner_proof.public_inputs[4..8]; + + // Compute node_hash in-circuit + let mut node_vd_input_t = Vec::new(); + node_vd_input_t.extend_from_slice(&node_verifier_data.circuit_digest.elements); + for cap_elem in node_verifier_data.constants_sigmas_cap.0.iter() { + node_vd_input_t.extend_from_slice(&cap_elem.elements); + } + let node_hash_t = builder.hash_n_to_hash_no_pad::(node_vd_input_t); + builder.register_public_inputs(&node_hash_t.elements); // public input + + + let mut pub_in_hashes_t = Vec::new(); + let mut vd_hashes_t = Vec::new(); + + // hash targets for the leaf and inner circuit's verifier data. + let leaf_hash_t = builder.add_virtual_hash_public_input(); // public input + let inner_hash_t = builder.add_virtual_hash_public_input(); // public input + + // Leaf level hashing: chunks of N + let base_chunks = T / N; // T is assumed to be multiple of N + for i in 0..base_chunks { + // flatten the inputs from i*N .. i*N + N + let mut chunk_targets = Vec::with_capacity(N * K); + for row_idx in (i * N)..(i * N + N) { + chunk_targets.extend_from_slice(&inner_pub_inputs[row_idx]); + } + // hash + let pi_hash_chunk = builder.hash_n_to_hash_no_pad::(chunk_targets); + + // track these in vectors + pub_in_hashes_t.push(pi_hash_chunk); + vd_hashes_t.push(inner_hash_t); + } + + // Now at the node level: + + let mut level = 0; + let mut current_len = base_chunks; + + while current_len > 1 { + + let next_len = (current_len + (M - 1)) / M; + + let mut next_pub_in_hashes_t = Vec::with_capacity(next_len); + let mut next_vd_hashes_t = Vec::with_capacity(next_len); + + for i in 0..next_len { + let start_idx = i * M; + let end_idx = (start_idx + M).min(current_len); + + // flatten all pub_in_hashes in [start_idx..end_idx] + let mut pi_flat = Vec::with_capacity((end_idx - start_idx) * 4); + for j in start_idx..end_idx { + pi_flat.extend_from_slice(&pub_in_hashes_t[j].elements); + } + let pi_hash = builder.hash_n_to_hash_no_pad::(pi_flat); + + // flatten all vd_hashes in [start_idx..end_idx] + let mut vd_flat = Vec::with_capacity((end_idx - start_idx) * 4); + for j in start_idx..end_idx { + vd_flat.extend_from_slice(&vd_hashes_t[j].elements); + } + // use leaf_hash if level == 0, else node_hash + let hash_n_t = if level == 0 { leaf_hash_t } else { node_hash_t }; + vd_flat.extend_from_slice(&hash_n_t.elements); + + let vd_hash = builder.hash_n_to_hash_no_pad::(vd_flat); + + next_pub_in_hashes_t.push(pi_hash); + next_vd_hashes_t.push(vd_hash); + } + + pub_in_hashes_t = next_pub_in_hashes_t; + vd_hashes_t = next_vd_hashes_t; + current_len = next_len; + level += 1; + } + + // now have exactly one pub_in_hash and one vd_hash + let final_computed_pi_t = &pub_in_hashes_t[0]; + let final_computed_vd_t = &vd_hashes_t[0]; + + // connect them to the final 8 public inputs of `inner_proof`. + for i in 0..4 { + builder.connect(final_pi_hash_t[i], final_computed_pi_t.elements[i]); + builder.connect(final_vd_hash_t[i], final_computed_vd_t.elements[i]); + } + + // return all the targets + Ok(PublicInputVerificationTargets { + inner_proof, + node_verifier_data, + leaf_verifier_data: leaf_hash_t, + inner_verifier_data: inner_hash_t, + inner_pub_inputs, + }) + } + + /// Assigns witness values to the targets. + /// - `inner_proof`: The tree root proof with 8 public inputs [pi_hash, vd_hash]. + /// - `inner_pub_inputs_vals`: T×K public input values from inner proofs. + /// - `node_verifier_data`: node verifier data + /// - `leaf_verifier_data`: leaf circuit’s verifier data. + /// - `inner_verifier_data`:inner-circuit’s verifier data. + pub fn assign_targets( + &self, + pw: &mut PartialWitness, + targets: &PublicInputVerificationTargets, + inner_proof: ProofWithPublicInputs, + inner_pub_inputs_vals: Vec>, + node_verifier_data: &VerifierCircuitData, + leaf_verifier_data: &VerifierCircuitData, + inner_verifier_data: &VerifierCircuitData, + ) -> Result<()> { + // Assign the final proof - it should have 8 public inputs + pw.set_proof_with_pis_target(&targets.inner_proof, &inner_proof) + .map_err(|e| { + CircuitError::ProofTargetAssignmentError("final-proof".to_string(), e.to_string()) + })?; + + // Assign T×K inner public inputs + if inner_pub_inputs_vals.len() != T { + return Err(CircuitError::InvalidArgument(format!( + "Expected T={} rows of inner_pub_inputs_vals, got {}", + T, + inner_pub_inputs_vals.len() + ))); + } + for (i, row_vals) in inner_pub_inputs_vals.into_iter().enumerate() { + if row_vals.len() != K { + return Err(CircuitError::InvalidArgument(format!( + "Expected K={} values in row {}, got {}", + K, + i, + row_vals.len() + ))); + } + for (j, val) in row_vals.into_iter().enumerate() { + pw.set_target(targets.inner_pub_inputs[i][j], val).map_err(|e| { + CircuitError::TargetAssignmentError(format!("inner public input index [{}][{}]", i,j), e.to_string()) + })?; + } + } + + // Assign the node verifier data + pw.set_verifier_data_target(&targets.node_verifier_data, &node_verifier_data.verifier_only) + .map_err(|e| { + CircuitError::VerifierDataTargetAssignmentError(e.to_string()) + })?; + + // Assign the leaf circuit’s verifier data + let leaf_hash = Self::get_hash_of_verifier_data(leaf_verifier_data); + pw.set_hash_target(targets.leaf_verifier_data, leaf_hash).map_err(|e| { + CircuitError::HashTargetAssignmentError("leaf verifier data hash".to_string(), e.to_string()) + })?; + + // Assign the inner circuit’s verifier data + let inner_hash = Self::get_hash_of_verifier_data(inner_verifier_data); + pw.set_hash_target(targets.inner_verifier_data, inner_hash).map_err(|e| { + CircuitError::HashTargetAssignmentError("inner verifier data hash".to_string(), e.to_string()) + })?; + + Ok(()) + } + + /// helper fn to generate hash of verifier data + fn get_hash_of_verifier_data(verifier_data: &VerifierCircuitData) -> HashOut{ + let mut vd = vec![]; + let digest: &HashOut = &verifier_data.verifier_only.circuit_digest; + let caps = &verifier_data.verifier_only.constants_sigmas_cap; + vd.extend_from_slice(&digest.elements); + for i in 0..verifier_data.common.config.fri_config.num_cap_elements() { + let cap_hash = caps.0[i] as HashOut; + vd.extend_from_slice(&cap_hash.elements); + } + + H::hash_no_pad(&vd) + } +} diff --git a/codex-plonky2-circuits/src/recursion/uniform/tree.rs b/codex-plonky2-circuits/src/recursion/uniform/tree.rs index f1bf545..f05576a 100644 --- a/codex-plonky2-circuits/src/recursion/uniform/tree.rs +++ b/codex-plonky2-circuits/src/recursion/uniform/tree.rs @@ -6,10 +6,10 @@ use plonky2::plonk::circuit_data::{CircuitConfig, CircuitData, CommonCircuitData use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; use plonky2::plonk::proof::ProofWithPublicInputs; use plonky2_poseidon2::poseidon2_hash::poseidon2::Poseidon2; -// use crate::recursion::circuits::inner_circuit::InnerCircuit; use plonky2_field::extension::Extendable; use crate::{error::CircuitError, Result}; use crate::recursion::uniform::{leaf::{LeafTargets,LeafCircuit},node::{NodeTargets,NodeCircuit}}; +use crate::recursion::uniform::compress::{CompressionCircuit, CompressionTargets}; /// tree recursion pub struct TreeRecursion< @@ -24,10 +24,13 @@ pub struct TreeRecursion< { leaf: LeafCircuit, node: NodeCircuit, + compression: CompressionCircuit, leaf_circ_data: CircuitData, node_circ_data: CircuitData, + compression_circ_data: CircuitData, leaf_targets: LeafTargets, node_targets: NodeTargets, + compression_targets: CompressionTargets, phantom_data: PhantomData<(H)> } @@ -63,13 +66,25 @@ impl< let node_circ_data = builder.build::(); // println!("node circuit size = {:?}", node_circ_data.common.degree_bits()); + // compression build + let config = CircuitConfig::standard_recursion_config(); + let mut builder = CircuitBuilder::::new(config); + let node_common = node_circ_data.common.clone(); + let compression_circ = CompressionCircuit::new(node_common); + let compression_targets = compression_circ.build(&mut builder)?; + let compression_circ_data = builder.build::(); + // println!("compress circuit size = {:?}", compression_circ_data.common.degree_bits()); + Ok(Self{ leaf, node, + compression: compression_circ, leaf_circ_data, node_circ_data, + compression_circ_data, leaf_targets, node_targets, + compression_targets, phantom_data: Default::default(), }) } @@ -78,10 +93,34 @@ impl< self.leaf_circ_data.verifier_data() } + pub fn get_node_common_data(&self) -> CommonCircuitData{ + self.node_circ_data.common.clone() + } + + pub fn get_leaf_common_data(&self) -> CommonCircuitData{ + self.leaf_circ_data.common.clone() + } + pub fn get_node_verifier_data(&self) -> VerifierCircuitData{ self.node_circ_data.verifier_data() } + pub fn prove_tree_and_compress( + &mut self, + proofs_with_pi: &[ProofWithPublicInputs], + inner_verifier_only_data: &VerifierOnlyCircuitData, + ) -> Result<(ProofWithPublicInputs)> + { + let proof = + self.prove_tree(proofs_with_pi, inner_verifier_only_data)?; + let mut pw = PartialWitness::::new(); + self.compression.assign_targets(&mut pw, &self.compression_targets, proof, &self.node_circ_data.verifier_only)?; + + self.compression_circ_data.prove(pw).map_err( + |e| CircuitError::InvalidProofError(e.to_string()) + ) + } + pub fn prove_tree ( &mut self, @@ -162,19 +201,46 @@ impl< self.prove(&new_proofs, &self.node_circ_data.verifier_only) } + pub fn verify_proof( + &self, + proof: ProofWithPublicInputs, + is_compressed: bool, + ) -> Result<()>{ + if is_compressed{ + self.compression_circ_data.verify(proof) + .map_err(|e| CircuitError::InvalidProofError(e.to_string())) + }else { + self.node_circ_data.verify(proof) + .map_err(|e| CircuitError::InvalidProofError(e.to_string())) + } + } + pub fn verify_proof_and_public_input( &self, proof: ProofWithPublicInputs, inner_public_input: Vec>, - inner_verifier_data: &VerifierCircuitData) -> Result<()> - { + inner_verifier_data: &VerifierCircuitData, + is_compressed: bool, + ) -> Result<()>{ let public_input = proof.public_inputs.clone(); - self.node_circ_data.verify(proof) - .map_err(|e| CircuitError::InvalidProofError(e.to_string()))?; - self.verify_public_input(public_input, inner_public_input, inner_verifier_data) + if is_compressed{ + self.compression_circ_data.verify(proof) + .map_err(|e| CircuitError::InvalidProofError(e.to_string()))?; + self.verify_public_input(public_input, inner_public_input, inner_verifier_data, is_compressed) + }else { + self.node_circ_data.verify(proof) + .map_err(|e| CircuitError::InvalidProofError(e.to_string()))?; + self.verify_public_input(public_input, inner_public_input, inner_verifier_data, is_compressed) + } } - pub fn verify_public_input(&self, public_input: Vec, inner_public_input: Vec>, inner_verifier_data: &VerifierCircuitData) -> Result<()>{ + pub fn verify_public_input( + &self, + public_input: Vec, + inner_public_input: Vec>, + inner_verifier_data: &VerifierCircuitData, + is_compressed: bool, + ) -> Result<()>{ assert_eq!(public_input.len(), 8); let given_input_hash = &public_input[0..4]; @@ -227,7 +293,14 @@ impl< //check expected hash let expected_pi_hash = pub_in_hashes[0]; - let expected_vd_hash = inner_vd_hashes[0]; + let mut expected_vd_hash = inner_vd_hashes[0]; + + if is_compressed { + let mut vd_to_hash = vec![]; + vd_to_hash.extend_from_slice(&expected_vd_hash.elements); + vd_to_hash.extend_from_slice(&node_hash.elements); + expected_vd_hash = H::hash_no_pad(&vd_to_hash); + } assert_eq!(given_input_hash, expected_pi_hash.elements); assert_eq!(given_vd_hash, expected_vd_hash.elements); diff --git a/proof-input/Cargo.toml b/proof-input/Cargo.toml index b480f82..2c57eb9 100644 --- a/proof-input/Cargo.toml +++ b/proof-input/Cargo.toml @@ -14,4 +14,8 @@ plonky2 = { workspace = true } plonky2_field = { workspace = true } # --- local --- plonky2_poseidon2 = { path = "../plonky2_poseidon2" } -codex-plonky2-circuits = { path = "../codex-plonky2-circuits" } \ No newline at end of file +codex-plonky2-circuits = { path = "../codex-plonky2-circuits" } + +[features] +default = [] +parallel = ["plonky2/parallel"] \ No newline at end of file diff --git a/proof-input/src/recursion/uniform.rs b/proof-input/src/recursion/uniform.rs index a845c60..63d8e13 100644 --- a/proof-input/src/recursion/uniform.rs +++ b/proof-input/src/recursion/uniform.rs @@ -1,8 +1,7 @@ -// some tests for approach 2 of the tree recursion +// some tests for the tree recursion #[cfg(test)] mod tests { - use std::fs; use plonky2::iop::witness::{PartialWitness}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::{CircuitConfig}; @@ -13,6 +12,7 @@ mod tests { use crate::gen_input::gen_testing_circuit_input; use crate::params::Params; use codex_plonky2_circuits::recursion::uniform::{tree::TreeRecursion}; + use codex_plonky2_circuits::recursion::uniform::pi_verifier::PublicInputVerificationCircuit; #[test] fn test_uniform_recursion() -> anyhow::Result<()> { @@ -35,7 +35,8 @@ mod tests { println!("sampling circuit degree bits = {:?}", inner_data.common.degree_bits()); let inner_proof = inner_data.prove(pw)?; - let proofs: Vec> = (0..4).map(|i| inner_proof.clone()).collect(); + let num_of_proofs = 4; + let proofs: Vec> = (0..num_of_proofs).map(|i| inner_proof.clone()).collect(); // ------------------- tree -------------------- const N: usize = 1; @@ -45,14 +46,106 @@ mod tests { let root = tree.prove_tree(&proofs, &inner_data.verifier_only)?; println!("pub input size = {}", root.public_inputs.len()); + println!("proof size = {:?} bytes", root.to_bytes().len()); + + let root_compressed = tree.prove_tree_and_compress(&proofs, &inner_data.verifier_only)?; + println!("pub input size (compressed) = {}", root_compressed.public_inputs.len()); + println!("proof size compressed = {:?} bytes", root_compressed.to_bytes().len()); let inner_pi: Vec> = proofs.iter().map(|p| p.public_inputs.clone()).collect(); assert!( - tree.verify_proof_and_public_input(root,inner_pi,&inner_data.verifier_data()).is_ok(), + tree.verify_proof_and_public_input(root,inner_pi.clone(),&inner_data.verifier_data(), false).is_ok(), "proof verification failed" ); + assert!( + tree.verify_proof_and_public_input(root_compressed,inner_pi,&inner_data.verifier_data(), true).is_ok(), + "compressed proof verification failed" + ); + + + Ok(()) + } + + #[test] + fn test_pi_verifier() -> anyhow::Result<()> { + + let config = CircuitConfig::standard_recursion_config(); + let mut sampling_builder = CircuitBuilder::::new(config); + + //------------ sampling inner circuit ---------------------- + // Circuit that does the sampling - 100 samples + let mut params = Params::default(); + params.input_params.n_samples = 100; + params.circuit_params.n_samples = 100; + let one_circ_input = gen_testing_circuit_input::(¶ms.input_params); + let samp_circ = SampleCircuit::::new(params.circuit_params); + let inner_tar = samp_circ.sample_slot_circuit_with_public_input(&mut sampling_builder)?; + // get generate a sampling proof + let mut pw = PartialWitness::::new(); + samp_circ.sample_slot_assign_witness(&mut pw,&inner_tar,&one_circ_input)?; + let inner_data = sampling_builder.build::(); + println!("sampling circuit degree bits = {:?}", inner_data.common.degree_bits()); + let inner_proof = inner_data.prove(pw)?; + + // 9 field elems as public inputs in the sampling circuit + const K:usize = 9; + // change the following as needed. + const T: usize = 4; + let proofs: Vec> = (0..T).map(|i| inner_proof.clone()).collect(); + + // ------------------- tree -------------------- + const N: usize = 1; + const M: usize = 2; + + let mut tree = TreeRecursion::::build(inner_data.common.clone())?; + + let root = tree.prove_tree(&proofs, &inner_data.verifier_only)?; + println!("pub input size = {}", root.public_inputs.len()); + println!("proof size = {:?} bytes", root.to_bytes().len()); + + let inner_pi: Vec> = proofs.iter().map(|p| p.public_inputs.clone()).collect(); + + assert!( + tree.verify_proof_and_public_input(root.clone(),inner_pi.clone(),&inner_data.verifier_data(), false).is_ok(), + "proof verification failed" + ); + + // ------------------- Public input verifier Circuit -------------------- + + let pi_verifier_circ = PublicInputVerificationCircuit::::new(tree.get_node_common_data()); + + let config = CircuitConfig::standard_recursion_config(); + let mut builder = CircuitBuilder::::new(config); + let pi_tarq = pi_verifier_circ.build(&mut builder)?; + + let pi_circ_data = builder.build::(); + println!("PI verifier circuit degree bits = {:?}", pi_circ_data.common.degree_bits()); + + let mut pw = PartialWitness::::new(); + + pi_verifier_circ.assign_targets(&mut pw, &pi_tarq, root, inner_pi.clone(), &tree.get_node_verifier_data(), &tree.get_leaf_verifier_data(), &inner_data.verifier_data())?; + + let proof = pi_circ_data.prove(pw)?; + println!("pub input size = {}", proof.public_inputs.len()); + println!("proof size = {:?} bytes", proof.to_bytes().len()); + + let pub_input_flat: Vec = inner_pi.iter().cloned().flatten().collect(); + let num_pi = proof.public_inputs.len(); + + // sanity check + for (i, e) in proof.public_inputs.iter().enumerate(){ + if i < pub_input_flat.len() { + assert_eq!(*e, pub_input_flat[i]) + } + } + + assert!( + pi_circ_data.verify(proof).is_ok(), + "pi-verifier proof verification failed" + ); + Ok(()) } } \ No newline at end of file diff --git a/workflow/benches/compression.rs b/workflow/benches/compression.rs new file mode 100644 index 0000000..965e04c --- /dev/null +++ b/workflow/benches/compression.rs @@ -0,0 +1,111 @@ +use anyhow::{anyhow, Result}; +use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; +use plonky2::gates::noop::NoopGate; +use plonky2::hash::hash_types::HashOut; +use plonky2::iop::witness::{PartialWitness, WitnessWrite}; +use plonky2::plonk::circuit_builder::CircuitBuilder; +use plonky2::plonk::circuit_data::CircuitConfig; +use plonky2::plonk::config::GenericConfig; + +use codex_plonky2_circuits::recursion::uniform::compress::CompressionCircuit; +use proof_input::params::{D, C, F, HF}; + +/// Benchmark for building, proving, and verifying the Plonky2 circuit. +fn bench_compression_runtime(c: &mut Criterion, circuit_size: usize) -> Result<()>{ + + #[cfg(feature = "parallel")] + println!("Parallel feature is ENABLED"); + + // Create the circuit configuration + let config = CircuitConfig::standard_recursion_config(); + let mut builder = CircuitBuilder::::new(config); + + let num_dummy_gates = match circuit_size { + 0 => return Err(anyhow!("size must be at least 1")), + 1 => 0, + 2 => 1, + n => (1 << (n - 1)) + 1, + }; + + for _ in 0..num_dummy_gates { + builder.add_gate(NoopGate, vec![]); + } + + // 2 virtual hashes (8 field elems) as public input - same as in the recursion tree + let mut pi = vec![]; + for i in 0..2{ + pi.push(builder.add_virtual_hash_public_input()); + } + + let inner_data = builder.build::(); + println!("inner circuit size = {:?}", inner_data.common.degree_bits()); + + // prove with dummy public input + let mut pw = PartialWitness::::new(); + pw.set_hash_target(pi[0], HashOut::::ZERO)?; + pw.set_hash_target(pi[1], HashOut::::ZERO)?; + let inner_proof = inner_data.prove(pw)?; + + // Compression circuit + let config = CircuitConfig::standard_recursion_config(); + let mut builder = CircuitBuilder::::new(config); + let compression_circ = CompressionCircuit::::new(inner_data.common.clone()); + let compression_targets = compression_circ.build(&mut builder)?; + + // Benchmark Group + let mut group = c.benchmark_group(format!("Compression Circuit Benchmark for inner-proof size = {}", circuit_size)); + + // Benchmark the Circuit Building Phase + group.bench_function("Build Circuit", |b| { + b.iter(|| { + let config = CircuitConfig::standard_recursion_config(); + let mut local_builder = CircuitBuilder::::new(config); + let _compression_targets = compression_circ.build(&mut local_builder); + let _data = local_builder.build::(); + }) + }); + + // Build the circuit once for proving and verifying benchmarks + let compression_circ_data = builder.build::(); + println!("compress circuit size = {:?}", compression_circ_data.common.degree_bits()); + + let mut pw = PartialWitness::::new(); + compression_circ.assign_targets(&mut pw, &compression_targets, inner_proof, &inner_data.verifier_only)?; + + group.bench_function("Prove Circuit", |b| { + b.iter_batched( + || pw.clone(), + |local_pw| compression_circ_data.prove(local_pw).expect("Failed to prove circuit"), + BatchSize::SmallInput, + ) + }); + + let proof = compression_circ_data.prove(pw)?; + println!("Proof size: {} bytes", proof.to_bytes().len()); + + let verifier_data = compression_circ_data.verifier_data(); + + // Benchmark the Verifying Phase + group.bench_function("Verify Proof", |b| { + b.iter(|| { + verifier_data.verify(proof.clone()).expect("Failed to verify proof"); + }) + }); + + group.finish(); + Ok(()) +} + +fn bench_compression(c: &mut Criterion) -> Result<()>{ + bench_compression_runtime(c, 13)?; + bench_compression_runtime(c, 14)?; + Ok(()) +} + +/// Criterion benchmark group +criterion_group!{ + name = benches; + config = Criterion::default().sample_size(10); + targets = bench_compression +} +criterion_main!(benches); diff --git a/workflow/input.json b/workflow/input.json deleted file mode 100644 index 982fc1b..0000000 --- a/workflow/input.json +++ /dev/null @@ -1,2081 +0,0 @@ -{ - "dataSetRoot": [ - "3896334872301643957", - "5437605165746282680", - "6957555185215355191", - "8741057093230336700" - ], - "entropy": [ - "1234567", - "0", - "0", - "0" - ], - "nCellsPerSlot": 512, - "nSlotsPerDataSet": 11, - "slotIndex": 3, - "slotRoot": [ - "2091274318560528263", - "15867507602281619836", - "4087329433835498368", - "854050144221681622" - ], - "slotProof": [ - "827439652992611846", - "16905769495525140780", - "16695068033037246276", - "17151630741232149889", - "3469569746364851618", - "18391056527690884511", - "8010039421125473150", - "3408023460182710126", - "12855129173382438132", - "10585118078362511618", - "18326498811560493459", - "4121357915895258498", - "15982493084566743355", - "14593007143866990693", - "14424160485348619", - "291881629905080749", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - "cellData": [ - [ - "18330358302717222964", - "6507716008418741318", - "2256185936184418259", - "2898088607685606295", - "1302915809230795973", - "5423554669334752774", - "2318485810914448292", - "8308751247627978409", - "1103547858908696215", - "13233094711216728766", - "12631661090253497388", - "2046427086594652633", - "12372958155033440526", - "4906110936661253305", - "12951448619650960630", - "15515691435552624787", - "8711898685487222626", - "1624759412220415555", - "12141590265745345815", - "12828239716182853447", - "6871869883274421664", - "4288372286635225182", - "7084370383737579849", - "9533524650293409334", - "2281442371050407492", - "15120282317371890996", - "4220647213202675636", - "9278581394831696946", - "10121906054396019771", - "2343399635414797907", - "102095381610988948", - "1668957779409538900", - "353181221613246114", - "9190279091863477556", - "15989576676802785255", - "9126051073676755676", - "10537383302293726888", - "6238730694132810570", - "7335683468273463516", - "18344519236602362946", - "7834529440241434567", - "1947882134481937929", - "2233454836383959363", - "17576771599874598793", - "2443675233164328989", - "15224644855304110551", - "4357885755474370578", - "6927749866954912813", - "7184681767738107936", - "17235069758634839571", - "879658911441157170", - "17767019191439130549", - "11632721901465657835", - "6352922484560567201", - "17249552273846114156", - "13797412685674866739", - "18104856234959648054", - "17179101883590930428", - "15708838740700020520", - "1440645445260792963", - "15648371865695967031", - "2480438736168893423", - "6296601090294756647", - "14516645316007286817", - "9713220960108441811", - "355115770314014612", - "9992324583142651721", - "4800518786438339256", - "10730244007275855610", - "16446215638663537131", - "391919445077999880", - "1591795078404059596", - "8234544813413728830", - "5687532553799599261", - "1223968843855782186", - "18187331106057408835", - "12692039220638239585", - "10371508840765049356", - "16408915085639966159", - "16788436719690779698", - "12517934006574458803", - "10378856360286225439", - "9212852833305663554", - "4030523167820779400", - "13728824594003237588", - "3592034120977442185", - "15053344871890549863", - "7756943018505899981", - "17673393676445655527", - "7765889117335449413", - "15889598986799734934", - "6346596138672077006", - "6812528080448215733", - "367806217451947896", - "6450715386068276285", - "5651552074456290133", - "2539992777876453903", - "4489011303612760695", - "17653241403847189201", - "82354677793627929", - "13247595858591716630", - "8412263732574982145", - "2762478568033603892", - "15429442983867112171", - "145336139449885223", - "17668263425851638619", - "16213095307575155594", - "13128910142479093723", - "15470554273684504769", - "6863839518005676192", - "2723231954453139571", - "13350398717654009020", - "5603565446072078703", - "5464383408143301502", - "4699226346785514616", - "16232301515228084734", - "6251554592891016296", - "4147397067184668363", - "5240822663879547891", - "2694649322312604804", - "14936866687569872883", - "2379909682772271483", - "9588413267009702046", - "1450847958732257828", - "8894751488374566347", - "2407515705810905982", - "17863636188403127064", - "14443065811232016534", - "6970186694121612428", - "14092106069643338742", - "18425471678226095456", - "1920790388562028317", - "6821325985404373456", - "11598376700102362980", - "1477293024549865313", - "14819077286740650838", - "17806968660875972405", - "5182033852134799639", - "5840064194315030017", - "2483157692556050764", - "10240024354560610797", - "16842181429344362943", - "2428440900469415112", - "14575480586694971838", - "12686414028447657477", - "11142257784015821825", - "610647302795506780", - "8007876532856369192", - "3549412812296813076", - "10909546860080127459", - "8633860027041277263", - "9287408931850356823", - "11267096463614036790", - "2082239752149251674", - "14469722807120983974", - "2815518808749884870", - "17335121274955139523", - "11539365205204827848", - "506757789496250553", - "12768017655522980108", - "14897169434572145582", - "13334117134964353338", - "408705049898630467", - "13384617482335244483", - "6066782261680500838", - "1909741990609436211", - "8150731797145908150", - "5032876940337690827", - "1833677732927550399", - "17870632304987530770", - "1043111022966168609", - "11924947150445263933", - "387799164925368024", - "7100687119152685534", - "2877065480252564073", - "15181904882125092224", - "4560957099909586965", - "13410948375347159401", - "10691785821671872419", - "9091430661152546090", - "808457983279473454", - "1237378245891311191", - "11567989689105450500", - "3271241596664485145", - "16308039407781227672", - "6002377584118476479", - "14241291652116477240", - "7477529203592851507", - "10777948244090073209", - "18014613904538144971", - "8148244950622234855", - "7962477891321942845", - "13775495009330769671", - "13766193932849175327", - "12181553543544297317", - "8022777856899397429", - "2726675390993032032", - "2928415607420199223", - "6520727440352391933", - "12424361960302419525", - "16630906264864011823", - "12017316750121834154", - "2705444273257815318", - "7707408066550180185", - "5337012174917624813", - "9518602700463645551", - "6436042144705386441", - "584709617383512147", - "12391699084800145702", - "16341810740105891227", - "3965914340383450576", - "10072353390216556216", - "17515562330802299581", - "11142517074309082862", - "15082789040488182887", - "6141300519797304983", - "17451169609761832117", - "10038325410238910601", - "10589539259001144479", - "12308550557184319477", - "4431314911487966273", - "250487909807963228", - "9635425354084757161", - "16492585041203267048", - "1492383999021801989", - "17781407035731441296", - "5281295682253802348", - "16938222757098535735", - "4387064153683067536", - "4773050523112384889", - "16417057159660156716", - "8879568805177491789", - "10121840300045205832", - "8198428980331139832", - "17162464339379107451", - "14532367286382504718", - "3191570956242495304", - "17925127694666021891", - "4735365465022202816", - "14953971934195286620", - "5543044529839679375", - "5300349928749640799", - "6814534542614527821", - "15847519850064005990", - "8382700467151183461", - "11491238721753988325", - "17722085984997448829", - "13501164404405464545", - "8212447339106702018", - "15558051562821776001", - "16115509935983828775", - "16168064376253988524", - "14707093160538871715", - "12474895037183109928", - "6348088841578626445", - "15579121596648041958", - "17520509120817341181", - "14684549538787446669", - "622701494186892056", - "15134107781207897057", - "3675327913785542103", - "17848942807626472725", - "6756193774633032973", - "6166089527522988133", - "4486663761775452283", - "5573586060477108336", - "1886466867719042014", - "11935108797612960773", - "11243046145260072415", - "3372124182990205817", - "8404868355263887004", - "4259067870247838263" - ], - [ - "2554248953359389240", - "11961182032432955174", - "4743762984056564843", - "18157637666358338256", - "8951567553442772490", - "15141703014374341269", - "869898787902432284", - "8629210681427351152", - "11553972393271938276", - "8244762424194569619", - "14233069285793611008", - "17430807520062510062", - "12929304632141557434", - "17231804441135598149", - "1555840316306463553", - "6622947404949430589", - "10637129968144401939", - "8198876010929994402", - "7384410486347087294", - "10685016080901246026", - "5864233071686451640", - "5138844121465062645", - "17429460807710892826", - "6916520714514362567", - "6914925272423812449", - "13697102926884594561", - "8004650612993829403", - "8796236366390955808", - "17632709876924755900", - "3211627029909015413", - "14465020985905337519", - "4797820017860027574", - "5674598005795604909", - "136582789728376187", - "1254619357915313006", - "6765206005479439182", - "4452312147468070223", - "13926752097109816412", - "11362931187937116888", - "3961203844713330319", - "13554338997389464219", - "13935046550859911180", - "6898839646722319157", - "17813302789245981620", - "4208821964133381116", - "5889810336990051249", - "8429103352544893516", - "1963463753916703524", - "2121648492580956931", - "625703753399704903", - "8618898879504943415", - "6528130179852904688", - "8913075836225154289", - "11234459604032249828", - "5014016457558681981", - "10154910548866752999", - "12365269295565704867", - "11750775782456349793", - "7348822133789419003", - "6056194343563316804", - "10145034646363459170", - "7699127262969908232", - "16692085631977682823", - "13661665674264824001", - "4196249974906996807", - "13160331428166950261", - "1445885387070821339", - "77984788142825621", - "5889270200456711391", - "17546151015750866117", - "5844794468080238880", - "11785671145574573559", - "3583732087649537364", - "15835416970211588306", - "16348586721697469603", - "15640647972173886493", - "16135392702253472431", - "7685275846269390330", - "13915168006467240730", - "13046296819125885141", - "8553453163737497787", - "1878100716751805550", - "11752933696938492629", - "11780221055292423627", - "17913289632275653812", - "2261337199795074181", - "3627935726133135101", - "2977026936791369917", - "5635561679525790508", - "8359595760372978385", - "7835390044225174124", - "8193577836670081541", - "17760978676678350871", - "3575628458687168192", - "10373879232454117564", - "2510151138656924320", - "16323126968439258015", - "11662881868712630401", - "8749863063901864077", - "9883880507365911047", - "12568870023388072358", - "7433413673476409449", - "4262850434501394911", - "2479131069458054424", - "5781019441297266602", - "12003100795125103165", - "9354505070505954289", - "10383989385697620874", - "6217624880006091657", - "3739142856133165223", - "10525562991872671354", - "10114417835424477925", - "10005696544048570846", - "5979713885512847950", - "860876340720416195", - "6747484017607648316", - "9958760772029389127", - "14037719010649387006", - "11712726513650464707", - "1279848787760337499", - "7740902769658340320", - "16896216433684349673", - "7404855294456284327", - "6774440204124647336", - "2921228496551122198", - "2724501771692992251", - "10737799061806798617", - "1421529002998871158", - "3502413798331672251", - "15823339384447155121", - "1493485810185488854", - "18012388953541737563", - "3147356147448742246", - "4009211403032006602", - "17141132557997898725", - "9650695587973561873", - "14172350142195776534", - "2458212666017715329", - "959482990160337677", - "12443123566173925689", - "8593556962485601113", - "4820015600082830499", - "13588139157368647343", - "13002775883489700548", - "15928260911730342471", - "3856618943467689087", - "1804285428066858081", - "10903877070076536920", - "5143029497717548920", - "5867442711505477890", - "5743117204772268504", - "1533409640713165918", - "7947302118844013789", - "10328430552089665321", - "17904940076524079608", - "5504372455555879729", - "16241006548882475484", - "14400066599214435000", - "16314233938768001700", - "17598801578107716240", - "1982847591828730641", - "3549362229193406603", - "8953570772099984893", - "10822245473317661058", - "12437096339921022904", - "12344495870128704097", - "4907112044407200015", - "17473580954791455086", - "10206508785729541147", - "15028108523194120629", - "2711000216200794859", - "12977707890475069452", - "4942227539028492685", - "3403183560191540029", - "2094235444511867041", - "6019199475540767802", - "1683950267859679524", - "3936604393560933434", - "2284272313041977589", - "3684578989904504355", - "1697630692196918416", - "17957759796202595169", - "16556989328478467724", - "8108835067133033396", - "1540617429245072708", - "11405669301927516202", - "11162475705735376111", - "14260476227634304842", - "8481389746377445148", - "12971590006873046141", - "15742395766224456628", - "7698771093121379779", - "5796001893386684347", - "1968569347244874664", - "8219535667057606931", - "374283386955216025", - "13778761973134192834", - "5818334872458576735", - "10874331673969900334", - "17091594370460250044", - "3836415427718117704", - "11014630561035939244", - "14853076798337624274", - "3438600385392696323", - "13220274019494948186", - "9098022470375622094", - "14894939140546870199", - "16728051593019229453", - "15896342158778902232", - "2899373746121977018", - "175865786748147125", - "14894992809586206054", - "15633851264791277100", - "1060501470920334300", - "12012330940424173598", - "17949620037546180633", - "341179442352493245", - "7580892620341288990", - "4505804241173227849", - "3492553580924154648", - "1336352480409127149", - "10158856905877363931", - "13398494624226901102", - "8987870095845331242", - "12671081251769856781", - "11518808443149401408", - "5687783740071271821", - "16859870053305236514", - "3076336710390917748", - "11251232899084313791", - "6600335049234661834", - "10475290620370664775", - "13591889836272898906", - "13000704554474335053", - "6080483580429140264", - "2213313257417592927", - "2298063125663364305", - "13256730481199118518", - "48507904343606769", - "1778950548776184314", - "2247280870411114548", - "18158880993908821138", - "8889762178076496169", - "17779899034509958284", - "7564854511188583147", - "11745001222261965445", - "5064873064889604827", - "4130854436855559487", - "10405290921584765705", - "5185318186038269767", - "9706511559242648544", - "17894364128360417438", - "5633099074394082957", - "12010224754418144953", - "715268077181160626", - "8453978350231595273", - "12345956233132578356", - "4099904579089633615", - "7504839058787265666", - "14694904543552031612", - "9233629494219073964", - "17029358076104081980", - "17725217208692662042", - "10971159566132203021", - "17698169057024335242", - "18223848010073217552", - "17802201476064457629", - "6224414886466851425", - "17749515847239620683", - "8400116497939496624", - "6133882611670092350", - "254988821262229361" - ], - [ - "4697170051990383089", - "15705943222273278726", - "10031110245349788886", - "1054098934552380418", - "695893462903469813", - "5972845621142893923", - "18287855622049345743", - "7994073607551221737", - "18408120472735710694", - "18171740712485021590", - "10073223420333010328", - "10498494360481890263", - "15442447167528786584", - "12074310881255975194", - "10799967761950659647", - "9477899770492672372", - "6404598103262754545", - "11032471082111744005", - "5087315545265827079", - "3666418415830628197", - "1960623310471778297", - "14455795903234389170", - "15774673009015852726", - "17312332308837705342", - "5118388051633021778", - "8983738229451626643", - "12022524187608293595", - "10860048566788365822", - "6941073485149659190", - "9075121413629222033", - "15109653886470150505", - "6445237282950802592", - "14926547804653375571", - "3266142460157722778", - "3881061153114267242", - "3648566981902264081", - "352423591704558276", - "5125425048752242714", - "2271345168873240225", - "16803476412001202053", - "11158777746085144876", - "14079163039305211687", - "15723687066143318136", - "1317853383369806465", - "469665977396541927", - "681394695539440245", - "5601031186875894767", - "14239713170688082535", - "197243869740613027", - "16400197918041934519", - "13489758172518261097", - "16841797961852871947", - "6462360274286668959", - "14217871325921841400", - "4243417926501367017", - "14798617822916648240", - "7399784075750328072", - "14206632346149140418", - "11993478439253053121", - "2152739439111503211", - "12124072048638567506", - "17717842258426267771", - "13378330398932439819", - "3368764126519548335", - "8459432294829151241", - "5270516860071547972", - "18176654784940724914", - "2335800346866253579", - "6796528347513398527", - "6946405672626937202", - "6786929669956623907", - "4447727096203816363", - "3296372231736850621", - "10213433993889811454", - "15644155910942272018", - "11880304161426381865", - "5673600384469434067", - "16274556737819420435", - "16149892563537035091", - "10749810927377197426", - "17243421432400270469", - "9391928327693934350", - "14270156639174437474", - "5958030162649282220", - "1826058943276424207", - "13533486235175407342", - "546776410215035276", - "15038391164692805522", - "7170870584295016311", - "2817554477973425190", - "9297618907380447415", - "14433136339464858989", - "8378934323829639751", - "2074695116243478785", - "8151911239139994781", - "2723306407790614847", - "2952771319949873464", - "10303895396520205278", - "9010924196578662536", - "3948666267053032665", - "6349106285231719134", - "9008883124951001293", - "3692521131574098010", - "14808708120866627953", - "12013583019771582545", - "17011456583930964620", - "17674649294781657696", - "12294586986449231239", - "381313865740335794", - "5226735447763685797", - "7102966238059789622", - "13452379912368072262", - "18227584039659961171", - "7431127969001026589", - "16732581151685921228", - "11978657963632860190", - "12082348805718061401", - "3621170792006608590", - "9904636576855375644", - "7498249006986879551", - "15300756575097930446", - "16603381566810367173", - "9625776925390345398", - "12587464813711148564", - "13844902622840412829", - "561333174638500266", - "9962974480595421306", - "2735125561273100435", - "14517170162751579339", - "12469599950490746357", - "14293005501579141432", - "830755266693615087", - "16708487741519252694", - "7396159034429408847", - "17128588011027783850", - "3273219290402717619", - "5209883051411155399", - "13118801438516155411", - "7912515957914540214", - "12974494691818164185", - "3934310433330095525", - "3085219572333338857", - "13313509400214391405", - "17611451645629597577", - "15324549213772209853", - "13504896927825921955", - "7193175408954480947", - "4551190610688377402", - "4514279077112514043", - "17093085817379059839", - "6167818373803559267", - "15490984992120770353", - "16927970216322221190", - "7856077947540961030", - "4766378688203452498", - "10834303926424929367", - "13740002598336008813", - "13007879310939622770", - "8724372160262103455", - "11909421732537824220", - "16686267692464995305", - "6791877790720558331", - "11809279838416552857", - "10792622723204117268", - "6569019711117275504", - "11445984314688026784", - "1904427165777674698", - "829159069332738923", - "14160920643593121817", - "4414682846911225088", - "13106132322250851044", - "9417259416343839564", - "5115806273537458235", - "12431195520180507066", - "8454510396057208812", - "12991780197332825651", - "14238502287088430382", - "11310385335909876747", - "10608485521255924439", - "5430032070512795765", - "4601028979178784296", - "16833993550246449259", - "4513672048491773715", - "5126281239816404810", - "15142362263531347784", - "10526734022989703341", - "9583377126857776068", - "6835928321080966777", - "9770536959398089508", - "4069097212149071088", - "8996146472781084290", - "3076713620438508694", - "7292305773642209311", - "4187637175571623544", - "13232073679101916682", - "1795983352972370573", - "7540869770238757814", - "15344977036174546799", - "13055103604220626840", - "3609137395630412230", - "15199240348404297073", - "763375532024166407", - "5860485752906327301", - "6899020298477872362", - "17339236002905349730", - "10981694698015851001", - "9427806881875460266", - "5691245907415698933", - "12472645809129307718", - "11628951914156387026", - "1730631858594918766", - "16334698725329052323", - "8443845786816378906", - "14757321192106069192", - "1241230068921480615", - "16151273846282392832", - "12661843977524200596", - "7081707993037416853", - "15776136987626362001", - "2042795771657142859", - "16224936410866631466", - "7763344779053650600", - "4998815549996740648", - "1887650545293309244", - "14704502101644149212", - "9955144556310537079", - "2982835077106153550", - "6518943519189324449", - "10298931494632375521", - "4219026845831505853", - "14925803924551970077", - "7045072633154846080", - "2467904064963600026", - "14332476869272911177", - "10240474222644919975", - "2709720907550230627", - "10315555072982540554", - "8844933974729850474", - "4807562079006938418", - "4012129376674586941", - "9996629705496302584", - "214702606212963561", - "15231966413657345547", - "10803395171780196802", - "16487871640380392801", - "5377647638725794738", - "11576143069139026755", - "1333511262428987944", - "2376680689542705852", - "7600166371306374019", - "10248707961604325274", - "715230938949629559", - "18366067747728860495", - "8483339946821715859", - "17747562928366546193", - "2327269746890689450", - "8067942924188899273", - "5408766916822069865", - "3665413494960970591", - "4507294233543415945", - "7392773350251395709", - "2492788844396202559", - "15833071453168952636", - "10496698098221480260", - "415454662860965261", - "18423936935277932492", - "1794462365289722294", - "1831212518401371509", - "4177424401948879960", - "12385346903516442204", - "18036432146855669993", - "15017326031664985520" - ], - [ - "968986837111167621", - "11023202023552528937", - "7109319375469548030", - "10231687589402140079", - "2247885776474650982", - "4524883914934930581", - "8702947782308537532", - "8003692047015773028", - "7015627677575030623", - "16790820249532623689", - "17403110762247548640", - "5695041612699681760", - "6795449704131678445", - "16779210483217092034", - "9383697691005078955", - "8066999772086003644", - "3252503929134582681", - "14861099317773408350", - "15052228921891357028", - "15910868676375773667", - "15710553468963508212", - "18367623746392894440", - "18063934428382321636", - "9247713793457727100", - "1137039407533771580", - "12216719318691656983", - "3839954905613630094", - "9037739054070100125", - "17357512543627992440", - "14195989939269234930", - "8447989907909682828", - "9222500622793232630", - "3431170445900162313", - "5136335651507348259", - "180876284592966660", - "3407323929292072419", - "17705905586038356590", - "16229857619328438006", - "13498136627989658964", - "1183914418426549025", - "13356039365931498843", - "12974651311268938856", - "8310161842037084193", - "17554770325805343225", - "4534514115822916773", - "547400538625376975", - "8557364048296472541", - "5492253517139676339", - "8412185741358413230", - "12336360356004338118", - "8557015846799918434", - "18231692912557974336", - "6102950715770956311", - "17845822213986397155", - "17470304140277589123", - "3898314124176525545", - "3936986604559966454", - "5173170507692127532", - "12717464869607222453", - "15934177828502443776", - "6230734386058191602", - "4849192139892913587", - "257365502333883028", - "17973890203019361363", - "7912727503510533475", - "1593417619236956341", - "422155712594489392", - "3964870407856035299", - "858631127469988904", - "2399898440342532439", - "5229377141814523368", - "12296766709774515982", - "16784538897826719206", - "5032311776465683395", - "934222303527785322", - "3839163725125422118", - "2692452251347538857", - "9469481509454200432", - "15951107345866523369", - "6983047114569280829", - "2248814498079683789", - "15507625847245042681", - "8763046323329537379", - "13137568216849854554", - "14389010267370866305", - "2845893048319250434", - "4227540222827982298", - "15672702581967458593", - "13617854497495277235", - "16798012121971055172", - "12690546337524331266", - "1101308298645047231", - "17973204414856407408", - "5195078151876630940", - "1157329759282625236", - "11592489809327331742", - "15542548319761325808", - "7691153831272226865", - "6522830237810821191", - "16334410646790223317", - "3594903407451800113", - "9091670910663667905", - "11195144982270177906", - "17840768832008475702", - "10950958872420205437", - "2069187534788259258", - "9592275726792938024", - "4290063192457146293", - "1755608274351152316", - "8777594422001252653", - "15096176139812698768", - "8455648224829772301", - "8610476183017801708", - "15186122367760452984", - "5167331611624825297", - "3144039624510251468", - "18335398753585836575", - "15111475499499522137", - "4167483615335676887", - "8082087687834868614", - "16379054402782854290", - "5938561557201962596", - "9463046084310591064", - "653347360053190943", - "2369372701097738665", - "8980274968427085392", - "13608539089682265509", - "7413174775504834163", - "9851691726969828643", - "13649129025442455930", - "13789403824292483965", - "2574065327110397543", - "7479701780325982613", - "7481397727409372289", - "5467563678831499249", - "6054999606614753835", - "6357079093013460220", - "4856570583948319742", - "17353625252712728632", - "10551716188576421133", - "18201634272293064212", - "10416450395985696774", - "5050795782086316929", - "16507875791588617571", - "10616947474030235745", - "10177958076160820141", - "15238954676145325483", - "14687417431264404715", - "15517276030345913652", - "1215831430632476521", - "4764243801051359965", - "14056702103089330934", - "2937547246384108009", - "18366978634910566633", - "1178639339175017753", - "950181426245030529", - "8237277353760826518", - "4265148637576282095", - "17692707419746573544", - "17306486337182703004", - "3225551917721183698", - "726000162977808203", - "16403535508002977140", - "387212275904345341", - "9095401159125154682", - "7540327992420383789", - "7936370159163452109", - "1103494665889835036", - "11320511122255284226", - "3705776053123311806", - "17505944557224505886", - "12447839616358240829", - "17858011360148818658", - "13174248358461966532", - "11466508955335460709", - "7492692318614249545", - "8028218088307906304", - "6437104859351944800", - "15188358660547410505", - "4600222128368733771", - "16587684535007765655", - "6944793298633689025", - "1640226373363733922", - "14817292651848508122", - "17589788922924831510", - "5395908649960021606", - "2953474638019020902", - "641388158971591525", - "15621002156886148404", - "17877035283595538812", - "1427847944984939420", - "16317500779531144289", - "1143586953805876813", - "3003515787502075734", - "4951391686697004670", - "5775599057055990017", - "592038181477359217", - "17960086352794653853", - "11744284503595973483", - "4042597307587797676", - "15876940598946751610", - "9817564269805008720", - "11299394058967632147", - "12480964870647655829", - "16314760994728990896", - "11573392707935712776", - "8948492923212775997", - "4302885500990663310", - "9046378018020784480", - "7590189130456528904", - "14601101803519893488", - "6561996158954563807", - "13766244947533886505", - "17456620615089106406", - "7592951759001920541", - "17166738101635629271", - "5296568726825292034", - "6511072221889411996", - "10641114003940037277", - "15398754778040061058", - "16445804519657228698", - "8506197066511155059", - "11444774570766447780", - "4705356783331895920", - "13082386206153370910", - "15381971591527141923", - "3740968490787492430", - "3245544745861235367", - "3624436585736425944", - "8467643600942823682", - "7580108172001774215", - "6713277347848596854", - "4252654502632875623", - "13595956713892753946", - "10514084847895051634", - "11097577105450808414", - "16157055788045953263", - "3290150736806592098", - "3383836618682456709", - "14659937755551390418", - "15940169041119206388", - "15344962117143328059", - "5294033025881482353", - "8225216434257086816", - "16340559935892558317", - "17537484456244849191", - "16521497440699775351", - "1430855957293224342", - "3823672510270163922", - "4086011640481127626", - "4523872574095536634", - "10094078200427995780", - "5387405208360770253", - "2142718292057063042", - "11994701164549095979", - "2950196675800861497", - "11720230196027494061", - "2450134288195631221", - "7033019614294730228", - "14303772139697258549", - "9038488246228705056", - "2835040654062824330", - "17822791801029497568", - "14877292311436656019", - "14327994879516646583", - "17869020005153208352", - "7756558168498156914", - "1806031063610104982", - "4663609648634798568", - "6082487753074736427", - "11175242967066652998", - "8670852380387185520" - ], - [ - "4587094892466826831", - "15029979853100887834", - "11154955150286534954", - "5362649725248853456", - "8492568456830493712", - "5565549050909176445", - "7570901852898932675", - "10892255810321546367", - "11288643084137973466", - "10860571888612174605", - "2985898893312072241", - "1469558012543155107", - "1996693041428274320", - "16439899778208414133", - "12628734151133078836", - "13435710815475424131", - "16057006491015385797", - "7075213629638981658", - "1874889368453504427", - "13870249564686806586", - "2633805298302133929", - "14435594186036877692", - "11972258494098795354", - "3959419201417766729", - "10128392220200140619", - "5059435223210406876", - "12522777511062090651", - "14471948305379496349", - "13946234476082372410", - "14256634447710024659", - "1672003885580659782", - "8448018855708115892", - "17579860589093080517", - "2846020754645619341", - "13641843732487655842", - "9998092043296946875", - "3912032571162943317", - "6789588062619519098", - "10174533586367441195", - "16695758505590415351", - "5098326712208714820", - "10520885367598219780", - "13507306444068280004", - "15191983147149306127", - "16179508743502802505", - "3467893878282034026", - "11500222600814800665", - "5100154980514712908", - "12226100912915433898", - "5286759329100507362", - "5322867237571666297", - "16289035286238744840", - "4117587611101109721", - "18420914943026856829", - "16508677350806130884", - "14565564288853006712", - "17492195767386217680", - "16069131499471877192", - "5844159125000764659", - "6436857504899054330", - "18130770744054728362", - "3301540484932207801", - "5801765179727715417", - "12848550937229613602", - "9105042600963370929", - "3258467487050982097", - "7055862774579784310", - "14825889250886023550", - "999676687351290176", - "11822463803577304488", - "8128811624784855774", - "1315548132444113628", - "13231847019907074431", - "13720212041916516562", - "8231994545091462239", - "12565117921930292358", - "11365094455238104564", - "18362193233165992105", - "17044501042204526958", - "2070419570184842787", - "551895847450489837", - "5441894112204158961", - "12223629924376922389", - "1867016583849489969", - "16022267346622700042", - "5334000678890344511", - "6830137385919963005", - "2354736263260929252", - "14771745329549488344", - "17739924719083830993", - "4237268085129185129", - "17905372912859186862", - "15066207504830111413", - "9983558675861165593", - "720597608474644573", - "7506813448887934254", - "16703111293970202462", - "2754342023553094838", - "10867827534989538248", - "3563196437408729957", - "17442436540763807684", - "3843274540197123015", - "7334599442322533487", - "14991648973737962076", - "6845266898259082935", - "1982363083743530455", - "8170231412638697258", - "4365837520112416948", - "6935233863230985650", - "7506738158670122513", - "14767078992645075499", - "4106855800197125728", - "11685476046647623589", - "4184343020665924972", - "6053486288982930808", - "11010025945177388085", - "17829905999264221597", - "3149855251542418074", - "3986270969422184727", - "16541252862193221180", - "16328210833877535003", - "155022352147522494", - "12404023829528238726", - "14956138720989510730", - "1117931073451868206", - "262195456996901954", - "2319074502751614143", - "9090409342572504199", - "14836503461935300165", - "11009551306985729139", - "3625313080964677755", - "8110219284975469675", - "10430442776443625599", - "11949089559010101857", - "17637380992460518882", - "5270150588008865345", - "11970872125776796554", - "8356573751472717423", - "2141582442876540123", - "487540130433288896", - "13862114713665106336", - "5213780791121734677", - "11209826978047710697", - "14894436403126436269", - "13017913202632420032", - "2649391013881151137", - "9075689816784751831", - "5207915296879284140", - "3020809662222266337", - "4236505893144565543", - "9807318246518333898", - "11786033481073799942", - "8467428442020791871", - "10486718233035454569", - "2853946848858774802", - "12803334786002283066", - "12024390624701235090", - "17813311568599353756", - "11201847172629959128", - "7172580325338283795", - "10643596124749337067", - "8786436647703540815", - "5355346580973283766", - "15377431810766932569", - "13200016012825911743", - "1954126459932666423", - "9189314740833225596", - "8506089338040015218", - "14264387309159223115", - "3247118872562616100", - "4341024482559372083", - "9457574502742811826", - "2867757071028349868", - "16756783891677907294", - "15881169477280169987", - "18099037419070438749", - "16898438818115245277", - "4790172270488272447", - "5255007743183813819", - "10772945990205343325", - "15085844660316353370", - "6480438745780531665", - "2795888213205419658", - "7477388231016304903", - "16777657366538286992", - "7844274468623743924", - "9814259068670884913", - "9489489129193012576", - "12068026417778649178", - "9318953823621360640", - "18134332246586831821", - "5302415519312907484", - "11086990450000891892", - "5076533947222740009", - "933865678306635661", - "10115316042305478944", - "8855227319884894697", - "6773762051718060133", - "5948794930712262630", - "455205180519202534", - "5863529265995694729", - "1481304300092236156", - "18304006372824921565", - "18201925513750843388", - "387243585873061103", - "17149370309127289452", - "16139865751275650940", - "6104623721718490927", - "5043780958928006072", - "5380085759886604462", - "15638838984242784731", - "6884827393328098972", - "3419059888567653333", - "12652677278448174876", - "4876465800924618786", - "5265505025933900366", - "1161362844515871643", - "4951132027873166915", - "13847625412259316330", - "15409127284480840470", - "11425333191765528809", - "9875271043036495054", - "5333227347154160893", - "17389767807788205076", - "9867387306656588598", - "635942662587690458", - "8194481697823122037", - "2099686295855038944", - "13943069067907935162", - "3754394752956086513", - "8874677886728014592", - "2040231909538278233", - "3802862328435024936", - "5006774219387746528", - "10108293716516048072", - "18080955287391508031", - "18006513547127627015", - "1048898107561309066", - "7480503792132294444", - "12778828126886716133", - "7420714006231663213", - "17031037480492755852", - "15679422581894254598", - "15144285291844899212", - "153263463212350798", - "8969657985142217240", - "2024945117756993593", - "1545656951472461395", - "1576525070311866488", - "3857219898784710001", - "11105920922520688881", - "10316675717551937111", - "13861641931031388297", - "12303763916499446312", - "1436278804032525568", - "13313580655178138523", - "4694957155039284864", - "4024062290182962504", - "3912126277295482284", - "14285085561308879778", - "11454735080472441481", - "7292550743529262844", - "10735050192239483245", - "2642690520318234664", - "11401131739206420197", - "12437440219903132832", - "505244767510712858", - "18058402071146526353", - "9756406927545704767", - "3730400697788070398", - "10725274323667200205", - "6653877115849325151" - ] - ], - "merklePaths": [ - [ - "7599041403246563815", - "8329168937849394285", - "4440075771863988501", - "6969724823296119926", - "4885721547974190668", - "3331928415941087294", - "17324266136095310160", - "14996332736412099843", - "16989304880669127152", - "16625852016893663020", - "12339724448155475223", - "16971968596848917924", - "3452745143094693481", - "14677663824423209891", - "14554743566815646426", - "2971510552634068499", - "13124129550327796101", - "2520668631491002195", - "16100926211027719028", - "4676602281594707272", - "2304623030054787303", - "7664049036283862282", - "12283890199958271965", - "3442896561308166682", - "17095813506692999390", - "6656171086867016100", - "4605741466238057522", - "11120937475547947287", - "240406562034990975", - "115063727324617014", - "16547472758218979561", - "10989978370470299915", - "1409286658812794462", - "6061726686687360814", - "6649989053254953485", - "3724889144416980978", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - [ - "13016203662242306738", - "10331334847513960722", - "1647704192777853197", - "736175322221880290", - "17961248099532886995", - "2768252392929806490", - "7478206415755178198", - "3415087068952691000", - "6702254901922703136", - "17439272039763539925", - "11055244367761229750", - "15332796701275548335", - "8951575437641215241", - "18423783467452999537", - "12767088227271876498", - "13924305877620006398", - "11033808444833257342", - "5337069970891062472", - "3440755475411994140", - "9200127230416817717", - "6154356769184844780", - "4079160409632499268", - "13944827686130687101", - "6220940754588292450", - "2052021701077723166", - "5102472990362041929", - "10847985044035674867", - "10587474866563727711", - "2816725934989959809", - "11963841763895151011", - "8061480405142838822", - "4101076623974360581", - "2590545951636037830", - "5705136620222431867", - "44887296942569969", - "1962469851411691965", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - [ - "11910048993107143922", - "1937739428751898044", - "6972159660763598713", - "1227916687428857615", - "5764457921114130264", - "8755176881926314259", - "9405815383120438481", - "14296175010606967814", - "3563802703894037102", - "17162608180273041644", - "15008634238844292013", - "15402549497522682629", - "1160108171861101699", - "8474764821058822609", - "17284224608107426765", - "7757472337314149961", - "11750975923374246242", - "11816470063992374578", - "12704637828421677494", - "10342207856812524757", - "4197413461037071213", - "4971629113135792208", - "13364931768774627780", - "9508952045454174966", - "15440500095942942205", - "18030057197476641433", - "2658218245716388564", - "13650298488077331031", - "2816725934989959809", - "11963841763895151011", - "8061480405142838822", - "4101076623974360581", - "2590545951636037830", - "5705136620222431867", - "44887296942569969", - "1962469851411691965", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - [ - "3020460826145300028", - "3820152465827797072", - "8348151100730936247", - "17918391567891843229", - "18194692508038912001", - "17371196392137203108", - "3028518356247880080", - "3591011215258502558", - "17197757509462828053", - "16264613284014900765", - "7572322155302972870", - "3488021971286880851", - "10030047026231864928", - "15058983506976286823", - "14268328150156546270", - "5837928485703634755", - "17913067617133360722", - "5953131161443084220", - "17329021589346504731", - "7657664206029749599", - "1684237723268025232", - "8584052081357535902", - "9717434319844006825", - "6593754821269522301", - "17004130080421410449", - "2255364198865448916", - "13577067913052357786", - "14177101141450953033", - "8770204964736616394", - "18260001390710965620", - "12907786710587678037", - "14481856084590206301", - "2590545951636037830", - "5705136620222431867", - "44887296942569969", - "1962469851411691965", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ], - [ - "4817169651029766362", - "13240857514883298700", - "18004138849936275241", - "17125557668458424176", - "4105217842596232447", - "10300511964166464514", - "10975683521240653973", - "671767041885394385", - "10039633629209588685", - "14855886440903160182", - "16539247555217470059", - "14486071409018450136", - "2136445670271190526", - "7944505621958896340", - "1212695963127581794", - "8303189456743405363", - "16481332309972602310", - "7582779040501390905", - "13920883052466697429", - "12698328245585817234", - "3396829268539458856", - "18310694356184208909", - "3774535376283555816", - "4998666315084366672", - "17095813506692999390", - "6656171086867016100", - "4605741466238057522", - "11120937475547947287", - "240406562034990975", - "115063727324617014", - "16547472758218979561", - "10989978370470299915", - "1409286658812794462", - "6061726686687360814", - "6649989053254953485", - "3724889144416980978", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0" - ] - ] -} \ No newline at end of file