mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-09 14:47:56 -05:00
chore: make NoiseSimulationLwe/NoiseSimulationGlwe properly private
- this avoids submodules of the noise_simulation module to be able to partially update an output - switch the NEG_INFINITY default value for Variance to NAN, NAN will fail all comparisons and absorb all computations which is a nice way to propagate an undefined noise value in our case
This commit is contained in:
@@ -81,11 +81,11 @@ impl AllocateLweKeyswitchResult for NoiseSimulationLweKeyswitchKey {
|
||||
&self,
|
||||
_side_resources: &mut Self::SideResources,
|
||||
) -> Self::Output {
|
||||
Self::Output {
|
||||
lwe_dimension: self.output_lwe_dimension,
|
||||
variance: Variance(f64::NEG_INFINITY),
|
||||
modulus: self.output_modulus,
|
||||
}
|
||||
Self::Output::new(
|
||||
self.output_lwe_dimension,
|
||||
Variance(f64::NAN),
|
||||
self.output_modulus,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ impl LweKeyswitch<NoiseSimulationLwe, NoiseSimulationLwe> for NoiseSimulationLwe
|
||||
output: &mut NoiseSimulationLwe,
|
||||
_side_resources: &mut Self::SideResources,
|
||||
) {
|
||||
assert_eq!(input.lwe_dimension, self.input_lwe_dimension);
|
||||
assert_eq!(input.lwe_dimension(), self.input_lwe_dimension);
|
||||
|
||||
let ks_additive_var = match self.noise_distribution {
|
||||
DynamicDistribution::Gaussian(_) => {
|
||||
@@ -107,7 +107,7 @@ impl LweKeyswitch<NoiseSimulationLwe, NoiseSimulationLwe> for NoiseSimulationLwe
|
||||
self.output_lwe_dimension,
|
||||
self.decomposition_base_log,
|
||||
self.decomposition_level_count,
|
||||
input.modulus.as_f64(),
|
||||
input.modulus().as_f64(),
|
||||
self.output_modulus.as_f64(),
|
||||
)
|
||||
}
|
||||
@@ -117,7 +117,7 @@ impl LweKeyswitch<NoiseSimulationLwe, NoiseSimulationLwe> for NoiseSimulationLwe
|
||||
self.output_lwe_dimension,
|
||||
self.decomposition_base_log,
|
||||
self.decomposition_level_count,
|
||||
input.modulus.as_f64(),
|
||||
input.modulus().as_f64(),
|
||||
self.output_modulus.as_f64(),
|
||||
)
|
||||
}
|
||||
@@ -125,7 +125,7 @@ impl LweKeyswitch<NoiseSimulationLwe, NoiseSimulationLwe> for NoiseSimulationLwe
|
||||
|
||||
*output = NoiseSimulationLwe::new(
|
||||
self.output_lwe_dimension,
|
||||
Variance(input.variance.0 + ks_additive_var.0),
|
||||
Variance(input.variance().0 + ks_additive_var.0),
|
||||
self.output_modulus,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ impl LweMultiBitFftBlindRotate<NoiseSimulationLwe, NoiseSimulationLwe, NoiseSimu
|
||||
*output = NoiseSimulationLwe::new(
|
||||
output_lwe_dimension,
|
||||
Variance(accumulator.variance_per_occupied_slot().0 + br_additive_variance.0),
|
||||
accumulator.modulus,
|
||||
accumulator.modulus(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,12 +116,12 @@ impl AllocateLwePackingKeyswitchResult for NoiseSimulationLwePackingKeyswitchKey
|
||||
&self,
|
||||
_side_resources: &mut Self::SideResources,
|
||||
) -> Self::Output {
|
||||
Self::Output {
|
||||
glwe_dimension: self.output_glwe_size().to_glwe_dimension(),
|
||||
polynomial_size: self.output_polynomial_size(),
|
||||
variance_per_occupied_slot: Variance(f64::NEG_INFINITY),
|
||||
modulus: self.modulus,
|
||||
}
|
||||
Self::Output::new(
|
||||
self.output_glwe_size().to_glwe_dimension(),
|
||||
self.output_polynomial_size(),
|
||||
Variance(f64::NAN),
|
||||
self.modulus,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,10 +170,11 @@ impl LwePackingKeyswitch<[&NoiseSimulationLwe], NoiseSimulationGlwe>
|
||||
}
|
||||
};
|
||||
|
||||
output.glwe_dimension = self.output_glwe_size().to_glwe_dimension();
|
||||
output.polynomial_size = self.output_polynomial_size();
|
||||
output.variance_per_occupied_slot =
|
||||
Variance(input.variance().0 + packing_ks_additive_var.0);
|
||||
output.modulus = self.modulus();
|
||||
*output = NoiseSimulationGlwe::new(
|
||||
self.output_glwe_size().to_glwe_dimension(),
|
||||
self.output_polynomial_size(),
|
||||
Variance(input.variance().0 + packing_ks_additive_var.0),
|
||||
self.modulus(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,10 +154,11 @@ impl LweClassicFftBootstrap<NoiseSimulationLwe, NoiseSimulationLwe, NoiseSimulat
|
||||
.to_glwe_dimension()
|
||||
.to_equivalent_lwe_dimension(self.output_polynomial_size());
|
||||
|
||||
output.lwe_dimension = output_lwe_dimension;
|
||||
output.variance =
|
||||
Variance(accumulator.variance_per_occupied_slot().0 + br_additive_variance.0);
|
||||
output.modulus = accumulator.modulus;
|
||||
*output = NoiseSimulationLwe::new(
|
||||
output_lwe_dimension,
|
||||
Variance(accumulator.variance_per_occupied_slot().0 + br_additive_variance.0),
|
||||
accumulator.modulus(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,9 +302,10 @@ impl LweClassicFft128Bootstrap<NoiseSimulationLwe, NoiseSimulationLwe, NoiseSimu
|
||||
.to_glwe_dimension()
|
||||
.to_equivalent_lwe_dimension(self.output_polynomial_size());
|
||||
|
||||
output.lwe_dimension = output_lwe_dimension;
|
||||
output.variance =
|
||||
Variance(accumulator.variance_per_occupied_slot().0 + br_additive_variance.0);
|
||||
output.modulus = accumulator.modulus;
|
||||
*output = NoiseSimulationLwe::new(
|
||||
output_lwe_dimension,
|
||||
Variance(accumulator.variance_per_occupied_slot().0 + br_additive_variance.0),
|
||||
accumulator.modulus(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,146 +70,158 @@ impl NoiseSimulationModulus {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct NoiseSimulationLwe {
|
||||
lwe_dimension: LweDimension,
|
||||
variance: Variance,
|
||||
modulus: NoiseSimulationModulus,
|
||||
}
|
||||
// Avoids fields to be public/accessible in the noise_simulation module to make sure all functions
|
||||
// use constructors
|
||||
mod simulation_ciphertexts {
|
||||
use super::*;
|
||||
|
||||
impl NoiseSimulationLwe {
|
||||
pub fn new(
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct NoiseSimulationLwe {
|
||||
lwe_dimension: LweDimension,
|
||||
variance: Variance,
|
||||
modulus: NoiseSimulationModulus,
|
||||
) -> Self {
|
||||
Self {
|
||||
lwe_dimension,
|
||||
variance,
|
||||
modulus,
|
||||
}
|
||||
|
||||
impl NoiseSimulationLwe {
|
||||
pub fn new(
|
||||
lwe_dimension: LweDimension,
|
||||
variance: Variance,
|
||||
modulus: NoiseSimulationModulus,
|
||||
) -> Self {
|
||||
Self {
|
||||
lwe_dimension,
|
||||
variance,
|
||||
modulus,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lwe_dimension(&self) -> LweDimension {
|
||||
self.lwe_dimension
|
||||
}
|
||||
|
||||
pub fn variance(&self) -> Variance {
|
||||
self.variance
|
||||
}
|
||||
|
||||
pub fn modulus(&self) -> NoiseSimulationModulus {
|
||||
self.modulus
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lwe_dimension(&self) -> LweDimension {
|
||||
self.lwe_dimension
|
||||
impl<Scalar: CastInto<f64>> ScalarMul<Scalar> for NoiseSimulationLwe {
|
||||
type Output = Self;
|
||||
type SideResources = ();
|
||||
|
||||
fn scalar_mul(
|
||||
&self,
|
||||
rhs: Scalar,
|
||||
side_resources: &mut Self::SideResources,
|
||||
) -> Self::Output {
|
||||
let mut output = *self;
|
||||
output.scalar_mul_assign(rhs, side_resources);
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
pub fn variance(&self) -> Variance {
|
||||
self.variance
|
||||
impl<Scalar: CastInto<f64>> ScalarMulAssign<Scalar> for NoiseSimulationLwe {
|
||||
type SideResources = ();
|
||||
|
||||
fn scalar_mul_assign(&mut self, rhs: Scalar, _side_resources: &mut Self::SideResources) {
|
||||
let rhs: f64 = rhs.cast_into();
|
||||
self.variance.0 *= rhs.powi(2);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modulus(&self) -> NoiseSimulationModulus {
|
||||
self.modulus
|
||||
}
|
||||
}
|
||||
|
||||
impl<Scalar: CastInto<f64>> ScalarMul<Scalar> for NoiseSimulationLwe {
|
||||
type Output = Self;
|
||||
type SideResources = ();
|
||||
|
||||
fn scalar_mul(&self, rhs: Scalar, side_resources: &mut Self::SideResources) -> Self::Output {
|
||||
let mut output = *self;
|
||||
output.scalar_mul_assign(rhs, side_resources);
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
impl<Scalar: CastInto<f64>> ScalarMulAssign<Scalar> for NoiseSimulationLwe {
|
||||
type SideResources = ();
|
||||
|
||||
fn scalar_mul_assign(&mut self, rhs: Scalar, _side_resources: &mut Self::SideResources) {
|
||||
let rhs: f64 = rhs.cast_into();
|
||||
self.variance.0 *= rhs.powi(2);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct NoiseSimulationGlwe {
|
||||
glwe_dimension: GlweDimension,
|
||||
polynomial_size: PolynomialSize,
|
||||
variance_per_occupied_slot: Variance,
|
||||
modulus: NoiseSimulationModulus,
|
||||
}
|
||||
|
||||
impl NoiseSimulationGlwe {
|
||||
pub fn new(
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct NoiseSimulationGlwe {
|
||||
glwe_dimension: GlweDimension,
|
||||
polynomial_size: PolynomialSize,
|
||||
variance_per_occupied_slot: Variance,
|
||||
modulus: NoiseSimulationModulus,
|
||||
) -> Self {
|
||||
Self {
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
variance_per_occupied_slot,
|
||||
modulus,
|
||||
}
|
||||
|
||||
impl NoiseSimulationGlwe {
|
||||
pub fn new(
|
||||
glwe_dimension: GlweDimension,
|
||||
polynomial_size: PolynomialSize,
|
||||
variance_per_occupied_slot: Variance,
|
||||
modulus: NoiseSimulationModulus,
|
||||
) -> Self {
|
||||
Self {
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
variance_per_occupied_slot,
|
||||
modulus,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_lwe(self) -> NoiseSimulationLwe {
|
||||
let lwe_dimension = self
|
||||
.glwe_dimension()
|
||||
.to_equivalent_lwe_dimension(self.polynomial_size());
|
||||
NoiseSimulationLwe {
|
||||
lwe_dimension,
|
||||
variance: self.variance_per_occupied_slot(),
|
||||
modulus: self.modulus(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn glwe_dimension(&self) -> GlweDimension {
|
||||
self.glwe_dimension
|
||||
}
|
||||
|
||||
pub fn polynomial_size(&self) -> PolynomialSize {
|
||||
self.polynomial_size
|
||||
}
|
||||
|
||||
pub fn variance_per_occupied_slot(&self) -> Variance {
|
||||
self.variance_per_occupied_slot
|
||||
}
|
||||
|
||||
pub fn modulus(&self) -> NoiseSimulationModulus {
|
||||
self.modulus
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_lwe(self) -> NoiseSimulationLwe {
|
||||
let lwe_dimension = self
|
||||
.glwe_dimension()
|
||||
.to_equivalent_lwe_dimension(self.polynomial_size());
|
||||
NoiseSimulationLwe {
|
||||
lwe_dimension,
|
||||
variance: self.variance_per_occupied_slot(),
|
||||
modulus: self.modulus(),
|
||||
impl AllocateLweBootstrapResult for NoiseSimulationGlwe {
|
||||
type Output = NoiseSimulationLwe;
|
||||
type SideResources = ();
|
||||
|
||||
fn allocate_lwe_bootstrap_result(
|
||||
&self,
|
||||
_side_resources: &mut Self::SideResources,
|
||||
) -> Self::Output {
|
||||
let lwe_dimension = self
|
||||
.glwe_dimension()
|
||||
.to_equivalent_lwe_dimension(self.polynomial_size());
|
||||
|
||||
Self::Output {
|
||||
lwe_dimension,
|
||||
variance: self.variance_per_occupied_slot(),
|
||||
modulus: self.modulus(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn glwe_dimension(&self) -> GlweDimension {
|
||||
self.glwe_dimension
|
||||
}
|
||||
impl AllocateLweMultiBitBlindRotateResult for NoiseSimulationGlwe {
|
||||
type Output = NoiseSimulationLwe;
|
||||
type SideResources = ();
|
||||
|
||||
pub fn polynomial_size(&self) -> PolynomialSize {
|
||||
self.polynomial_size
|
||||
}
|
||||
fn allocate_lwe_multi_bit_blind_rotate_result(
|
||||
&self,
|
||||
_side_resources: &mut Self::SideResources,
|
||||
) -> Self::Output {
|
||||
let lwe_dimension = self
|
||||
.glwe_dimension()
|
||||
.to_equivalent_lwe_dimension(self.polynomial_size());
|
||||
|
||||
pub fn variance_per_occupied_slot(&self) -> Variance {
|
||||
self.variance_per_occupied_slot
|
||||
}
|
||||
|
||||
pub fn modulus(&self) -> NoiseSimulationModulus {
|
||||
self.modulus
|
||||
}
|
||||
}
|
||||
|
||||
impl AllocateLweBootstrapResult for NoiseSimulationGlwe {
|
||||
type Output = NoiseSimulationLwe;
|
||||
type SideResources = ();
|
||||
|
||||
fn allocate_lwe_bootstrap_result(
|
||||
&self,
|
||||
_side_resources: &mut Self::SideResources,
|
||||
) -> Self::Output {
|
||||
let lwe_dimension = self
|
||||
.glwe_dimension()
|
||||
.to_equivalent_lwe_dimension(self.polynomial_size());
|
||||
|
||||
Self::Output {
|
||||
lwe_dimension,
|
||||
variance: self.variance_per_occupied_slot(),
|
||||
modulus: self.modulus(),
|
||||
Self::Output {
|
||||
lwe_dimension,
|
||||
variance: self.variance_per_occupied_slot(),
|
||||
modulus: self.modulus(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AllocateLweMultiBitBlindRotateResult for NoiseSimulationGlwe {
|
||||
type Output = NoiseSimulationLwe;
|
||||
type SideResources = ();
|
||||
|
||||
fn allocate_lwe_multi_bit_blind_rotate_result(
|
||||
&self,
|
||||
_side_resources: &mut Self::SideResources,
|
||||
) -> Self::Output {
|
||||
let lwe_dimension = self
|
||||
.glwe_dimension()
|
||||
.to_equivalent_lwe_dimension(self.polynomial_size());
|
||||
|
||||
Self::Output {
|
||||
lwe_dimension,
|
||||
variance: self.variance_per_occupied_slot(),
|
||||
modulus: self.modulus(),
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use simulation_ciphertexts::{NoiseSimulationGlwe, NoiseSimulationLwe};
|
||||
|
||||
@@ -20,11 +20,11 @@ impl AllocateStandardModSwitchResult for NoiseSimulationLwe {
|
||||
&self,
|
||||
_side_resources: &mut Self::SideResources,
|
||||
) -> Self::Output {
|
||||
Self {
|
||||
lwe_dimension: self.lwe_dimension,
|
||||
variance: Variance(f64::INFINITY),
|
||||
modulus: self.modulus(),
|
||||
}
|
||||
Self::Output::new(
|
||||
self.lwe_dimension(),
|
||||
Variance(f64::INFINITY),
|
||||
self.modulus(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,18 +46,18 @@ impl StandardModSwitch<Self> for NoiseSimulationLwe {
|
||||
assert!(output_modulus_f64 < input_modulus_f64);
|
||||
|
||||
let mod_switch_additive_variance = modulus_switch_additive_variance(
|
||||
self.lwe_dimension,
|
||||
self.lwe_dimension(),
|
||||
input_modulus_f64,
|
||||
output_modulus_f64,
|
||||
);
|
||||
|
||||
*output = Self::new(
|
||||
self.lwe_dimension,
|
||||
Variance(self.variance.0 + mod_switch_additive_variance.0),
|
||||
self.lwe_dimension(),
|
||||
Variance(self.variance().0 + mod_switch_additive_variance.0),
|
||||
// Mod switched but the noise is to be interpreted with respect to the input modulus,
|
||||
// as strictly the operation adding the noise is the rounding under the
|
||||
// original modulus
|
||||
self.modulus,
|
||||
self.modulus(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -70,11 +70,11 @@ impl AllocateMultiBitModSwitchResult for NoiseSimulationLwe {
|
||||
&self,
|
||||
_side_resources: &mut Self::SideResources,
|
||||
) -> Self::Output {
|
||||
Self {
|
||||
lwe_dimension: self.lwe_dimension,
|
||||
variance: Variance(f64::INFINITY),
|
||||
modulus: self.modulus(),
|
||||
}
|
||||
Self::Output::new(
|
||||
self.lwe_dimension(),
|
||||
Variance(f64::INFINITY),
|
||||
self.modulus(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,19 +98,19 @@ impl MultiBitModSwitch<Self> for NoiseSimulationLwe {
|
||||
assert!(output_modulus_f64 < input_modulus_f64);
|
||||
|
||||
let mod_switch_additive_variance = multi_bit_modulus_switch_additive_variance(
|
||||
self.lwe_dimension,
|
||||
self.lwe_dimension(),
|
||||
grouping_factor_f64,
|
||||
input_modulus_f64,
|
||||
output_modulus_f64,
|
||||
);
|
||||
|
||||
*output = Self::new(
|
||||
self.lwe_dimension,
|
||||
Variance(self.variance.0 + mod_switch_additive_variance.0),
|
||||
self.lwe_dimension(),
|
||||
Variance(self.variance().0 + mod_switch_additive_variance.0),
|
||||
// Mod switched but the noise is to be interpreted with respect to the input modulus,
|
||||
// as strictly the operation adding the noise is the rounding under the
|
||||
// original modulus
|
||||
self.modulus,
|
||||
self.modulus(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -123,11 +123,7 @@ impl AllocateCenteredBinaryShiftedStandardModSwitchResult for NoiseSimulationLwe
|
||||
&self,
|
||||
_side_resources: &mut Self::SideResources,
|
||||
) -> Self::Output {
|
||||
Self::new(
|
||||
self.lwe_dimension(),
|
||||
Variance(f64::NEG_INFINITY),
|
||||
self.modulus(),
|
||||
)
|
||||
Self::new(self.lwe_dimension(), Variance(f64::NAN), self.modulus())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,18 +145,18 @@ impl CenteredBinaryShiftedStandardModSwitch<Self> for NoiseSimulationLwe {
|
||||
assert!(output_modulus_f64 < input_modulus_f64);
|
||||
|
||||
let mod_switch_additive_variance = centered_binary_shifted_modulus_switch_additive_variance(
|
||||
self.lwe_dimension,
|
||||
self.lwe_dimension(),
|
||||
input_modulus_f64,
|
||||
output_modulus_f64,
|
||||
);
|
||||
|
||||
*output = Self::new(
|
||||
self.lwe_dimension,
|
||||
Variance(self.variance.0 + mod_switch_additive_variance.0),
|
||||
self.lwe_dimension(),
|
||||
Variance(self.variance().0 + mod_switch_additive_variance.0),
|
||||
// Mod switched but the noise is to be interpreted with respect to the input modulus,
|
||||
// as strictly the operation adding the noise is the rounding under the
|
||||
// original modulus
|
||||
self.modulus,
|
||||
self.modulus(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -939,11 +939,8 @@ impl AllocateDriftTechniqueStandardModSwitchResult for NoiseSimulationDriftTechn
|
||||
&self,
|
||||
side_resources: &mut Self::SideResources,
|
||||
) -> (Self::AfterDriftOutput, Self::AfterMsOutput) {
|
||||
let after_drift = NoiseSimulationLwe::new(
|
||||
self.lwe_dimension,
|
||||
Variance(f64::NEG_INFINITY),
|
||||
self.modulus,
|
||||
);
|
||||
let after_drift =
|
||||
NoiseSimulationLwe::new(self.lwe_dimension, Variance(f64::NAN), self.modulus);
|
||||
let after_ms = after_drift.allocate_standard_mod_switch_result(side_resources);
|
||||
(after_drift, after_ms)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user