From eb5357a69a93b90e79a75666bf61472ab2e1f625 Mon Sep 17 00:00:00 2001 From: Mikhail Volkhov Date: Tue, 24 Sep 2024 12:39:22 +0100 Subject: [PATCH] Write serialization regression tests for poly-commitment and parts of kimchi --- kimchi/src/bench.rs | 3 +- kimchi/src/proof.rs | 12 +- kimchi/src/prover.rs | 11 +- kimchi/src/tests/and.rs | 336 +++++++++++++++++++++ kimchi/src/tests/framework.rs | 66 +++- kimchi/src/tests/range_check.rs | 11 +- kimchi/src/tests/serde.rs | 11 +- poly-commitment/src/evaluation_proof.rs | 2 +- poly-commitment/src/tests/commitment.rs | 32 +- poly-commitment/src/tests/mod.rs | 1 + poly-commitment/src/tests/serialization.rs | 160 ++++++++++ utils/Cargo.toml | 9 +- utils/src/serialization.rs | 165 ++++++++-- 13 files changed, 756 insertions(+), 63 deletions(-) create mode 100644 poly-commitment/src/tests/serialization.rs diff --git a/kimchi/src/bench.rs b/kimchi/src/bench.rs index ccf4808c84..8f1139ab65 100644 --- a/kimchi/src/bench.rs +++ b/kimchi/src/bench.rs @@ -85,11 +85,12 @@ impl BenchmarkCtx { // add the proof to the batch ( - ProverProof::create::( + ProverProof::create::( &self.group_map, witness, &[], &self.index, + &mut rand::rngs::OsRng, ) .unwrap(), public_input, diff --git a/kimchi/src/proof.rs b/kimchi/src/proof.rs index 75468abe8c..5492fef1f5 100644 --- a/kimchi/src/proof.rs +++ b/kimchi/src/proof.rs @@ -18,7 +18,7 @@ use std::array; //~ spec:startcode /// Evaluations of a polynomial at 2 points #[serde_as] -#[derive(Copy, Clone, Serialize, Deserialize, Default, Debug)] +#[derive(Copy, Clone, Serialize, Deserialize, Default, Debug, PartialEq)] #[cfg_attr( feature = "ocaml_types", derive(ocaml::IntoValue, ocaml::FromValue, ocaml_gen::Struct) @@ -41,7 +41,7 @@ pub struct PointEvaluations { /// - **Chunked evaluations** `Field` is instantiated with vectors with a length that equals the length of the chunk /// - **Non chunked evaluations** `Field` is instantiated with a field, so they are single-sized#[serde_as] #[serde_as] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct ProofEvaluations { /// public input polynomials pub public: Option, @@ -106,7 +106,7 @@ pub struct ProofEvaluations { /// Commitments linked to the lookup feature #[serde_as] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")] pub struct LookupCommitments { /// Commitments to the sorted lookup table polynomial (may have chunks) @@ -119,7 +119,7 @@ pub struct LookupCommitments { /// All the commitments that the prover creates as part of the proof. #[serde_as] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")] pub struct ProverCommitments { /// The commitments to the witness (execution trace) @@ -134,7 +134,7 @@ pub struct ProverCommitments { /// The proof that the prover creates from a [ProverIndex](super::prover_index::ProverIndex) and a `witness`. #[serde_as] -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")] pub struct ProverProof { /// All the polynomial commitments required in the proof @@ -160,7 +160,7 @@ pub struct ProverProof { /// A struct to store the challenges inside a `ProverProof` #[serde_as] -#[derive(Debug, Clone, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] #[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")] pub struct RecursionChallenge where diff --git a/kimchi/src/prover.rs b/kimchi/src/prover.rs index 7ac12871a3..14e043be07 100644 --- a/kimchi/src/prover.rs +++ b/kimchi/src/prover.rs @@ -48,6 +48,7 @@ use poly_commitment::{ evaluation_proof::DensePolynomialOrEvaluations, OpenProof, SRS as _, }; +use rand_core::{CryptoRng, RngCore}; use rayon::prelude::*; use std::{array, collections::HashMap}; @@ -133,22 +134,25 @@ where pub fn create< EFqSponge: Clone + FqSponge, EFrSponge: FrSponge, + RNG: RngCore + CryptoRng, >( groupmap: &G::Map, witness: [Vec; COLUMNS], runtime_tables: &[RuntimeTable], index: &ProverIndex, + rng: &mut RNG, ) -> Result where VerifierIndex: Clone, { - Self::create_recursive::( + Self::create_recursive::( groupmap, witness, runtime_tables, index, Vec::new(), None, + rng, ) } @@ -164,6 +168,7 @@ where pub fn create_recursive< EFqSponge: Clone + FqSponge, EFrSponge: FrSponge, + RNG: RngCore + CryptoRng, >( group_map: &G::Map, mut witness: [Vec; COLUMNS], @@ -171,6 +176,7 @@ where index: &ProverIndex, prev_challenges: Vec>, blinders: Option<[Option>; COLUMNS]>, + rng: &mut RNG, ) -> Result where VerifierIndex: Clone, @@ -186,9 +192,6 @@ where d1_size / index.max_poly_size }; - // TODO: rng should be passed as arg - let rng = &mut rand::rngs::OsRng; - // Verify the circuit satisfiability by the computed witness (baring plookup constraints) // Catch mistakes before proof generation. if cfg!(debug_assertions) && !index.cs.disable_gates_checks { diff --git a/kimchi/src/tests/and.rs b/kimchi/src/tests/and.rs index 1b76f43c2c..00d4467d00 100644 --- a/kimchi/src/tests/and.rs +++ b/kimchi/src/tests/and.rs @@ -143,6 +143,36 @@ where .unwrap(); } +/// Generic test for checking serialization & regression of AND circuit. +fn prove_and_check_serialization_regression( + bytes: usize, + buf_expected: Vec, +) where + G::BaseField: PrimeField, + EFqSponge: Clone + FqSponge, + EFrSponge: FrSponge, +{ + let rng = &mut StdRng::from_seed(RNG_SEED); + + // Create + let mut gates = vec![]; + let _next_row = CircuitGate::::extend_and(&mut gates, bytes); + + // Create inputs + let input1 = rng.gen(None, Some(bytes * 8)); + let input2 = rng.gen(None, Some(bytes * 8)); + + // Create witness + let witness = and::create_and_witness(input1, input2, bytes); + + TestFramework::::default() + .gates(gates) + .witness(witness) + .setup() + .prove_and_check_serialization_regression::(buf_expected, rng) + .unwrap(); +} + #[test] // End-to-end test fn test_prove_and_verify() { @@ -328,3 +358,309 @@ fn test_bad_and() { )) ); } + +#[test] +fn test_serialization_regression() { + // Generated with commit 1494cf973d40fb276465929eb7db1952c5de7bdc + let buf_expected = vec![ + 149, 148, 159, 145, 145, 196, 33, 36, 165, 245, 213, 186, 207, 201, 96, 141, 145, 71, 154, + 187, 239, 170, 150, 114, 105, 170, 226, 168, 160, 25, 82, 94, 241, 119, 173, 45, 239, 224, + 30, 128, 145, 145, 196, 33, 27, 54, 218, 52, 109, 125, 14, 178, 84, 87, 98, 184, 89, 113, + 138, 8, 94, 134, 192, 240, 129, 61, 17, 148, 198, 215, 182, 192, 69, 98, 63, 46, 128, 145, + 145, 196, 33, 53, 195, 34, 72, 152, 165, 75, 4, 119, 74, 67, 191, 242, 68, 37, 64, 127, + 211, 16, 77, 22, 193, 31, 218, 173, 149, 98, 177, 53, 26, 47, 5, 128, 145, 145, 196, 33, + 179, 96, 55, 27, 255, 197, 234, 235, 20, 99, 92, 7, 151, 70, 127, 33, 8, 175, 33, 73, 194, + 149, 52, 140, 160, 193, 249, 221, 251, 9, 207, 4, 0, 145, 145, 196, 33, 221, 218, 156, 17, + 6, 250, 210, 122, 201, 45, 241, 155, 89, 175, 217, 126, 142, 99, 216, 14, 77, 134, 151, + 110, 226, 74, 198, 115, 67, 143, 235, 50, 0, 145, 145, 196, 33, 191, 185, 3, 102, 157, 183, + 106, 253, 137, 81, 222, 197, 150, 153, 51, 247, 190, 234, 84, 59, 82, 178, 23, 69, 229, + 164, 180, 212, 104, 120, 104, 63, 128, 145, 145, 196, 33, 187, 239, 165, 36, 6, 11, 220, + 181, 49, 78, 7, 76, 75, 7, 99, 255, 142, 195, 221, 152, 65, 7, 167, 192, 39, 155, 194, 11, + 146, 71, 147, 13, 128, 145, 145, 196, 33, 216, 210, 29, 61, 63, 106, 247, 206, 197, 66, 31, + 66, 126, 44, 34, 58, 230, 12, 202, 248, 42, 175, 28, 66, 166, 188, 249, 92, 199, 72, 141, + 42, 0, 145, 145, 196, 33, 97, 179, 85, 45, 61, 162, 43, 109, 27, 112, 131, 204, 183, 110, + 138, 192, 26, 79, 53, 210, 200, 228, 5, 221, 134, 153, 30, 162, 129, 62, 43, 48, 0, 145, + 145, 196, 33, 18, 169, 75, 241, 81, 127, 153, 194, 40, 22, 114, 150, 86, 125, 175, 81, 151, + 113, 87, 60, 170, 10, 204, 133, 194, 244, 65, 18, 14, 75, 219, 21, 128, 145, 145, 196, 33, + 9, 51, 243, 183, 164, 35, 134, 182, 198, 115, 70, 208, 54, 95, 30, 123, 43, 234, 247, 200, + 138, 51, 151, 93, 80, 141, 11, 173, 6, 98, 148, 5, 0, 145, 145, 196, 33, 37, 66, 190, 145, + 21, 175, 28, 70, 11, 113, 206, 20, 129, 188, 111, 139, 224, 89, 215, 5, 203, 78, 241, 228, + 51, 3, 243, 168, 122, 215, 236, 34, 0, 145, 145, 196, 33, 152, 87, 187, 243, 94, 49, 180, + 30, 159, 54, 114, 173, 172, 10, 234, 166, 144, 21, 183, 5, 2, 224, 94, 150, 113, 167, 164, + 236, 91, 81, 115, 57, 0, 145, 145, 196, 33, 151, 175, 254, 34, 234, 12, 31, 180, 135, 112, + 139, 138, 184, 234, 162, 109, 63, 7, 253, 230, 186, 3, 63, 248, 64, 61, 54, 233, 236, 173, + 221, 12, 128, 145, 145, 196, 33, 247, 26, 39, 62, 128, 234, 191, 91, 195, 174, 219, 67, + 146, 102, 247, 157, 243, 211, 13, 38, 210, 175, 130, 166, 186, 13, 170, 33, 148, 147, 43, + 18, 128, 145, 145, 196, 33, 12, 255, 46, 115, 136, 68, 54, 56, 122, 180, 137, 92, 245, 18, + 201, 98, 206, 6, 121, 76, 164, 19, 132, 37, 186, 85, 20, 89, 106, 225, 253, 30, 128, 145, + 151, 196, 33, 55, 94, 56, 215, 185, 205, 93, 188, 86, 77, 52, 1, 31, 168, 232, 104, 244, + 79, 106, 57, 121, 209, 63, 74, 184, 119, 173, 235, 186, 154, 13, 10, 0, 196, 33, 245, 193, + 217, 36, 95, 189, 143, 215, 76, 233, 34, 248, 30, 34, 45, 41, 208, 101, 250, 85, 240, 151, + 205, 229, 195, 33, 218, 201, 5, 221, 248, 50, 0, 196, 33, 241, 18, 105, 236, 134, 232, 56, + 131, 161, 185, 216, 118, 155, 92, 181, 134, 204, 153, 170, 9, 81, 105, 145, 195, 95, 230, + 44, 124, 168, 141, 65, 12, 128, 196, 33, 131, 3, 72, 84, 233, 111, 193, 151, 113, 61, 232, + 220, 188, 31, 198, 186, 155, 141, 203, 252, 107, 46, 8, 215, 136, 15, 16, 98, 63, 46, 208, + 36, 128, 196, 33, 20, 122, 241, 183, 36, 169, 55, 92, 142, 196, 113, 118, 14, 48, 155, 25, + 214, 59, 68, 41, 2, 229, 82, 140, 94, 207, 106, 7, 33, 225, 21, 45, 128, 196, 33, 253, 59, + 240, 215, 91, 219, 180, 177, 54, 179, 229, 138, 252, 189, 136, 112, 138, 181, 230, 155, + 114, 11, 92, 244, 164, 202, 133, 66, 225, 108, 124, 21, 128, 196, 33, 10, 2, 2, 88, 246, + 207, 17, 158, 39, 228, 153, 4, 54, 41, 25, 195, 101, 83, 1, 151, 172, 61, 162, 203, 3, 216, + 239, 140, 208, 167, 117, 30, 128, 147, 149, 145, 145, 196, 33, 168, 20, 0, 160, 190, 182, + 71, 220, 31, 185, 150, 70, 29, 86, 10, 187, 56, 88, 112, 10, 173, 72, 132, 234, 249, 40, + 65, 168, 178, 217, 178, 10, 0, 145, 145, 196, 33, 125, 1, 225, 118, 245, 42, 119, 14, 112, + 28, 173, 45, 226, 47, 202, 47, 128, 139, 126, 117, 75, 226, 200, 6, 223, 103, 43, 32, 169, + 215, 232, 39, 128, 145, 145, 196, 33, 190, 108, 171, 208, 51, 18, 137, 67, 14, 145, 210, + 67, 59, 245, 95, 168, 107, 44, 232, 32, 55, 99, 199, 189, 79, 139, 72, 221, 147, 240, 206, + 58, 128, 145, 145, 196, 33, 25, 5, 39, 73, 139, 181, 227, 102, 210, 144, 18, 148, 55, 247, + 135, 114, 109, 20, 23, 1, 132, 68, 122, 9, 18, 165, 173, 91, 166, 120, 231, 1, 0, 145, 145, + 196, 33, 227, 157, 66, 26, 83, 194, 100, 178, 85, 122, 6, 156, 33, 54, 51, 94, 110, 28, + 251, 86, 25, 23, 154, 120, 182, 208, 228, 246, 68, 117, 236, 14, 128, 145, 145, 196, 33, + 243, 151, 191, 177, 116, 24, 152, 176, 112, 7, 6, 9, 1, 84, 149, 151, 3, 202, 122, 119, 48, + 240, 186, 59, 162, 57, 55, 188, 171, 75, 97, 1, 128, 192, 149, 220, 0, 16, 146, 196, 33, + 224, 152, 195, 71, 46, 249, 164, 109, 115, 126, 223, 209, 35, 33, 201, 228, 17, 79, 245, + 207, 238, 3, 133, 82, 139, 241, 209, 179, 74, 250, 252, 32, 0, 196, 33, 36, 48, 163, 190, + 148, 134, 115, 172, 128, 67, 162, 36, 176, 96, 119, 56, 45, 11, 11, 91, 15, 235, 164, 77, + 231, 118, 27, 201, 253, 210, 218, 29, 0, 146, 196, 33, 92, 40, 50, 24, 164, 89, 253, 180, + 19, 181, 207, 221, 6, 53, 35, 192, 211, 153, 164, 93, 72, 51, 115, 42, 68, 155, 0, 39, 120, + 110, 63, 24, 128, 196, 33, 212, 106, 62, 139, 172, 167, 41, 28, 3, 54, 177, 153, 133, 166, + 213, 45, 23, 5, 151, 208, 107, 78, 191, 245, 174, 178, 173, 103, 73, 167, 12, 46, 0, 146, + 196, 33, 99, 37, 180, 55, 215, 170, 173, 254, 209, 118, 71, 198, 174, 54, 140, 87, 208, 2, + 137, 195, 55, 66, 49, 72, 30, 105, 97, 76, 64, 30, 149, 46, 0, 196, 33, 187, 83, 231, 253, + 36, 164, 169, 56, 40, 74, 39, 164, 143, 156, 38, 5, 238, 233, 224, 254, 42, 26, 223, 180, + 4, 138, 114, 189, 24, 8, 147, 3, 128, 146, 196, 33, 214, 248, 85, 127, 130, 217, 152, 60, + 34, 62, 21, 60, 62, 114, 245, 208, 27, 204, 164, 167, 67, 200, 20, 161, 124, 236, 18, 16, + 58, 24, 143, 5, 0, 196, 33, 178, 185, 115, 105, 66, 21, 51, 170, 224, 36, 187, 81, 32, 86, + 77, 61, 205, 8, 243, 153, 91, 189, 6, 79, 1, 255, 102, 45, 198, 226, 134, 29, 0, 146, 196, + 33, 107, 157, 62, 160, 168, 130, 81, 105, 68, 177, 134, 222, 48, 53, 246, 197, 9, 144, 76, + 113, 99, 153, 56, 108, 60, 63, 202, 62, 251, 241, 83, 47, 0, 196, 33, 154, 225, 166, 53, + 169, 246, 162, 212, 120, 159, 221, 5, 145, 20, 168, 83, 7, 131, 241, 68, 80, 4, 19, 190, + 36, 67, 93, 55, 74, 135, 158, 49, 128, 146, 196, 33, 126, 91, 134, 159, 147, 229, 22, 241, + 214, 58, 134, 178, 225, 137, 147, 224, 139, 152, 240, 98, 3, 103, 69, 208, 94, 31, 52, 88, + 77, 7, 149, 55, 0, 196, 33, 111, 187, 150, 224, 164, 94, 91, 94, 24, 202, 106, 203, 137, + 141, 151, 6, 251, 43, 195, 85, 170, 98, 83, 183, 39, 251, 66, 207, 118, 87, 218, 21, 128, + 146, 196, 33, 37, 23, 28, 167, 53, 39, 201, 88, 54, 123, 42, 144, 72, 17, 8, 229, 138, 237, + 253, 43, 221, 28, 197, 115, 150, 145, 144, 58, 167, 123, 85, 20, 0, 196, 33, 162, 65, 229, + 69, 125, 63, 218, 120, 69, 74, 145, 144, 28, 209, 73, 125, 214, 32, 48, 115, 100, 98, 89, + 56, 59, 64, 207, 239, 52, 79, 183, 32, 0, 146, 196, 33, 165, 136, 235, 209, 28, 15, 225, + 127, 10, 78, 198, 46, 77, 17, 93, 190, 249, 146, 240, 142, 49, 147, 182, 141, 94, 201, 39, + 39, 197, 56, 103, 37, 0, 196, 33, 53, 169, 79, 96, 3, 82, 127, 139, 179, 252, 93, 45, 15, + 117, 103, 196, 244, 243, 89, 253, 41, 198, 2, 82, 210, 182, 157, 116, 222, 84, 172, 16, + 128, 146, 196, 33, 36, 192, 51, 27, 179, 112, 132, 42, 59, 121, 161, 93, 252, 82, 255, 43, + 211, 79, 85, 151, 225, 25, 255, 178, 177, 218, 253, 197, 243, 141, 141, 50, 128, 196, 33, + 211, 167, 99, 187, 185, 244, 188, 10, 106, 243, 113, 70, 66, 48, 139, 91, 15, 159, 194, + 150, 106, 71, 234, 145, 27, 119, 91, 169, 152, 124, 112, 42, 128, 146, 196, 33, 242, 14, + 18, 63, 196, 174, 160, 13, 192, 41, 244, 65, 23, 20, 135, 35, 192, 247, 96, 153, 8, 86, + 237, 240, 98, 169, 39, 22, 200, 40, 171, 41, 128, 196, 33, 137, 188, 107, 112, 249, 34, 76, + 217, 123, 80, 47, 202, 39, 217, 76, 73, 143, 116, 151, 46, 210, 170, 148, 133, 139, 231, + 56, 88, 91, 104, 135, 23, 128, 146, 196, 33, 187, 61, 193, 95, 158, 113, 196, 75, 246, 144, + 130, 208, 202, 202, 185, 12, 162, 149, 126, 21, 136, 249, 90, 101, 32, 243, 65, 201, 140, + 81, 16, 51, 128, 196, 33, 131, 220, 72, 14, 247, 232, 15, 241, 134, 1, 177, 185, 226, 26, + 143, 118, 88, 122, 195, 154, 38, 156, 15, 250, 180, 150, 1, 47, 176, 196, 202, 45, 0, 146, + 196, 33, 215, 114, 86, 8, 229, 151, 5, 113, 216, 114, 191, 149, 163, 255, 32, 184, 75, 171, + 226, 211, 246, 74, 54, 18, 236, 184, 100, 140, 178, 249, 83, 46, 128, 196, 33, 245, 191, + 158, 90, 205, 254, 30, 146, 42, 3, 167, 142, 115, 41, 239, 46, 156, 149, 169, 121, 248, 14, + 71, 140, 97, 32, 145, 68, 180, 68, 204, 37, 0, 146, 196, 33, 147, 105, 251, 87, 253, 146, + 116, 248, 107, 153, 82, 215, 236, 239, 11, 196, 58, 142, 195, 4, 60, 237, 189, 157, 3, 74, + 248, 63, 238, 31, 225, 41, 128, 196, 33, 139, 107, 58, 13, 150, 85, 187, 56, 216, 205, 75, + 167, 37, 217, 240, 105, 39, 240, 183, 78, 214, 109, 34, 133, 238, 62, 242, 89, 14, 194, + 101, 18, 0, 146, 196, 33, 160, 23, 108, 181, 158, 24, 85, 125, 72, 212, 229, 26, 50, 29, + 240, 127, 217, 212, 230, 198, 150, 116, 82, 43, 244, 102, 164, 175, 101, 138, 142, 29, 0, + 196, 33, 178, 71, 208, 9, 220, 149, 29, 205, 181, 117, 220, 15, 193, 88, 91, 114, 250, 143, + 48, 249, 162, 130, 191, 230, 149, 141, 42, 3, 172, 154, 183, 54, 0, 146, 196, 33, 151, 182, + 7, 47, 223, 166, 49, 130, 21, 243, 46, 156, 173, 85, 0, 68, 110, 158, 227, 153, 79, 113, + 158, 141, 247, 161, 171, 191, 134, 45, 81, 18, 128, 196, 33, 133, 184, 83, 248, 93, 85, 79, + 35, 22, 37, 198, 171, 243, 89, 171, 7, 239, 46, 149, 50, 151, 105, 235, 209, 104, 105, 126, + 80, 21, 106, 150, 5, 0, 146, 196, 33, 68, 143, 196, 245, 28, 73, 139, 12, 104, 140, 2, 163, + 192, 10, 98, 43, 214, 110, 72, 32, 216, 10, 244, 127, 62, 45, 225, 17, 175, 30, 70, 13, + 128, 196, 33, 177, 251, 45, 232, 65, 90, 253, 118, 45, 116, 191, 148, 2, 30, 250, 200, 87, + 24, 96, 215, 88, 26, 154, 193, 82, 18, 233, 80, 144, 20, 193, 37, 0, 196, 33, 122, 51, 12, + 144, 237, 57, 249, 223, 167, 247, 122, 63, 196, 164, 70, 165, 34, 31, 73, 81, 43, 254, 132, + 210, 38, 164, 134, 11, 224, 53, 89, 50, 128, 196, 32, 50, 229, 204, 135, 86, 209, 98, 48, + 87, 228, 85, 123, 223, 213, 78, 110, 205, 35, 65, 70, 2, 186, 52, 224, 148, 243, 97, 231, + 69, 153, 179, 60, 196, 32, 16, 161, 242, 238, 35, 203, 56, 64, 61, 45, 232, 213, 84, 21, + 145, 154, 49, 208, 179, 147, 158, 146, 215, 167, 246, 159, 4, 87, 76, 120, 170, 23, 196, + 33, 121, 227, 28, 56, 43, 207, 127, 209, 138, 117, 222, 133, 254, 3, 66, 85, 176, 179, 37, + 35, 200, 152, 199, 33, 246, 130, 159, 192, 144, 157, 184, 6, 128, 220, 0, 26, 146, 145, + 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, 146, 145, 196, 32, 24, 85, 231, 154, 170, 14, 90, 95, + 93, 63, 221, 62, 107, 160, 197, 69, 151, 52, 206, 31, 8, 63, 43, 180, 68, 224, 140, 87, + 189, 144, 195, 10, 145, 196, 32, 77, 214, 22, 209, 247, 242, 145, 83, 107, 245, 102, 128, + 153, 160, 115, 11, 121, 130, 64, 147, 233, 237, 66, 88, 248, 252, 240, 173, 213, 83, 241, + 35, 146, 145, 196, 32, 38, 83, 172, 209, 53, 215, 0, 163, 135, 173, 92, 72, 178, 11, 133, + 234, 125, 2, 164, 126, 192, 157, 155, 245, 127, 224, 223, 33, 100, 121, 46, 43, 145, 196, + 32, 140, 196, 243, 73, 215, 215, 254, 160, 25, 13, 225, 53, 162, 34, 36, 179, 0, 184, 76, + 197, 147, 29, 162, 134, 124, 164, 237, 117, 254, 240, 69, 45, 146, 145, 196, 32, 40, 62, + 22, 41, 200, 92, 217, 69, 42, 160, 64, 42, 33, 89, 250, 41, 246, 129, 39, 31, 111, 232, + 147, 58, 141, 15, 131, 202, 89, 23, 42, 8, 145, 196, 32, 213, 135, 162, 72, 105, 121, 88, + 175, 245, 115, 103, 51, 125, 181, 186, 198, 87, 225, 212, 155, 12, 244, 154, 78, 233, 146, + 156, 77, 138, 246, 149, 4, 146, 145, 196, 32, 10, 31, 99, 24, 35, 195, 229, 59, 38, 196, + 68, 26, 17, 111, 189, 142, 255, 98, 22, 61, 121, 127, 86, 202, 125, 191, 163, 54, 63, 120, + 222, 34, 145, 196, 32, 210, 43, 230, 154, 52, 80, 89, 31, 36, 132, 97, 199, 24, 99, 129, + 90, 39, 253, 243, 39, 24, 222, 1, 55, 21, 77, 65, 120, 104, 239, 39, 38, 146, 145, 196, 32, + 238, 154, 202, 147, 123, 17, 242, 231, 108, 68, 180, 211, 138, 183, 62, 241, 19, 111, 169, + 149, 85, 78, 235, 76, 146, 182, 182, 5, 40, 66, 45, 33, 145, 196, 32, 141, 124, 9, 194, 99, + 121, 36, 91, 25, 24, 124, 23, 85, 40, 195, 231, 112, 169, 213, 117, 196, 59, 235, 180, 226, + 134, 8, 139, 146, 235, 8, 57, 146, 145, 196, 32, 25, 222, 218, 15, 134, 8, 98, 49, 203, + 167, 49, 169, 224, 47, 17, 173, 14, 31, 146, 141, 214, 91, 10, 119, 252, 114, 202, 49, 230, + 125, 205, 15, 145, 196, 32, 124, 145, 151, 135, 28, 252, 158, 182, 224, 212, 25, 154, 141, + 231, 125, 204, 127, 62, 105, 117, 128, 187, 56, 155, 203, 183, 119, 228, 90, 238, 54, 15, + 146, 145, 196, 32, 243, 13, 116, 154, 248, 70, 156, 72, 159, 33, 156, 214, 56, 162, 200, + 123, 252, 101, 137, 183, 176, 54, 209, 72, 56, 142, 74, 76, 112, 185, 245, 39, 145, 196, + 32, 9, 203, 220, 141, 49, 87, 70, 233, 132, 185, 84, 105, 77, 12, 73, 210, 173, 26, 25, 20, + 143, 124, 64, 106, 130, 88, 218, 237, 53, 88, 234, 32, 146, 145, 196, 32, 225, 48, 139, + 230, 239, 149, 131, 150, 17, 194, 205, 147, 190, 213, 33, 59, 127, 36, 176, 53, 99, 28, + 241, 157, 144, 243, 235, 69, 173, 215, 109, 62, 145, 196, 32, 111, 51, 228, 140, 34, 174, + 116, 217, 156, 10, 21, 148, 250, 138, 84, 35, 63, 11, 66, 151, 172, 16, 211, 180, 220, 44, + 35, 32, 124, 103, 16, 9, 146, 145, 196, 32, 195, 182, 4, 60, 3, 121, 71, 159, 218, 57, 142, + 143, 199, 1, 124, 71, 43, 250, 181, 191, 57, 237, 152, 236, 28, 89, 78, 201, 85, 188, 49, + 24, 145, 196, 32, 61, 27, 101, 214, 107, 28, 239, 241, 138, 253, 86, 44, 119, 194, 242, + 155, 234, 15, 223, 166, 163, 229, 49, 139, 250, 124, 211, 252, 56, 176, 7, 43, 146, 145, + 196, 32, 201, 54, 50, 22, 150, 177, 4, 80, 207, 229, 244, 2, 19, 181, 30, 83, 13, 135, 180, + 75, 202, 201, 101, 255, 121, 165, 176, 215, 185, 75, 187, 28, 145, 196, 32, 213, 225, 10, + 164, 230, 246, 22, 90, 160, 105, 87, 85, 5, 84, 219, 251, 230, 84, 201, 50, 200, 118, 81, + 80, 110, 93, 243, 68, 11, 109, 30, 13, 146, 145, 196, 32, 212, 219, 255, 196, 132, 203, + 252, 39, 94, 47, 32, 4, 242, 194, 76, 155, 15, 173, 231, 234, 157, 249, 154, 118, 55, 110, + 55, 200, 73, 96, 104, 35, 145, 196, 32, 10, 22, 117, 186, 67, 113, 249, 170, 143, 150, 165, + 142, 89, 210, 107, 159, 253, 170, 60, 98, 110, 49, 218, 80, 40, 174, 107, 4, 65, 173, 74, + 32, 146, 145, 196, 32, 217, 71, 161, 77, 156, 151, 139, 146, 36, 137, 226, 148, 115, 164, + 104, 129, 82, 3, 137, 162, 97, 49, 234, 212, 38, 122, 217, 113, 94, 49, 170, 45, 145, 196, + 32, 0, 39, 234, 144, 83, 228, 112, 65, 112, 22, 52, 127, 110, 182, 130, 134, 5, 100, 243, + 12, 22, 87, 248, 188, 245, 43, 25, 98, 31, 249, 159, 49, 146, 145, 196, 32, 145, 204, 161, + 210, 214, 241, 10, 251, 99, 163, 218, 136, 194, 187, 142, 105, 81, 219, 86, 178, 182, 41, + 137, 104, 99, 78, 22, 119, 150, 107, 20, 56, 145, 196, 32, 110, 89, 67, 49, 48, 163, 98, + 249, 137, 112, 1, 177, 61, 250, 234, 8, 222, 227, 118, 204, 209, 158, 28, 91, 61, 228, 139, + 122, 119, 65, 194, 56, 146, 145, 196, 32, 233, 40, 75, 127, 89, 189, 115, 18, 154, 137, 79, + 76, 36, 166, 255, 136, 181, 48, 9, 218, 43, 230, 186, 78, 82, 212, 166, 29, 246, 43, 170, + 8, 145, 196, 32, 79, 88, 158, 213, 202, 249, 211, 235, 104, 186, 133, 224, 183, 74, 155, + 142, 215, 154, 140, 53, 35, 194, 245, 47, 254, 247, 143, 107, 68, 255, 39, 18, 146, 145, + 196, 32, 32, 147, 1, 102, 47, 170, 216, 11, 6, 69, 114, 245, 235, 55, 90, 192, 103, 234, + 209, 244, 144, 152, 107, 42, 113, 135, 3, 159, 141, 174, 193, 55, 145, 196, 32, 121, 109, + 205, 190, 125, 162, 169, 77, 94, 177, 167, 210, 101, 104, 174, 226, 140, 71, 66, 20, 230, + 169, 189, 194, 135, 37, 55, 191, 228, 46, 126, 46, 146, 145, 196, 32, 231, 21, 102, 129, + 249, 168, 118, 224, 122, 142, 152, 38, 182, 64, 83, 38, 217, 212, 3, 215, 191, 164, 210, + 212, 86, 109, 117, 210, 63, 214, 217, 48, 145, 196, 32, 67, 119, 48, 123, 3, 206, 210, 69, + 189, 198, 57, 192, 186, 130, 26, 157, 50, 10, 20, 235, 222, 33, 244, 46, 148, 137, 77, 116, + 48, 79, 3, 47, 150, 146, 145, 196, 32, 127, 81, 253, 112, 121, 172, 132, 45, 235, 176, 11, + 207, 223, 221, 216, 192, 161, 8, 224, 64, 90, 201, 150, 60, 42, 234, 246, 26, 17, 165, 235, + 37, 145, 196, 32, 57, 159, 19, 161, 200, 181, 34, 82, 175, 92, 125, 142, 178, 157, 116, 42, + 47, 159, 19, 104, 98, 27, 10, 5, 53, 93, 189, 61, 19, 129, 112, 2, 146, 145, 196, 32, 168, + 145, 95, 229, 189, 41, 81, 220, 109, 116, 180, 186, 197, 8, 95, 127, 64, 15, 38, 71, 195, + 167, 176, 21, 65, 191, 217, 180, 47, 250, 68, 33, 145, 196, 32, 86, 37, 33, 206, 208, 85, + 149, 198, 4, 188, 184, 69, 182, 238, 122, 216, 38, 197, 107, 63, 121, 14, 241, 56, 4, 18, + 230, 132, 180, 68, 50, 26, 146, 145, 196, 32, 223, 29, 112, 229, 75, 205, 165, 75, 255, 7, + 215, 111, 246, 40, 174, 34, 234, 45, 53, 180, 118, 255, 180, 154, 43, 245, 14, 119, 207, + 109, 151, 28, 145, 196, 32, 247, 109, 122, 154, 23, 155, 251, 23, 136, 14, 39, 138, 208, + 20, 160, 208, 183, 198, 24, 250, 7, 132, 109, 25, 255, 244, 135, 234, 62, 168, 198, 9, 146, + 145, 196, 32, 41, 200, 167, 174, 85, 44, 163, 25, 20, 155, 78, 40, 52, 85, 52, 129, 10, + 249, 25, 242, 156, 65, 112, 183, 191, 1, 102, 89, 133, 56, 2, 18, 145, 196, 32, 134, 59, + 148, 56, 113, 189, 245, 223, 58, 179, 152, 188, 41, 218, 87, 169, 233, 79, 130, 96, 8, 62, + 183, 25, 146, 0, 136, 83, 17, 35, 44, 37, 146, 145, 196, 32, 232, 241, 18, 204, 46, 153, + 108, 69, 138, 84, 171, 189, 108, 246, 95, 107, 187, 119, 175, 123, 199, 71, 247, 249, 192, + 128, 64, 229, 249, 11, 68, 42, 145, 196, 32, 48, 24, 67, 3, 124, 44, 60, 255, 246, 181, 14, + 227, 136, 146, 107, 142, 149, 11, 119, 76, 201, 29, 8, 87, 145, 2, 211, 206, 11, 145, 58, + 4, 146, 145, 196, 32, 180, 157, 246, 21, 31, 235, 235, 196, 67, 173, 242, 182, 26, 6, 102, + 222, 70, 217, 153, 86, 144, 107, 96, 192, 200, 236, 92, 192, 129, 18, 215, 54, 145, 196, + 32, 73, 230, 155, 131, 29, 194, 23, 144, 31, 24, 139, 11, 10, 16, 75, 53, 61, 79, 36, 192, + 136, 24, 121, 223, 184, 67, 20, 33, 185, 102, 24, 46, 159, 146, 145, 196, 32, 83, 119, 237, + 167, 31, 187, 214, 117, 191, 206, 40, 195, 150, 206, 52, 87, 231, 139, 197, 15, 97, 83, + 207, 239, 183, 29, 15, 43, 135, 229, 115, 14, 145, 196, 32, 131, 103, 154, 225, 190, 207, + 85, 82, 73, 104, 135, 180, 222, 201, 146, 42, 80, 143, 174, 170, 153, 93, 237, 215, 204, + 178, 117, 68, 203, 30, 76, 61, 146, 145, 196, 32, 176, 101, 3, 109, 92, 181, 188, 246, 121, + 96, 110, 71, 232, 77, 67, 218, 39, 3, 71, 138, 6, 13, 197, 82, 118, 234, 238, 109, 241, + 204, 207, 18, 145, 196, 32, 164, 17, 234, 58, 176, 54, 71, 24, 97, 103, 7, 133, 170, 25, + 56, 159, 191, 136, 126, 133, 90, 70, 10, 157, 65, 51, 32, 189, 149, 24, 164, 59, 146, 145, + 196, 32, 81, 154, 252, 146, 144, 123, 112, 162, 161, 152, 222, 193, 19, 75, 3, 72, 216, + 252, 184, 117, 249, 242, 58, 173, 137, 21, 17, 146, 14, 51, 48, 45, 145, 196, 32, 93, 238, + 21, 197, 60, 250, 229, 128, 186, 145, 69, 132, 81, 127, 14, 131, 64, 119, 129, 122, 165, + 185, 245, 98, 190, 204, 223, 66, 106, 231, 91, 4, 146, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 196, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 146, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 145, 196, 32, 176, 101, 3, 109, 92, 181, + 188, 246, 121, 96, 110, 71, 232, 77, 67, 218, 39, 3, 71, 138, 6, 13, 197, 82, 118, 234, + 238, 109, 241, 204, 207, 18, 145, 196, 32, 164, 17, 234, 58, 176, 54, 71, 24, 97, 103, 7, + 133, 170, 25, 56, 159, 191, 136, 126, 133, 90, 70, 10, 157, 65, 51, 32, 189, 149, 24, 164, + 59, 146, 145, 196, 32, 81, 154, 252, 146, 144, 123, 112, 162, 161, 152, 222, 193, 19, 75, + 3, 72, 216, 252, 184, 117, 249, 242, 58, 173, 137, 21, 17, 146, 14, 51, 48, 45, 145, 196, + 32, 93, 238, 21, 197, 60, 250, 229, 128, 186, 145, 69, 132, 81, 127, 14, 131, 64, 119, 129, + 122, 165, 185, 245, 98, 190, 204, 223, 66, 106, 231, 91, 4, 146, 145, 196, 32, 161, 52, + 249, 37, 52, 198, 179, 171, 39, 56, 112, 122, 43, 253, 191, 109, 176, 249, 113, 235, 242, + 229, 117, 90, 19, 43, 34, 36, 29, 102, 96, 26, 145, 196, 32, 186, 220, 43, 138, 121, 244, + 203, 1, 117, 35, 139, 8, 163, 254, 28, 6, 129, 238, 2, 245, 74, 115, 235, 197, 124, 153, + 191, 133, 212, 206, 183, 8, 146, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 145, 196, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 146, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 145, 196, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, + 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 146, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 145, 196, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 196, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 146, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 145, 196, 32, 83, 119, 237, 167, + 31, 187, 214, 117, 191, 206, 40, 195, 150, 206, 52, 87, 231, 139, 197, 15, 97, 83, 207, + 239, 183, 29, 15, 43, 135, 229, 115, 14, 145, 196, 32, 131, 103, 154, 225, 190, 207, 85, + 82, 73, 104, 135, 180, 222, 201, 146, 42, 80, 143, 174, 170, 153, 93, 237, 215, 204, 178, + 117, 68, 203, 30, 76, 61, 146, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 145, 196, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 146, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 145, 196, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, + 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 146, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 196, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 192, 192, 192, 146, 145, 196, + 32, 110, 102, 247, 171, 156, 186, 16, 115, 183, 126, 129, 59, 82, 133, 202, 1, 119, 113, + 215, 111, 189, 2, 187, 238, 111, 133, 22, 51, 15, 39, 51, 3, 145, 196, 32, 46, 115, 234, + 37, 231, 189, 140, 98, 240, 154, 252, 196, 198, 141, 226, 230, 137, 106, 186, 156, 43, 162, + 61, 143, 220, 223, 83, 90, 79, 215, 253, 49, 192, 146, 145, 196, 32, 211, 211, 128, 7, 227, + 164, 230, 166, 87, 75, 134, 95, 148, 59, 79, 175, 144, 11, 187, 141, 242, 168, 88, 148, + 127, 9, 116, 69, 54, 66, 223, 55, 145, 196, 32, 53, 4, 41, 51, 3, 179, 232, 101, 53, 242, + 189, 251, 61, 11, 64, 181, 57, 219, 78, 243, 151, 228, 100, 149, 115, 44, 85, 135, 52, 218, + 119, 32, 146, 145, 196, 32, 245, 11, 26, 25, 15, 220, 187, 252, 168, 220, 32, 222, 6, 90, + 71, 17, 28, 31, 87, 80, 8, 73, 213, 165, 232, 54, 233, 53, 196, 31, 8, 48, 145, 196, 32, + 228, 24, 160, 146, 167, 151, 30, 193, 222, 233, 86, 65, 122, 85, 93, 178, 195, 14, 173, + 147, 96, 2, 191, 176, 10, 106, 80, 241, 124, 118, 52, 3, 149, 146, 145, 196, 32, 90, 224, + 81, 149, 111, 48, 6, 252, 183, 101, 11, 82, 13, 173, 24, 154, 14, 62, 100, 192, 235, 191, + 159, 162, 233, 96, 190, 10, 198, 204, 74, 24, 145, 196, 32, 111, 137, 38, 37, 2, 42, 30, + 38, 23, 188, 156, 183, 208, 208, 147, 195, 24, 105, 235, 130, 223, 108, 72, 171, 140, 199, + 93, 28, 162, 143, 125, 50, 146, 145, 196, 32, 254, 47, 69, 230, 79, 164, 131, 113, 199, + 251, 155, 24, 230, 200, 110, 131, 53, 219, 247, 46, 187, 243, 202, 188, 228, 213, 51, 94, + 191, 183, 209, 37, 145, 196, 32, 144, 24, 163, 133, 65, 123, 50, 173, 110, 98, 148, 135, + 77, 35, 15, 151, 134, 239, 185, 123, 89, 67, 203, 238, 77, 140, 221, 237, 176, 166, 151, + 35, 146, 145, 196, 32, 206, 85, 134, 244, 169, 90, 184, 226, 82, 254, 96, 192, 32, 142, + 214, 87, 16, 0, 50, 19, 163, 211, 4, 204, 121, 47, 121, 0, 12, 148, 245, 10, 145, 196, 32, + 231, 45, 157, 29, 11, 2, 56, 228, 112, 112, 112, 198, 217, 213, 218, 140, 245, 211, 177, + 12, 180, 195, 212, 102, 183, 85, 174, 26, 32, 124, 66, 31, 146, 145, 196, 32, 4, 116, 222, + 53, 166, 105, 196, 244, 52, 145, 248, 85, 102, 77, 21, 28, 34, 156, 239, 9, 42, 66, 70, 73, + 228, 27, 57, 205, 76, 24, 0, 1, 145, 196, 32, 99, 227, 137, 27, 63, 23, 100, 149, 59, 95, + 31, 58, 168, 227, 214, 93, 66, 158, 216, 94, 17, 121, 152, 240, 51, 172, 8, 59, 3, 255, + 158, 34, 146, 145, 196, 32, 200, 19, 121, 186, 173, 71, 186, 140, 232, 161, 29, 79, 129, + 20, 40, 177, 113, 61, 38, 5, 117, 127, 95, 49, 161, 71, 54, 122, 184, 175, 52, 54, 145, + 196, 32, 152, 85, 13, 195, 21, 224, 248, 230, 241, 103, 51, 95, 182, 180, 97, 0, 97, 92, + 153, 42, 69, 101, 156, 213, 94, 196, 237, 251, 13, 240, 23, 47, 192, 192, 146, 145, 196, + 32, 110, 102, 247, 171, 156, 186, 16, 115, 183, 126, 129, 59, 82, 133, 202, 1, 119, 113, + 215, 111, 189, 2, 187, 238, 111, 133, 22, 51, 15, 39, 51, 3, 145, 196, 32, 46, 115, 234, + 37, 231, 189, 140, 98, 240, 154, 252, 196, 198, 141, 226, 230, 137, 106, 186, 156, 43, 162, + 61, 143, 220, 223, 83, 90, 79, 215, 253, 49, 192, 192, 192, 196, 32, 25, 212, 127, 17, 107, + 251, 186, 229, 239, 230, 182, 195, 40, 232, 118, 45, 205, 78, 253, 203, 141, 81, 175, 186, + 185, 116, 235, 41, 158, 240, 90, 22, 144, + ]; + prove_and_check_serialization_regression::( + 8, + buf_expected, + ); +} diff --git a/kimchi/src/tests/framework.rs b/kimchi/src/tests/framework.rs index 9309b71581..b49fdf2aad 100644 --- a/kimchi/src/tests/framework.rs +++ b/kimchi/src/tests/framework.rs @@ -29,6 +29,7 @@ use num_bigint::BigUint; use poly_commitment::{ commitment::CommitmentCurve, evaluation_proof::OpeningProof as DlogOpeningProof, OpenProof, }; +use rand_core::{CryptoRng, RngCore}; use std::{fmt::Write, time::Instant}; // aliases @@ -241,13 +242,14 @@ where let group_map = ::Map::setup(); - ProverProof::create_recursive::( + ProverProof::create_recursive::( &group_map, witness, &self.0.runtime_tables, &prover, self.0.recursion, None, + &mut rand::rngs::OsRng, ) .map_err(|e| e.to_string())?; Ok(()) @@ -275,13 +277,14 @@ where let group_map = ::Map::setup(); - let proof = ProverProof::create_recursive::( + let proof = ProverProof::create_recursive::( &group_map, witness, &self.0.runtime_tables, &prover, self.0.recursion, None, + &mut rand::rngs::OsRng, ) .map_err(|e| e.to_string())?; println!("- time to create proof: {:?}s", start.elapsed().as_secs()); @@ -301,6 +304,65 @@ where } } +impl TestRunner +where + G::ScalarField: PrimeField + Clone, + G::BaseField: PrimeField + Clone, + OpeningProof: OpenProof + + Clone + + PartialEq + + std::fmt::Debug + + serde::Serialize + + for<'a> serde::Deserialize<'a>, + OpeningProof::SRS: Clone, + VerifierIndex: Clone, +{ + /// Regression test: Create a proof and check that is is equal to + /// the given serialized implementation (and that deserializes + /// correctly). + pub(crate) fn prove_and_check_serialization_regression< + EFqSponge, + EFrSponge, + RNG: RngCore + CryptoRng, + >( + self, + buf_expected: Vec, + rng: &mut RNG, + ) -> Result<(), String> + where + EFqSponge: Clone + FqSponge, + EFrSponge: FrSponge, + { + let prover = self.0.prover_index.unwrap(); + let witness = self.0.witness.unwrap(); + + if !self.0.disable_gates_checks { + // Note: this is already done by ProverProof::create_recursive::() + // not sure why we do it here + prover + .verify(&witness, &self.0.public_inputs) + .map_err(|e| format!("{e:?}"))?; + } + + let group_map = ::Map::setup(); + + let proof = ProverProof::create_recursive::( + &group_map, + witness, + &self.0.runtime_tables, + &prover, + self.0.recursion, + None, + rng, + ) + .map_err(|e| e.to_string())?; + + o1_utils::serialization::test_generic_serialization_regression_serde(proof, buf_expected); + + Ok(()) + } +} + pub fn print_witness(cols: &[Vec; COLUMNS], start_row: usize, end_row: usize) where F: PrimeField, diff --git a/kimchi/src/tests/range_check.rs b/kimchi/src/tests/range_check.rs index a97eb29830..2d7f194e91 100644 --- a/kimchi/src/tests/range_check.rs +++ b/kimchi/src/tests/range_check.rs @@ -1205,9 +1205,14 @@ fn verify_range_check_valid_proof1() { // Generate proof let group_map = ::Map::setup(); let public_input = witness[0][0..prover_index.cs.public].to_vec(); - let proof = - ProverProof::create::(&group_map, witness, &[], &prover_index) - .expect("failed to generate proof"); + let proof = ProverProof::create::( + &group_map, + witness, + &[], + &prover_index, + &mut rand::rngs::OsRng, + ) + .expect("failed to generate proof"); // Get the verifier index let verifier_index = prover_index.verifier_index(); diff --git a/kimchi/src/tests/serde.rs b/kimchi/src/tests/serde.rs index d9d278d6f4..c893d5e6cd 100644 --- a/kimchi/src/tests/serde.rs +++ b/kimchi/src/tests/serde.rs @@ -67,9 +67,14 @@ mod tests { // add the proof to the batch let group_map = ::Map::setup(); - let proof = - ProverProof::create::(&group_map, witness, &[], &index) - .unwrap(); + let proof = ProverProof::create::( + &group_map, + witness, + &[], + &index, + &mut rand::rngs::OsRng, + ) + .unwrap(); // deserialize the verifier index let mut verifier_index_deserialize: VerifierIndex, _> = diff --git a/poly-commitment/src/evaluation_proof.rs b/poly-commitment/src/evaluation_proof.rs index 04038fab33..71cf472aeb 100644 --- a/poly-commitment/src/evaluation_proof.rs +++ b/poly-commitment/src/evaluation_proof.rs @@ -362,7 +362,7 @@ impl SRS { } #[serde_as] -#[derive(Clone, Debug, Serialize, Deserialize, Default)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)] #[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")] pub struct OpeningProof { /// vector of rounds of L & R commitments diff --git a/poly-commitment/src/tests/commitment.rs b/poly-commitment/src/tests/commitment.rs index 859289ed9a..9eb2a37eab 100644 --- a/poly-commitment/src/tests/commitment.rs +++ b/poly-commitment/src/tests/commitment.rs @@ -67,7 +67,7 @@ pub struct AggregatedEvaluationProof { /// an Fq-sponge fq_sponge: DefaultFqSponge, /// the actual evaluation proof - proof: OpeningProof, + pub proof: OpeningProof, } impl AggregatedEvaluationProof { @@ -105,18 +105,17 @@ impl AggregatedEvaluationProof { } } -fn test_randomised(mut rng: &mut RNG) { - let group_map = ::Map::setup(); +pub fn generate_random_opening_proof( + mut rng: &mut RNG, + group_map: &::Map, + srs: &SRS, +) -> (Vec, Duration, Duration) { + let num_chunks = 1; + let fq_sponge = DefaultFqSponge::::new( mina_poseidon::pasta::fq_kimchi::static_params(), ); - // create an SRS optimized for polynomials of degree 2^7 - 1 - let srs = SRS::::create(1 << 7); - - let num_chunks = 1; - - // TODO: move to bench let mut time_commit = Duration::new(0, 0); let mut time_open = Duration::new(0, 0); @@ -194,7 +193,7 @@ fn test_randomised(mut rng: &mut RNG) { let timer = Instant::now(); let proof = srs.open::, _, _>( - &group_map, + group_map, &polynomials, &eval_points.clone(), polymask, @@ -216,6 +215,19 @@ fn test_randomised(mut rng: &mut RNG) { }); } + (proofs, time_commit, time_open) +} + +fn test_randomised(mut rng: &mut RNG) { + let group_map = ::Map::setup(); + // create an SRS optimized for polynomials of degree 2^7 - 1 + let srs = SRS::::create(1 << 7); + + // TODO: move to bench + + let (proofs, time_commit, time_open) = + generate_random_opening_proof(&mut rng, &group_map, &srs); + println!("{} {:?}", "total commitment time:".yellow(), time_commit); println!( "{} {:?}", diff --git a/poly-commitment/src/tests/mod.rs b/poly-commitment/src/tests/mod.rs index af9a5db131..f65c6f90b4 100644 --- a/poly-commitment/src/tests/mod.rs +++ b/poly-commitment/src/tests/mod.rs @@ -1,2 +1,3 @@ mod batch_15_wires; mod commitment; +mod serialization; diff --git a/poly-commitment/src/tests/serialization.rs b/poly-commitment/src/tests/serialization.rs new file mode 100644 index 0000000000..31e98f7d90 --- /dev/null +++ b/poly-commitment/src/tests/serialization.rs @@ -0,0 +1,160 @@ +//! This module checks serialization/regression for types defined within the crate. + +use crate::{commitment::CommitmentCurve, srs::SRS, SRS as _}; +use ark_ff::UniformRand; +use o1_utils::serialization::test_generic_serialization_regression_serde; +use rand::{rngs::StdRng, SeedableRng}; + +#[test] +pub fn ser_regression_canonical_srs() { + use mina_curves::pasta::{Fp, Fq, Pallas, Vesta}; + + let rng = &mut StdRng::from_seed([0u8; 32]); + + let td1 = Fp::rand(rng); + let data_expected = SRS::::create_trusted_setup(td1, 1 << 3); + // Generated with commit 1494cf973d40fb276465929eb7db1952c5de7bdc + let buf_expected: Vec = vec![ + 146, 152, 196, 33, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 33, 2, 208, 196, 173, 72, 216, 133, 169, 56, 56, 33, 35, + 130, 78, 164, 182, 235, 78, 233, 153, 95, 96, 113, 78, 110, 205, 98, 59, 183, 156, 34, 26, + 128, 196, 33, 6, 150, 178, 230, 252, 128, 97, 30, 248, 199, 147, 159, 227, 118, 248, 138, + 60, 143, 178, 158, 37, 232, 110, 15, 134, 143, 127, 109, 206, 204, 155, 27, 128, 196, 33, + 64, 90, 121, 139, 173, 254, 255, 108, 129, 22, 165, 14, 110, 147, 48, 189, 183, 210, 237, + 108, 189, 170, 107, 238, 149, 155, 227, 211, 89, 63, 121, 46, 0, 196, 33, 90, 220, 159, + 218, 37, 222, 219, 32, 63, 233, 183, 226, 174, 205, 38, 189, 143, 33, 160, 169, 226, 235, + 216, 43, 17, 29, 215, 31, 150, 233, 163, 36, 0, 196, 33, 98, 225, 126, 245, 162, 255, 249, + 60, 120, 105, 186, 96, 169, 208, 83, 62, 19, 64, 187, 79, 11, 120, 130, 242, 249, 79, 249, + 99, 210, 225, 25, 36, 0, 196, 33, 49, 147, 222, 224, 242, 240, 198, 119, 133, 90, 152, 19, + 122, 52, 255, 181, 14, 55, 81, 250, 47, 167, 47, 195, 36, 7, 187, 103, 225, 0, 169, 26, 0, + 196, 33, 160, 235, 225, 204, 186, 77, 26, 177, 237, 210, 27, 246, 174, 136, 126, 204, 93, + 48, 11, 220, 178, 86, 174, 156, 6, 6, 86, 90, 105, 215, 117, 16, 128, 196, 33, 1, 34, 38, + 38, 91, 206, 178, 229, 168, 199, 139, 226, 117, 121, 162, 156, 54, 54, 120, 117, 99, 242, + 180, 170, 153, 201, 1, 99, 56, 96, 32, 9, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + + test_generic_serialization_regression_serde(data_expected, buf_expected); + + let td2 = Fq::rand(rng); + let data_expected = SRS::::create_trusted_setup(td2, 1 << 3); + // Generated with commit 1494cf973d40fb276465929eb7db1952c5de7bdc + let buf_expected: Vec = vec![ + 146, 152, 196, 33, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 33, 144, 162, 168, 123, 25, 245, 211, 151, 234, 53, 230, + 184, 254, 200, 193, 156, 214, 207, 155, 171, 186, 143, 221, 21, 24, 49, 159, 187, 221, 215, + 92, 61, 0, 196, 33, 172, 18, 76, 72, 86, 115, 105, 59, 32, 148, 37, 128, 195, 62, 60, 165, + 201, 121, 67, 175, 73, 51, 78, 160, 25, 215, 242, 243, 71, 93, 49, 29, 128, 196, 33, 130, + 19, 51, 124, 82, 66, 228, 1, 66, 62, 240, 98, 240, 241, 101, 177, 252, 8, 42, 36, 76, 215, + 244, 24, 170, 221, 102, 204, 51, 183, 231, 52, 128, 196, 33, 121, 187, 189, 65, 178, 95, + 164, 135, 161, 57, 194, 93, 76, 12, 253, 165, 236, 21, 171, 199, 162, 16, 185, 75, 0, 120, + 171, 4, 1, 21, 184, 1, 0, 196, 33, 165, 208, 157, 8, 127, 129, 67, 81, 56, 223, 87, 125, + 139, 239, 36, 18, 139, 239, 53, 114, 116, 81, 1, 174, 76, 50, 97, 213, 108, 193, 107, 46, + 128, 196, 33, 83, 43, 226, 38, 146, 122, 97, 205, 114, 214, 23, 21, 165, 138, 211, 222, + 224, 190, 130, 70, 142, 203, 203, 89, 49, 138, 144, 104, 8, 247, 147, 11, 128, 196, 33, 73, + 128, 98, 223, 249, 164, 221, 198, 148, 190, 44, 37, 20, 106, 24, 112, 49, 72, 64, 157, 99, + 100, 170, 222, 105, 160, 160, 92, 194, 154, 93, 19, 128, 196, 33, 1, 130, 119, 215, 95, + 139, 130, 47, 90, 13, 171, 187, 79, 106, 134, 121, 50, 181, 54, 202, 63, 25, 38, 174, 42, + 5, 210, 172, 157, 149, 27, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + test_generic_serialization_regression_serde(data_expected, buf_expected); +} + +#[test] +pub fn ser_regression_canonical_polycomm() { + use crate::{commitment::BlindedCommitment, srs::SRS}; + use ark_poly::{univariate::DensePolynomial, DenseUVPolynomial}; + use mina_curves::pasta::{Fp, Vesta}; + + let rng = &mut StdRng::from_seed([0u8; 32]); + + let srs = SRS::::create(1 << 7); + + let com_length = 300; + let num_chunks = 6; + + let poly = DensePolynomial::::rand(com_length, rng); + + let BlindedCommitment { + commitment: chunked_commitment, + blinders: _blinders, + } = srs.commit(&poly, num_chunks, rng); + + let data_expected = chunked_commitment; + // Generated with commit 1494cf973d40fb276465929eb7db1952c5de7bdc + let buf_expected: Vec = vec![ + 145, 150, 196, 33, 36, 158, 70, 161, 147, 233, 138, 19, 54, 52, 87, 58, 158, 154, 255, 197, + 219, 225, 79, 25, 41, 193, 232, 64, 250, 71, 230, 154, 34, 145, 81, 23, 0, 196, 33, 37, + 227, 246, 88, 42, 44, 53, 244, 102, 92, 197, 246, 56, 56, 135, 155, 248, 155, 243, 23, 76, + 44, 94, 125, 60, 209, 195, 190, 73, 158, 97, 42, 128, 196, 33, 101, 254, 242, 100, 238, + 214, 56, 151, 94, 170, 69, 219, 239, 135, 253, 151, 207, 217, 47, 229, 75, 7, 41, 9, 131, + 205, 85, 171, 166, 213, 96, 52, 128, 196, 33, 53, 166, 32, 175, 166, 196, 121, 1, 25, 236, + 34, 226, 31, 145, 70, 96, 89, 179, 65, 35, 253, 161, 10, 211, 170, 116, 247, 40, 225, 104, + 155, 34, 0, 196, 33, 114, 151, 94, 73, 26, 234, 37, 98, 188, 142, 161, 165, 62, 238, 58, + 76, 200, 16, 62, 210, 124, 127, 229, 81, 119, 145, 43, 157, 254, 237, 154, 57, 128, 196, + 33, 212, 213, 38, 1, 17, 84, 147, 102, 31, 103, 242, 177, 110, 64, 239, 33, 211, 216, 40, + 103, 51, 55, 85, 96, 133, 20, 194, 6, 87, 180, 212, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + ]; + + test_generic_serialization_regression_serde(data_expected, buf_expected); +} + +#[test] +pub fn ser_regression_canonical_opening_proof() { + use crate::evaluation_proof::OpeningProof; + use groupmap::GroupMap; + use mina_curves::pasta::Vesta; + + let rng = &mut StdRng::from_seed([0u8; 32]); + + let group_map = ::Map::setup(); + let srs = SRS::::create(1 << 7); + + let data_expected: OpeningProof = + crate::tests::commitment::generate_random_opening_proof(rng, &group_map, &srs).0[0] + .proof + .clone(); + + // Generated with commit 1494cf973d40fb276465929eb7db1952c5de7bdc + let buf_expected: Vec = vec![ + 149, 151, 146, 196, 33, 166, 183, 76, 209, 121, 62, 56, 194, 134, 133, 238, 52, 190, 163, + 234, 149, 245, 202, 234, 70, 56, 187, 130, 25, 73, 135, 136, 95, 248, 80, 124, 39, 128, + 196, 33, 78, 148, 92, 114, 104, 136, 170, 61, 102, 158, 80, 42, 184, 109, 110, 33, 228, + 116, 55, 98, 16, 192, 10, 159, 156, 72, 87, 129, 68, 66, 248, 26, 0, 146, 196, 33, 251, 20, + 242, 183, 87, 51, 106, 226, 80, 224, 139, 186, 33, 52, 203, 117, 6, 129, 167, 88, 252, 193, + 163, 38, 21, 37, 63, 254, 106, 136, 63, 21, 0, 196, 33, 4, 215, 169, 8, 207, 56, 209, 41, + 107, 189, 92, 110, 124, 186, 112, 193, 204, 173, 82, 46, 110, 8, 194, 193, 93, 130, 12, + 216, 24, 151, 94, 61, 128, 146, 196, 33, 55, 26, 135, 155, 211, 30, 67, 184, 93, 78, 146, + 166, 31, 11, 120, 93, 17, 24, 164, 39, 177, 98, 25, 156, 33, 5, 179, 64, 237, 69, 199, 11, + 128, 196, 33, 249, 229, 29, 113, 38, 26, 30, 205, 26, 217, 71, 248, 199, 157, 244, 196, 1, + 108, 74, 39, 173, 55, 118, 216, 191, 232, 27, 95, 190, 38, 96, 35, 128, 146, 196, 33, 109, + 160, 19, 169, 187, 111, 247, 152, 101, 20, 161, 251, 150, 61, 204, 78, 118, 171, 81, 1, + 253, 83, 64, 170, 93, 114, 216, 224, 33, 250, 202, 14, 0, 196, 33, 247, 34, 197, 187, 28, + 46, 42, 6, 126, 129, 132, 151, 39, 150, 115, 138, 229, 50, 220, 8, 170, 81, 173, 13, 54, + 57, 90, 169, 201, 212, 128, 50, 128, 146, 196, 33, 73, 206, 252, 115, 3, 45, 100, 75, 98, + 139, 35, 227, 181, 241, 175, 2, 175, 14, 132, 86, 0, 174, 64, 84, 24, 88, 18, 163, 82, 102, + 164, 19, 0, 196, 33, 128, 62, 85, 80, 76, 1, 35, 195, 197, 48, 46, 1, 13, 183, 105, 91, + 243, 109, 124, 68, 41, 21, 42, 228, 124, 28, 193, 188, 85, 6, 180, 24, 128, 146, 196, 33, + 21, 245, 240, 236, 40, 30, 75, 91, 87, 50, 153, 173, 88, 231, 34, 227, 241, 146, 134, 156, + 217, 161, 155, 165, 76, 142, 69, 82, 45, 49, 163, 56, 0, 196, 33, 247, 220, 178, 199, 227, + 182, 213, 3, 75, 71, 188, 175, 31, 189, 247, 209, 217, 210, 21, 56, 246, 86, 89, 71, 165, + 90, 75, 150, 236, 68, 240, 37, 0, 146, 196, 33, 18, 70, 242, 33, 232, 246, 235, 191, 213, + 96, 68, 75, 173, 43, 125, 25, 239, 71, 93, 71, 74, 159, 50, 34, 251, 139, 133, 228, 241, + 49, 166, 36, 0, 196, 33, 28, 99, 102, 90, 22, 105, 167, 195, 200, 126, 132, 202, 178, 50, + 197, 41, 204, 7, 108, 2, 12, 7, 221, 0, 61, 120, 23, 112, 11, 47, 104, 60, 128, 196, 33, + 34, 178, 82, 48, 155, 153, 34, 99, 173, 221, 221, 236, 235, 5, 135, 165, 18, 39, 120, 175, + 253, 216, 48, 255, 8, 67, 160, 96, 72, 49, 99, 21, 0, 196, 32, 148, 153, 156, 103, 116, 92, + 72, 80, 249, 8, 110, 104, 44, 231, 231, 1, 62, 3, 189, 77, 153, 74, 89, 74, 191, 185, 236, + 20, 209, 93, 77, 51, 196, 32, 33, 224, 176, 185, 62, 76, 18, 58, 48, 219, 106, 206, 35, + 153, 234, 54, 21, 29, 87, 57, 147, 84, 219, 194, 208, 170, 158, 105, 241, 63, 76, 44, 196, + 33, 236, 186, 22, 30, 113, 33, 148, 99, 242, 146, 146, 41, 119, 163, 230, 139, 48, 191, 57, + 161, 79, 240, 7, 167, 28, 62, 213, 170, 132, 195, 255, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + + test_generic_serialization_regression_serde(data_expected, buf_expected); +} diff --git a/utils/Cargo.toml b/utils/Cargo.toml index d43f01e5ca..453f6201db 100644 --- a/utils/Cargo.toml +++ b/utils/Cargo.toml @@ -12,7 +12,7 @@ license = "Apache-2.0" [dependencies] ark-ec.workspace = true ark-ff.workspace = true -ark-poly.workspace = true +ark-poly.workspace = true ark-serialize.workspace = true bcs.workspace = true rayon.workspace = true @@ -20,16 +20,17 @@ serde.workspace = true serde_with.workspace = true hex.workspace = true num-bigint.workspace = true -num-integer.workspace = true +num-integer.workspace = true num-traits.workspace = true -rmp-serde.workspace = true +rmp-serde.workspace = true sha2.workspace = true thiserror.workspace = true rand.workspace = true rand_core.workspace = true + mina-curves.workspace = true [dev-dependencies] ark-ec.workspace = true -num-bigint.workspace = true +num-bigint.workspace = true secp256k1.workspace = true diff --git a/utils/src/serialization.rs b/utils/src/serialization.rs index 2fb0bd30f4..01f1e94a0b 100644 --- a/utils/src/serialization.rs +++ b/utils/src/serialization.rs @@ -1,8 +1,9 @@ //! This adds a few utility functions for serializing and deserializing //! [arkworks](http://arkworks.rs/) types that implement [CanonicalSerialize] and [CanonicalDeserialize]. -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Write}; use serde_with::Bytes; +use std::io::BufReader; // // Serialization with serde @@ -88,18 +89,147 @@ where } } +/// A generic regression serialization test for serialization via +/// `CanonicalSerialize` and `CanonicalDeserialize`. +pub fn test_generic_serialization_regression_canonical< + T: CanonicalSerialize + CanonicalDeserialize + std::cmp::PartialEq + std::fmt::Debug, +>( + data_expected: T, + buf_expected: Vec, +) { + // Step 1: serialize `data_expected` and check if it's equal to `buf_expected` + + let mut buf_written: Vec = vec![]; + data_expected + .serialize_compressed(&mut buf_written) + .expect("Given value could not be serialized"); + (buf_written.as_mut_slice()) + .flush() + .expect("Failed to flush buffer"); + assert!( + buf_written == buf_expected, + "Canonical: serialized (written) representation of {data_expected:?}...\n {buf_written:?}\n does not match the expected one...\n {buf_expected:?}" + ); + + // Step 2: deserialize `buf_expected` and check if it's equal to `data_expected` + + let reader = BufReader::new(buf_expected.as_slice()); + let data_read: T = + T::deserialize_compressed(reader).expect("Could not deseralize given bytevector"); + + assert!( + data_read == data_expected, + "Canonical: deserialized value...\n {data_read:?}\n does not match the expected one...\n {data_expected:?}" + ); +} + +/// A generic regression serialization test for serialization via `serde`. +pub fn test_generic_serialization_regression_serde< + T: serde::Serialize + for<'a> serde::Deserialize<'a> + std::cmp::PartialEq + std::fmt::Debug, +>( + data_expected: T, + buf_expected: Vec, +) { + // Step 1: serialize `data_expected` and check if it's equal to `buf_expected` + + let mut buf_written: Vec = vec![0; buf_expected.len()]; + let serialized_bytes = + rmp_serde::to_vec(&data_expected).expect("Given value could not be serialized"); + (buf_written.as_mut_slice()) + .write_all(&serialized_bytes) + .expect("Failed to write buffer"); + (buf_written.as_mut_slice()) + .flush() + .expect("Failed to flush buffer"); + assert!( + buf_written.len() == buf_expected.len(), + "Buffers length must be equal by design" + ); + if buf_written != buf_expected { + let mut first_distinct_byte_ix = 0; + for i in 0..buf_written.len() { + if buf_written[i] != buf_expected[i] { + first_distinct_byte_ix = i; + break; + } + } + panic!( + "Serde: serialized (written) representation of {data_expected:?}...\n {buf_written:?}\n does not match the expected one...\n {buf_expected:?}\nFirst distinct byte: #{first_distinct_byte_ix}: {} vs {}\n (total length is {})", + buf_written[first_distinct_byte_ix], + buf_expected[first_distinct_byte_ix], + buf_written.len() + + ); + } + + // Step 2: deserialize `buf_expected` and check if it's equal to `data_expected` + + let reader = BufReader::new(buf_expected.as_slice()); + let data_read: T = rmp_serde::from_read(reader).expect("Could not deseralize given bytevector"); + + assert!( + data_read == data_expected, + "Serde: deserialized value...\n {data_read:?}\n does not match the expected one...\n {data_expected:?}" + ); +} + #[cfg(test)] mod tests { + use super::{ + test_generic_serialization_regression_canonical, + test_generic_serialization_regression_serde, + }; use ark_ec::short_weierstrass::SWCurveConfig; - use ark_serialize::Write; use mina_curves::pasta::{Pallas, PallasParameters, Vesta, VestaParameters}; use serde::{Deserialize, Serialize}; use serde_with::serde_as; - use std::io::BufReader; #[test] - pub fn serde_as_regression_pasta() { + pub fn ser_regression_canonical_bigint() { + use mina_curves::pasta::Fp; + + // Generated with commit 1494cf973d40fb276465929eb7db1952c5de7bdc + let samples: Vec<(Fp, Vec)> = vec![ + ( + Fp::from(5u64), + vec![ + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ], + ), + ( + Fp::from((1u64 << 62) + 7u64), + vec![ + 7, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ], + ), + ( + Fp::from((1u64 << 30) * 13u64 * 7u64 * 5u64 * 3u64 + 7u64), + vec![ + 7, 0, 0, 64, 85, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ], + ), + ( + Fp::from((1u64 << 63) + 7u64) + * Fp::from((1u64 << 63) + 13u64) + * Fp::from((1u64 << 63) + 17u64), + vec![ + 11, 6, 0, 0, 0, 0, 0, 128, 215, 0, 0, 0, 0, 0, 0, 64, 9, 0, 0, 0, 0, 0, 0, 32, + 0, 0, 0, 0, 0, 0, 0, 0, + ], + ), + ]; + + for (data_expected, buf_expected) in samples { + test_generic_serialization_regression_canonical(data_expected, buf_expected); + } + } + + #[test] + pub fn ser_regression_canonical_pasta() { #[serde_as] #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] struct TestStruct { @@ -114,36 +244,13 @@ mod tests { vesta: VestaParameters::GENERATOR, }; - // reference serialized value + // Generated with commit 1494cf973d40fb276465929eb7db1952c5de7bdc let buf_expected: Vec = vec![ 146, 196, 33, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 33, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; - let mut buf_written: Vec = vec![0; buf_expected.len()]; - - let serialized_bytes = - rmp_serde::to_vec(&data_expected).expect("TestStruct could not be serialized"); - (buf_written.as_mut_slice()) - .write_all(&serialized_bytes) - .expect("failed to write file"); - (buf_written.as_mut_slice()) - .flush() - .expect("failed to flush file"); - - assert!( - buf_written == buf_expected, - "Serialized (written) representation {buf_written:?} does not match the expected one {buf_expected:?}" - ); - - let reader = BufReader::new(buf_expected.as_slice()); - let data_read: TestStruct = - rmp_serde::from_read(reader).expect("Could not deseralize TestStruct"); - - assert!( - data_read == data_expected, - "Deserialized value {data_read:?} does not match the expected one {data_expected:?}" - ); + test_generic_serialization_regression_serde(data_expected, buf_expected); } }