proof_of_sql/proof_primitive/dory/
public_parameters.rsuse super::{G1Affine, G2Affine};
use alloc::vec::Vec;
use ark_ff::UniformRand;
use ark_serialize::{
CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Valid, Validate,
};
use ark_std::rand::{CryptoRng, Rng};
use core::iter;
#[cfg(feature = "std")]
use std::{
fs::File,
io::{BufReader, BufWriter, Error, ErrorKind, Read, Write},
path::Path,
};
pub struct PublicParameters {
pub(super) Gamma_1: Vec<G1Affine>,
pub(super) Gamma_2: Vec<G2Affine>,
pub(super) H_1: G1Affine,
pub(super) H_2: G2Affine,
pub(super) Gamma_2_fin: G2Affine,
pub(super) max_nu: usize,
}
impl PublicParameters {
pub fn rand<R: CryptoRng + Rng + ?Sized>(max_nu: usize, rng: &mut R) -> Self {
Self::rand_impl(max_nu, rng)
}
pub fn test_rand<R: Rng + ?Sized>(max_nu: usize, rng: &mut R) -> Self {
Self::rand_impl(max_nu, rng)
}
fn rand_impl<R: Rng + ?Sized>(max_nu: usize, rng: &mut R) -> Self {
let (H_1, H_2) = (G1Affine::rand(rng), G2Affine::rand(rng));
let Gamma_2_fin = G2Affine::rand(rng);
let (Gamma_1, Gamma_2) = iter::repeat_with(|| (G1Affine::rand(rng), G2Affine::rand(rng)))
.take(1 << max_nu)
.unzip();
Self {
Gamma_1,
Gamma_2,
H_1,
H_2,
Gamma_2_fin,
max_nu,
}
}
#[cfg(feature = "std")]
pub fn save_to_file(&self, path: &Path) -> std::io::Result<()> {
let file = File::create(path)?;
let mut writer = BufWriter::new(file);
let mut serialized_data = Vec::new();
self.serialize_with_mode(&mut serialized_data, Compress::No)
.map_err(|e| Error::new(ErrorKind::Other, format!("{e}")))?;
writer.write_all(&serialized_data)?;
writer.flush()?;
Ok(())
}
#[cfg(feature = "std")]
pub fn load_from_file(path: &Path) -> std::io::Result<Self> {
let file = File::open(path)?;
let mut reader = BufReader::new(file);
let mut serialized_data = Vec::new();
reader.read_to_end(&mut serialized_data)?;
PublicParameters::deserialize_with_mode(
&mut &serialized_data[..],
Compress::No,
Validate::Yes,
)
.map_err(|e| Error::new(ErrorKind::Other, format!("{e}")))
}
}
impl CanonicalSerialize for PublicParameters {
fn serialize_with_mode<W: ark_serialize::Write>(
&self,
mut writer: W,
compress: ark_serialize::Compress,
) -> Result<(), SerializationError> {
(self.max_nu as u64).serialize_with_mode(&mut writer, compress)?;
self.Gamma_1
.iter()
.try_for_each(|g1| g1.serialize_with_mode(&mut writer, compress))?;
self.Gamma_2
.iter()
.try_for_each(|g2| g2.serialize_with_mode(&mut writer, compress))?;
self.H_1.serialize_with_mode(&mut writer, compress)?;
self.H_2.serialize_with_mode(&mut writer, compress)?;
self.Gamma_2_fin
.serialize_with_mode(&mut writer, compress)?;
Ok(())
}
fn serialized_size(&self, compress: ark_serialize::Compress) -> usize {
let max_nu_size = 8;
let gamma_1_size: usize = self
.Gamma_1
.iter()
.map(|g1| g1.serialized_size(compress))
.sum();
let gamma_2_size: usize = self
.Gamma_2
.iter()
.map(|g2| g2.serialized_size(compress))
.sum();
let h1_size = self.H_1.serialized_size(compress);
let h2_size = self.H_2.serialized_size(compress);
let gamma_2_fin_size = self.Gamma_2_fin.serialized_size(compress);
max_nu_size + gamma_1_size + gamma_2_size + h1_size + h2_size + gamma_2_fin_size
}
}
impl CanonicalDeserialize for PublicParameters {
fn deserialize_with_mode<R: ark_serialize::Read>(
mut reader: R,
compress: ark_serialize::Compress,
validate: ark_serialize::Validate,
) -> Result<Self, SerializationError> {
let max_nu_u64 = u64::deserialize_with_mode(&mut reader, compress, validate)?;
let max_nu: usize = max_nu_u64
.try_into()
.map_err(|_| SerializationError::InvalidData)?;
let Gamma_1: Vec<G1Affine> = (0..(1 << max_nu))
.map(|_| G1Affine::deserialize_with_mode(&mut reader, compress, validate))
.collect::<Result<_, _>>()?;
let Gamma_2: Vec<G2Affine> = (0..(1 << max_nu))
.map(|_| G2Affine::deserialize_with_mode(&mut reader, compress, validate))
.collect::<Result<_, _>>()?;
let H_1 = G1Affine::deserialize_with_mode(&mut reader, compress, validate)?;
let H_2 = G2Affine::deserialize_with_mode(&mut reader, compress, validate)?;
let Gamma_2_fin = G2Affine::deserialize_with_mode(&mut reader, compress, validate)?;
Ok(Self {
Gamma_1,
Gamma_2,
H_1,
H_2,
Gamma_2_fin,
max_nu,
})
}
}
impl Valid for PublicParameters {
fn check(&self) -> Result<(), SerializationError> {
self.Gamma_1
.iter()
.try_for_each(ark_serialize::Valid::check)?;
self.Gamma_2
.iter()
.try_for_each(ark_serialize::Valid::check)?;
self.H_1.check()?;
self.H_2.check()?;
self.Gamma_2_fin.check()?;
Ok(())
}
}
#[cfg(test)]
#[cfg(feature = "std")]
mod tests {
use super::*;
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_std::rand::thread_rng;
use std::io::Cursor;
#[test]
fn we_can_serialize_and_deserialize_round_trip() {
let mut rng = thread_rng();
let original_params = PublicParameters::rand(2, &mut rng);
let mut serialized_data = Vec::new();
original_params
.serialize_with_mode(&mut serialized_data, ark_serialize::Compress::No)
.expect("Failed to serialize PublicParameters");
let mut reader = Cursor::new(serialized_data);
let deserialized_params = PublicParameters::deserialize_with_mode(
&mut reader,
ark_serialize::Compress::No,
ark_serialize::Validate::Yes,
)
.expect("Failed to deserialize PublicParameters");
assert_eq!(original_params.Gamma_1, deserialized_params.Gamma_1);
assert_eq!(original_params.Gamma_2, deserialized_params.Gamma_2);
assert_eq!(original_params.H_1, deserialized_params.H_1);
assert_eq!(original_params.H_2, deserialized_params.H_2);
assert_eq!(original_params.Gamma_2_fin, deserialized_params.Gamma_2_fin);
assert_eq!(original_params.max_nu, deserialized_params.max_nu);
deserialized_params
.check()
.expect("Deserialized parameters are not valid");
}
#[test]
fn we_can_read_and_write_a_file_round_trip() {
let nu_values = vec![1, 2, 4];
for &nu in &nu_values {
println!("\nTesting with nu = {nu}");
let start_time = std::time::Instant::now();
let mut rng = thread_rng();
let original_params = PublicParameters::rand(nu, &mut rng);
let file_name = format!("public_params_{nu}.bin");
let file_path = Path::new(&file_name);
original_params
.save_to_file(file_path)
.expect("Failed to save PublicParameters to file");
let loaded_params = PublicParameters::load_from_file(file_path)
.expect("Failed to load PublicParameters from file");
assert_eq!(original_params.Gamma_1, loaded_params.Gamma_1);
assert_eq!(original_params.Gamma_2, loaded_params.Gamma_2);
assert_eq!(original_params.H_1, loaded_params.H_1);
assert_eq!(original_params.H_2, loaded_params.H_2);
assert_eq!(original_params.Gamma_2_fin, loaded_params.Gamma_2_fin);
assert_eq!(original_params.max_nu, loaded_params.max_nu);
let metadata = std::fs::metadata(file_path).expect("Failed to get file metadata");
let file_size = metadata.len(); println!("File size for nu = {nu}: {file_size} bytes");
let elapsed_time = start_time.elapsed();
println!("Time taken for nu = {nu}: {elapsed_time:?}");
std::fs::remove_file(file_path).expect("Failed to remove test file");
}
}
}