proof.rs
1 // Copyright (c) 2025-2026 ACDC Network 2 // This file is part of the alphavm library. 3 // 4 // Alpha Chain | Delta Chain Protocol 5 // International Monetary Graphite. 6 // 7 // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com). 8 // They built world-class ZK infrastructure. We installed the EASY button. 9 // Their cryptography: elegant. Our modifications: bureaucracy-compatible. 10 // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours. 11 // 12 // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0 13 // All modifications and new work: CC0 1.0 Universal Public Domain Dedication. 14 // No rights reserved. No permission required. No warranty. No refunds. 15 // 16 // https://creativecommons.org/publicdomain/zero/1.0/ 17 // SPDX-License-Identifier: CC0-1.0 18 19 use crate::{ 20 polycommit::{kzg10::KZGCommitment, sonic_pc}, 21 snark::varuna::{ahp, CircuitId, VarunaVersion}, 22 SNARKError, 23 }; 24 25 use ahp::prover::{FourthMessage, ThirdMessage}; 26 use alphavm_curves::PairingEngine; 27 use alphavm_fields::{One, PrimeField}; 28 use alphavm_utilities::{into_io_error, serialize::*, FromBytes, ToBytes}; 29 30 use anyhow::{anyhow, Result}; 31 use std::{ 32 collections::BTreeMap, 33 io::{self, Read, Write}, 34 }; 35 36 use std::mem::size_of; 37 38 #[derive(Clone, Debug, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)] 39 pub struct Commitments<E: PairingEngine> { 40 pub witness_commitments: Vec<WitnessCommitments<E>>, 41 /// Commitment to the masking polynomial. 42 pub mask_poly: Option<sonic_pc::Commitment<E>>, 43 /// Commitment to the `h_0` polynomial. 44 pub h_0: sonic_pc::Commitment<E>, 45 /// Commitment to the `g_1` polynomial. 46 pub g_1: sonic_pc::Commitment<E>, 47 /// Commitment to the `h_1` polynomial. 48 pub h_1: sonic_pc::Commitment<E>, 49 /// Commitment to the `g_a` polynomials. 50 pub g_a_commitments: Vec<sonic_pc::Commitment<E>>, 51 /// Commitment to the `g_b` polynomials. 52 pub g_b_commitments: Vec<sonic_pc::Commitment<E>>, 53 /// Commitment to the `g_c` polynomials. 54 pub g_c_commitments: Vec<sonic_pc::Commitment<E>>, 55 /// Commitment to the `h_2` polynomial. 56 pub h_2: sonic_pc::Commitment<E>, 57 } 58 59 impl<E: PairingEngine> Commitments<E> { 60 fn serialize_with_mode<W: alphavm_utilities::Write>( 61 &self, 62 mut writer: W, 63 compress: Compress, 64 ) -> Result<(), alphavm_utilities::SerializationError> { 65 serialize_vec_without_len(self.witness_commitments.iter(), &mut writer, compress)?; 66 CanonicalSerialize::serialize_with_mode(&self.mask_poly, &mut writer, compress)?; 67 CanonicalSerialize::serialize_with_mode(&self.h_0, &mut writer, compress)?; 68 CanonicalSerialize::serialize_with_mode(&self.g_1, &mut writer, compress)?; 69 CanonicalSerialize::serialize_with_mode(&self.h_1, &mut writer, compress)?; 70 serialize_vec_without_len(self.g_a_commitments.iter(), &mut writer, compress)?; 71 serialize_vec_without_len(self.g_b_commitments.iter(), &mut writer, compress)?; 72 serialize_vec_without_len(self.g_c_commitments.iter(), &mut writer, compress)?; 73 CanonicalSerialize::serialize_with_mode(&self.h_2, &mut writer, compress)?; 74 Ok(()) 75 } 76 77 fn serialized_size(&self, compress: Compress) -> usize { 78 serialized_vec_size_without_len(&self.witness_commitments, compress) 79 .saturating_add(CanonicalSerialize::serialized_size(&self.mask_poly, compress)) 80 .saturating_add(CanonicalSerialize::serialized_size(&self.h_0, compress)) 81 .saturating_add(CanonicalSerialize::serialized_size(&self.g_1, compress)) 82 .saturating_add(CanonicalSerialize::serialized_size(&self.h_1, compress)) 83 .saturating_add(serialized_vec_size_without_len(&self.g_a_commitments, compress)) 84 .saturating_add(serialized_vec_size_without_len(&self.g_b_commitments, compress)) 85 .saturating_add(serialized_vec_size_without_len(&self.g_c_commitments, compress)) 86 .saturating_add(CanonicalSerialize::serialized_size(&self.h_2, compress)) 87 } 88 89 fn deserialize_with_mode<R: alphavm_utilities::Read>( 90 batch_sizes: &[usize], 91 mut reader: R, 92 compress: Compress, 93 validate: Validate, 94 ) -> Result<Self, alphavm_utilities::SerializationError> { 95 let mut w = Vec::new(); 96 for batch_size in batch_sizes { 97 w.extend(deserialize_vec_without_len(&mut reader, compress, validate, *batch_size)?); 98 } 99 Ok(Commitments { 100 witness_commitments: w, 101 mask_poly: CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?, 102 h_0: CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?, 103 g_1: CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?, 104 h_1: CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?, 105 g_a_commitments: deserialize_vec_without_len(&mut reader, compress, validate, batch_sizes.len())?, 106 g_b_commitments: deserialize_vec_without_len(&mut reader, compress, validate, batch_sizes.len())?, 107 g_c_commitments: deserialize_vec_without_len(&mut reader, compress, validate, batch_sizes.len())?, 108 h_2: CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?, 109 }) 110 } 111 } 112 /// Commitments to the `w` polynomials. 113 #[derive(Clone, Debug, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)] 114 pub struct WitnessCommitments<E: PairingEngine> { 115 /// Commitment to the `w` polynomial. 116 pub w: sonic_pc::Commitment<E>, 117 } 118 119 #[derive(Clone, Debug, PartialEq, Eq)] 120 pub struct Evaluations<F: PrimeField> { 121 /// Evaluation of `g_1` at `beta`. 122 pub g_1_eval: F, 123 /// Evaluation of `g_a_i`'s at `beta`. 124 pub g_a_evals: Vec<F>, 125 /// Evaluation of `g_b_i`'s at `gamma`. 126 pub g_b_evals: Vec<F>, 127 /// Evaluation of `g_c_i`'s at `gamma`. 128 pub g_c_evals: Vec<F>, 129 } 130 131 impl<F: PrimeField> Evaluations<F> { 132 fn serialize_with_mode<W: alphavm_utilities::Write>( 133 &self, 134 mut writer: W, 135 compress: Compress, 136 ) -> Result<(), alphavm_utilities::SerializationError> { 137 CanonicalSerialize::serialize_with_mode(&self.g_1_eval, &mut writer, compress)?; 138 serialize_vec_without_len(self.g_a_evals.iter(), &mut writer, compress)?; 139 serialize_vec_without_len(self.g_b_evals.iter(), &mut writer, compress)?; 140 serialize_vec_without_len(self.g_c_evals.iter(), &mut writer, compress)?; 141 Ok(()) 142 } 143 144 fn serialized_size(&self, compress: Compress) -> usize { 145 CanonicalSerialize::serialized_size(&self.g_1_eval, compress) 146 .saturating_add(serialized_vec_size_without_len(&self.g_a_evals, compress)) 147 .saturating_add(serialized_vec_size_without_len(&self.g_b_evals, compress)) 148 .saturating_add(serialized_vec_size_without_len(&self.g_c_evals, compress)) 149 } 150 151 fn deserialize_with_mode<R: alphavm_utilities::Read>( 152 batch_sizes: &[usize], 153 mut reader: R, 154 compress: Compress, 155 validate: Validate, 156 ) -> Result<Self, alphavm_utilities::SerializationError> { 157 Ok(Evaluations { 158 g_1_eval: CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?, 159 g_a_evals: deserialize_vec_without_len(&mut reader, compress, validate, batch_sizes.len())?, 160 g_b_evals: deserialize_vec_without_len(&mut reader, compress, validate, batch_sizes.len())?, 161 g_c_evals: deserialize_vec_without_len(&mut reader, compress, validate, batch_sizes.len())?, 162 }) 163 } 164 } 165 166 impl<F: PrimeField> Evaluations<F> { 167 pub(crate) fn from_map( 168 map: &std::collections::BTreeMap<String, F>, 169 batch_sizes: BTreeMap<CircuitId, usize>, 170 ) -> Self { 171 let mut g_a_evals = Vec::with_capacity(batch_sizes.len()); 172 let mut g_b_evals = Vec::with_capacity(batch_sizes.len()); 173 let mut g_c_evals = Vec::with_capacity(batch_sizes.len()); 174 175 for (label, value) in map { 176 if label == "g_1" { 177 continue; 178 } 179 180 if label.contains("g_a") { 181 g_a_evals.push(*value); 182 } else if label.contains("g_b") { 183 g_b_evals.push(*value); 184 } else if label.contains("g_c") { 185 g_c_evals.push(*value); 186 } 187 } 188 Self { g_1_eval: map["g_1"], g_a_evals, g_b_evals, g_c_evals } 189 } 190 191 pub(crate) fn get(&self, circuit_index: usize, label: &str) -> Option<F> { 192 if label == "g_1" { 193 return Some(self.g_1_eval); 194 } 195 196 if label.contains("g_a") { 197 self.g_a_evals.get(circuit_index).copied() 198 } else if label.contains("g_b") { 199 self.g_b_evals.get(circuit_index).copied() 200 } else if label.contains("g_c") { 201 self.g_c_evals.get(circuit_index).copied() 202 } else { 203 None 204 } 205 } 206 207 pub fn to_field_elements(&self) -> Vec<F> { 208 let mut result = Vec::with_capacity(1 + self.g_a_evals.len() + self.g_b_evals.len() + self.g_c_evals.len()); 209 result.push(self.g_1_eval); 210 result.extend_from_slice(&self.g_a_evals); 211 result.extend_from_slice(&self.g_b_evals); 212 result.extend_from_slice(&self.g_c_evals); 213 result 214 } 215 } 216 217 impl<F: PrimeField> Valid for Evaluations<F> { 218 fn check(&self) -> Result<(), alphavm_utilities::SerializationError> { 219 self.g_1_eval.check()?; 220 self.g_a_evals.check()?; 221 self.g_b_evals.check()?; 222 self.g_c_evals.check() 223 } 224 } 225 226 /// A zkSNARK proof. 227 #[derive(Clone, Debug, PartialEq, Eq)] 228 pub struct Proof<E: PairingEngine> { 229 /// The number of instances being proven in this proof. 230 batch_sizes: Vec<usize>, 231 232 /// Commitments to prover polynomials. 233 pub commitments: Commitments<E>, 234 235 /// Evaluations of some of the committed polynomials. 236 pub evaluations: Evaluations<E::Fr>, 237 238 /// Prover message: sum_a, sum_b, sum_c for each instance 239 pub third_msg: ThirdMessage<E::Fr>, 240 241 /// Prover message: sum_a, sum_b, sum_c for each circuit 242 pub fourth_msg: FourthMessage<E::Fr>, 243 244 /// An evaluation proof from the polynomial commitment. 245 pub pc_proof: sonic_pc::BatchLCProof<E>, 246 } 247 248 impl<E: PairingEngine> Proof<E> { 249 /// Construct a new proof. 250 pub fn new( 251 batch_sizes: BTreeMap<CircuitId, usize>, 252 commitments: Commitments<E>, 253 evaluations: Evaluations<E::Fr>, 254 third_msg: ThirdMessage<E::Fr>, 255 fourth_msg: FourthMessage<E::Fr>, 256 pc_proof: sonic_pc::BatchLCProof<E>, 257 ) -> Result<Self, SNARKError> { 258 let batch_sizes: Vec<usize> = batch_sizes.into_values().collect(); 259 Ok(Self { batch_sizes, commitments, evaluations, third_msg, fourth_msg, pc_proof }) 260 } 261 262 pub fn is_hiding(&self) -> bool { 263 self.pc_proof.is_hiding() 264 } 265 266 pub fn batch_sizes(&self) -> &[usize] { 267 &self.batch_sizes 268 } 269 270 /// Check that the number of messages is consistent with our batch size 271 pub fn check_batch_sizes(&self) -> Result<(), SNARKError> { 272 let total_instances = self 273 .batch_sizes 274 .iter() 275 .try_fold(0usize, |acc, &size| acc.checked_add(size)) 276 .ok_or(SNARKError::BatchSizeMismatch)?; 277 if self.commitments.witness_commitments.len() != total_instances { 278 return Err(SNARKError::BatchSizeMismatch); 279 } 280 let g_comms = 281 [&self.commitments.g_a_commitments, &self.commitments.g_b_commitments, &self.commitments.g_c_commitments]; 282 for comms in g_comms { 283 if comms.len() != self.batch_sizes.len() { 284 return Err(SNARKError::BatchSizeMismatch); 285 } 286 } 287 let g_evals = [&self.evaluations.g_a_evals, &self.evaluations.g_b_evals, &self.evaluations.g_c_evals]; 288 for evals in g_evals { 289 if evals.len() != self.batch_sizes.len() { 290 return Err(SNARKError::BatchSizeMismatch); 291 } 292 } 293 if self.third_msg.sums.len() != self.batch_sizes.len() { 294 return Err(SNARKError::BatchSizeMismatch); 295 } 296 for (msg, &batch_size) in self.third_msg.sums.iter().zip(self.batch_sizes.iter()) { 297 if msg.len() != batch_size { 298 return Err(SNARKError::BatchSizeMismatch); 299 } 300 } 301 if self.fourth_msg.sums.len() != self.batch_sizes.len() { 302 return Err(SNARKError::BatchSizeMismatch); 303 } 304 Ok(()) 305 } 306 } 307 308 impl<E: PairingEngine> CanonicalSerialize for Proof<E> { 309 fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> { 310 let batch_sizes: Vec<u64> = self.batch_sizes.iter().map(|x| u64::try_from(*x)).collect::<Result<_, _>>()?; 311 CanonicalSerialize::serialize_with_mode(&batch_sizes, &mut writer, compress)?; 312 Commitments::serialize_with_mode(&self.commitments, &mut writer, compress)?; 313 Evaluations::serialize_with_mode(&self.evaluations, &mut writer, compress)?; 314 for third_sums in self.third_msg.sums.iter() { 315 serialize_vec_without_len(third_sums.iter(), &mut writer, compress)?; 316 } 317 serialize_vec_without_len(self.fourth_msg.sums.iter(), &mut writer, compress)?; 318 CanonicalSerialize::serialize_with_mode(&self.pc_proof, &mut writer, compress)?; 319 Ok(()) 320 } 321 322 fn serialized_size(&self, mode: Compress) -> usize { 323 let mut size = 0; 324 size += CanonicalSerialize::serialized_size(&self.batch_sizes, mode); 325 size += Commitments::serialized_size(&self.commitments, mode); 326 size += Evaluations::serialized_size(&self.evaluations, mode); 327 for third_sums in self.third_msg.sums.iter() { 328 size += serialized_vec_size_without_len(third_sums, mode); 329 } 330 size += serialized_vec_size_without_len(&self.fourth_msg.sums, mode); 331 size += CanonicalSerialize::serialized_size(&self.pc_proof, mode); 332 size 333 } 334 } 335 336 impl<E: PairingEngine> Valid for Proof<E> { 337 fn check(&self) -> Result<(), SerializationError> { 338 self.batch_sizes.check()?; 339 self.commitments.check()?; 340 self.evaluations.check()?; 341 self.third_msg.check()?; 342 self.fourth_msg.check()?; 343 self.pc_proof.check() 344 } 345 } 346 347 impl<E: PairingEngine> CanonicalDeserialize for Proof<E> { 348 fn deserialize_with_mode<R: Read>( 349 mut reader: R, 350 compress: Compress, 351 validate: Validate, 352 ) -> Result<Self, SerializationError> { 353 let batch_sizes: Vec<u64> = CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?; 354 let batch_sizes: Vec<usize> = batch_sizes.into_iter().map(|x| x as usize).collect(); 355 let commitments = Commitments::deserialize_with_mode(&batch_sizes, &mut reader, compress, validate)?; 356 let evaluations = Evaluations::deserialize_with_mode(&batch_sizes, &mut reader, compress, validate)?; 357 let third_msg_sums = batch_sizes 358 .iter() 359 .map(|&batch_size| deserialize_vec_without_len(&mut reader, compress, validate, batch_size)) 360 .collect::<Result<Vec<_>, _>>()?; 361 let fourth_msg_sums = deserialize_vec_without_len(&mut reader, compress, validate, batch_sizes.len())?; 362 Ok(Proof { 363 commitments, 364 evaluations, 365 third_msg: ThirdMessage { sums: third_msg_sums }, 366 fourth_msg: FourthMessage { sums: fourth_msg_sums }, 367 pc_proof: CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?, 368 batch_sizes, 369 }) 370 } 371 } 372 373 impl<E: PairingEngine> ToBytes for Proof<E> { 374 fn write_le<W: Write>(&self, mut w: W) -> io::Result<()> { 375 Self::serialize_compressed(self, &mut w) 376 .map_err(|err| into_io_error(anyhow::Error::from(err).context("could not serialize Proof"))) 377 } 378 } 379 380 impl<E: PairingEngine> FromBytes for Proof<E> { 381 fn read_le<R: Read>(mut r: R) -> io::Result<Self> { 382 Self::deserialize_compressed(&mut r) 383 .map_err(|err| into_io_error(anyhow::Error::from(err).context("could not deserialize Proof"))) 384 } 385 386 fn read_le_unchecked<R: Read>(mut r: R) -> io::Result<Self> { 387 Self::deserialize_compressed_unchecked(&mut r) 388 .map_err(|err| into_io_error(anyhow::Error::from(err).context("could not deserialize Proof"))) 389 } 390 } 391 392 /// Computes the size in bytes of a Varuna proof as produced by 393 /// `Proof::serialize_compressed` without needing to receive the proof itself. 394 /// 395 /// *Arguments*: 396 /// - `batch_sizes`: the batch sizes of the circuits and instances being 397 /// proved. 398 /// - `varuna_version`: the version of Varuna being used 399 /// - `hiding`: indicates whether the proof system is run in ZK mode 400 /// 401 /// *Returns*: 402 /// - `Ok(size)` for `VarunaVersion::V2`, where `size` is the size of the proof 403 /// in bytes. 404 /// - `Err` for `VarunaVersion::V1`. 405 pub fn proof_size<E: PairingEngine>( 406 batch_sizes: &[usize], 407 varuna_version: VarunaVersion, 408 hiding: bool, 409 ) -> Result<usize> { 410 let n_circuits: usize = batch_sizes.len(); 411 let n_instances: usize = batch_sizes.iter().sum(); 412 413 match varuna_version { 414 VarunaVersion::V1 => Err(anyhow!("Proof-size calculation not implemented for Varuna version V1")), 415 VarunaVersion::V2 => { 416 // All fields are serialised in Compressed mode The breakdown is as 417 // follows: 418 // - batch sizes: one `usize` (which is serialised as a `u64`) for each batch 419 // size, plus one `u64` for the number of batches. This contains the size 420 // information for the vectors in all other fields, which are therefore 421 // serialised without their length prefix. 422 // - commitments: 423 // + witness_commitments: n_instances commitments 424 // + mask_poly: 1 byte to encode the enum tag (a bool) plus one commitment if 425 // the variant is Some (if and only if the proof system is run in ZK mode) 426 // + h_0, g_1, g_2, h_2: four commitments 427 // + g_a, g_b, g_c: 3 * n_circuits commitments 428 // - evaluations: 429 // + g_1_eval: one field element 430 // + g_a_evals, g_b_evals, g_c_evals: 3 * n_circuits field elements 431 // - third_msg: 432 // + 3 * n_instances field elements 433 // - fourth_msg: 434 // + 3 * n_circuits field elements 435 // - pc_proof: 436 // + one usize for the size of the vector (which is always 3) 437 // + three of [1 commitment + 1 bool (for the Option tag) + {1 field element 438 // if the variant is Some (if and only if the proof system is run in ZK 439 // mode)}] 440 441 let n_bool = 1; 442 let n_u64 = 1; 443 let n_field_elements = 1 + 6 * n_circuits + 3 * n_instances; 444 let n_commitments = 4 + n_instances + (if hiding { 1 } else { 0 }) + 3 * n_circuits; 445 446 // The next three sizes are const functions 447 let size_bool = size_of::<bool>(); 448 let size_u64 = size_of::<u64>(); 449 450 // The next two can be hard-coded if performance becomes critical 451 // and they are considered fully stable. They are 32 and 48 bytes at 452 // the time of writing, respectively (commitments are affine points 453 // written in compressed form). 454 let size_field_element = E::Fr::one().compressed_size(); 455 let size_commitment = KZGCommitment::<E>::empty().compressed_size(); 456 457 let size_pc_proof = size_u64 + 3 * (size_commitment + 1) + if hiding { size_field_element } else { 0 }; 458 459 Ok(n_bool * size_bool 460 + (n_u64 + batch_sizes.len()) * size_u64 461 + n_field_elements * size_field_element 462 + n_commitments * size_commitment 463 + size_pc_proof) 464 } 465 } 466 } 467 468 #[cfg(test)] 469 mod test { 470 #![allow(non_camel_case_types)] 471 472 use super::*; 473 474 use crate::{ 475 polycommit::{ 476 kzg10::{KZGCommitment, KZGProof}, 477 sonic_pc::BatchProof, 478 }, 479 snark::varuna::prover::MatrixSums, 480 }; 481 use alphavm_curves::{ 482 bls12_377::{Bls12_377, Fr, G1Affine}, 483 AffineCurve, 484 }; 485 use alphavm_utilities::{TestRng, Uniform}; 486 487 const fn modes() -> [(Compress, Validate); 4] { 488 [ 489 (Compress::No, Validate::No), 490 (Compress::Yes, Validate::No), 491 (Compress::No, Validate::Yes), 492 (Compress::Yes, Validate::Yes), 493 ] 494 } 495 496 fn sample_commit() -> KZGCommitment<Bls12_377> { 497 let buf = G1Affine::prime_subgroup_generator().to_bytes_le().unwrap(); 498 FromBytes::read_le(buf.as_slice()).unwrap() 499 } 500 501 fn rand_commitments(j: usize, i: usize, test_with_none: bool) -> Commitments<Bls12_377> { 502 assert!(i > 0); 503 assert!(j > 0); 504 let sample_commit = sample_commit(); 505 let mask_poly = if test_with_none { None } else { Some(sample_commit) }; 506 Commitments { 507 witness_commitments: vec![WitnessCommitments { w: sample_commit }; i * j], 508 mask_poly, 509 h_0: sample_commit, 510 g_1: sample_commit, 511 h_1: sample_commit, 512 g_a_commitments: vec![sample_commit; i], 513 g_b_commitments: vec![sample_commit; i], 514 g_c_commitments: vec![sample_commit; i], 515 h_2: sample_commit, 516 } 517 } 518 519 fn rand_evaluations<F: PrimeField>(rng: &mut TestRng, i: usize) -> Evaluations<F> { 520 Evaluations { 521 g_1_eval: F::rand(rng), 522 g_a_evals: (0..i).map(|_| F::rand(rng)).collect(), 523 g_b_evals: (0..i).map(|_| F::rand(rng)).collect(), 524 g_c_evals: (0..i).map(|_| F::rand(rng)).collect(), 525 } 526 } 527 528 fn rand_sums<F: PrimeField>(rng: &mut TestRng) -> MatrixSums<F> { 529 MatrixSums::<F> { sum_a: F::rand(rng), sum_b: F::rand(rng), sum_c: F::rand(rng) } 530 } 531 532 fn rand_kzg_proof(rng: &mut TestRng, test_with_none: bool) -> KZGProof<Bls12_377> { 533 let random_v = if test_with_none { None } else { Some(Fr::rand(rng)) }; 534 KZGProof::<Bls12_377> { w: G1Affine::prime_subgroup_generator(), random_v } 535 } 536 537 #[test] 538 fn test_serializing_commitments() { 539 for i in 1..11 { 540 for j in 1..11 { 541 let test_with_none = i * j % 2 == 0; 542 let commitments = rand_commitments(j, i, test_with_none); 543 let batch_sizes = vec![j; i]; 544 let combinations = modes(); 545 for (compress, validate) in combinations { 546 let size = Commitments::serialized_size(&commitments, compress); 547 let mut serialized = vec![0; size]; 548 Commitments::serialize_with_mode(&commitments, &mut serialized[..], compress).unwrap(); 549 let de = 550 Commitments::deserialize_with_mode(&batch_sizes, &serialized[..], compress, validate).unwrap(); 551 assert_eq!(commitments, de); 552 } 553 } 554 } 555 } 556 557 #[test] 558 fn test_serializing_evaluations() { 559 let rng = &mut TestRng::default(); 560 561 for i in 1..11 { 562 for j in 1..11 { 563 let evaluations: Evaluations<Fr> = rand_evaluations(rng, i); 564 let batch_sizes = vec![j; i]; 565 let combinations = modes(); 566 for (compress, validate) in combinations { 567 let size = Evaluations::serialized_size(&evaluations, compress); 568 let mut serialized = vec![0; size]; 569 Evaluations::serialize_with_mode(&evaluations, &mut serialized[..], compress).unwrap(); 570 let de = 571 Evaluations::deserialize_with_mode(&batch_sizes, &serialized[..], compress, validate).unwrap(); 572 assert_eq!(evaluations, de); 573 } 574 } 575 } 576 } 577 578 #[test] 579 fn test_serializing_proof() { 580 let rng = &mut alphavm_utilities::rand::TestRng::default(); 581 582 for i in 1..11 { 583 for j in 1..11 { 584 let test_with_none = i * j % 2 == 0; 585 let batch_sizes = vec![j; i]; 586 let commitments = rand_commitments(j, i, test_with_none); 587 let evaluations: Evaluations<Fr> = rand_evaluations(rng, i); 588 let third_msg = ThirdMessage::<Fr> { sums: vec![vec![rand_sums(rng); j]; i] }; 589 let fourth_msg = FourthMessage::<Fr> { sums: vec![rand_sums(rng); i] }; 590 let pc_proof = 591 sonic_pc::BatchLCProof { proof: BatchProof(vec![rand_kzg_proof(rng, test_with_none); j]) }; 592 let proof = Proof { batch_sizes, commitments, evaluations, third_msg, fourth_msg, pc_proof }; 593 let combinations = modes(); 594 for (compress, validate) in combinations { 595 let size = Proof::serialized_size(&proof, compress); 596 let mut serialized = vec![0; size]; 597 Proof::serialize_with_mode(&proof, &mut serialized[..], compress).unwrap(); 598 let de = Proof::deserialize_with_mode(&serialized[..], compress, validate).unwrap(); 599 assert_eq!(proof, de); 600 } 601 } 602 } 603 } 604 }