diff --git a/tfhe/src/zk.rs b/tfhe/src/zk.rs index 34347c8374..57538a1ae2 100644 --- a/tfhe/src/zk.rs +++ b/tfhe/src/zk.rs @@ -1,6 +1,8 @@ use crate::core_crypto::commons::math::random::BoundedDistribution; use crate::core_crypto::prelude::*; use crate::named::Named; +use crate::prelude::ParameterSetConformant; +use crate::shortint::parameters::CompactPublicKeyEncryptionParameters; use rand_core::RngCore; use std::cmp::Ordering; use std::collections::Bound; @@ -16,6 +18,14 @@ impl Named for CompactPkeProof { const NAME: &'static str = "zk::CompactPkeProof"; } +impl ParameterSetConformant for CompactPkeProof { + type ParameterSet = (); + + fn is_conformant(&self, _parameter_set: &Self::ParameterSet) -> bool { + self.is_usable() + } +} + pub type CompactPkePublicParams = tfhe_zk_pok::proofs::pke::PublicParams; pub type SerializableCompactPkePublicParams = tfhe_zk_pok::serialization::SerializablePKEv1PublicParams; @@ -24,6 +34,65 @@ impl Named for CompactPkePublicParams { const NAME: &'static str = "zk::CompactPkePublicParams"; } +pub struct CompactPkePublicParamsConformanceParams { + lwe_dim: LweDimension, + max_num_message: usize, + noise_bound: u64, + ciphertext_modulus: u64, + plaintext_modulus: u64, + msbs_zero_padding_bit_count: ZkMSBZeroPaddingBitCount, +} + +impl CompactPkePublicParamsConformanceParams { + pub fn new>( + value: P, + max_num_message: usize, + ) -> Result + where + E: Into, + { + let params: CompactPublicKeyEncryptionParameters = + value.try_into().map_err(|e| e.into())?; + + let mut plaintext_modulus = (params.message_modulus.0 * params.carry_modulus.0) as u64; + // Add 1 bit of modulus for the padding bit + plaintext_modulus *= 2; + + let (lwe_dim, max_num_message, noise_bound, ciphertext_modulus, plaintext_modulus) = + CompactPkeCrs::prepare_crs_parameters( + params.encryption_lwe_dimension, + max_num_message, + params.encryption_noise_distribution, + params.ciphertext_modulus, + plaintext_modulus, + )?; + + Ok(Self { + lwe_dim, + max_num_message, + noise_bound, + ciphertext_modulus, + plaintext_modulus, + // CRS created from shortint params have 1 MSB 0bit + msbs_zero_padding_bit_count: ZkMSBZeroPaddingBitCount(1), + }) + } +} + +impl ParameterSetConformant for CompactPkePublicParams { + type ParameterSet = CompactPkePublicParamsConformanceParams; + + fn is_conformant(&self, parameter_set: &Self::ParameterSet) -> bool { + self.d == parameter_set.lwe_dim.0 + && self.k == parameter_set.max_num_message + && self.b == parameter_set.noise_bound + && self.q == parameter_set.ciphertext_modulus + && self.t == parameter_set.plaintext_modulus + && self.msbs_zero_padding_bit_count == parameter_set.msbs_zero_padding_bit_count.0 + && self.is_usable() + } +} + // If we call `CompactPkePublicParams::compress` we end up with a // `SerializableCompactPkePublicParams` that should also impl Named to be serializable with // `safe_serialization`. Since the `CompactPkePublicParams` is transformed into a