mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-09 14:47:56 -05:00
refactor(tfhe): transition GlweSecretKey
- serialization work still pending
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
use crate::core_crypto::commons::crypto::secret::generators::SecretRandomGenerator;
|
||||
use crate::core_crypto::commons::math::random::{
|
||||
ByteRandomGenerator, RandomGenerable, UniformBinary,
|
||||
};
|
||||
use crate::core_crypto::commons::numeric::Numeric;
|
||||
use crate::core_crypto::commons::traits::ContainerMut;
|
||||
use crate::core_crypto::entities::glwe_secret_key::{GlweSecretKey, GlweSecretKeyBase};
|
||||
use crate::core_crypto::specification::parameters::{GlweDimension, PolynomialSize};
|
||||
|
||||
pub fn allocate_and_generate_new_binary_glwe_secret_key<Scalar, Gen>(
|
||||
glwe_dimension: GlweDimension,
|
||||
polynomial_size: PolynomialSize,
|
||||
generator: &mut SecretRandomGenerator<Gen>,
|
||||
) -> GlweSecretKey<Scalar>
|
||||
where
|
||||
Scalar: RandomGenerable<UniformBinary> + Numeric,
|
||||
Gen: ByteRandomGenerator,
|
||||
{
|
||||
let mut glwe_secret_key =
|
||||
GlweSecretKey::from_container(vec![Scalar::ZERO; glwe_dimension.0], polynomial_size);
|
||||
|
||||
generate_binary_glwe_secret_key(&mut glwe_secret_key, generator);
|
||||
|
||||
glwe_secret_key
|
||||
}
|
||||
|
||||
pub fn generate_binary_glwe_secret_key<Scalar, InCont, Gen>(
|
||||
glwe_secret_key: &mut GlweSecretKeyBase<InCont>,
|
||||
generator: &mut SecretRandomGenerator<Gen>,
|
||||
) where
|
||||
Scalar: RandomGenerable<UniformBinary>,
|
||||
InCont: ContainerMut<Element = Scalar>,
|
||||
Gen: ByteRandomGenerator,
|
||||
{
|
||||
generator.fill_slice_with_random_uniform_binary(glwe_secret_key.as_mut())
|
||||
}
|
||||
34
tfhe/src/core_crypto/algorithms/lwe_secret_key_generation.rs
Normal file
34
tfhe/src/core_crypto/algorithms/lwe_secret_key_generation.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use crate::core_crypto::commons::crypto::secret::generators::SecretRandomGenerator;
|
||||
use crate::core_crypto::commons::math::random::{
|
||||
ByteRandomGenerator, RandomGenerable, UniformBinary,
|
||||
};
|
||||
use crate::core_crypto::commons::numeric::Numeric;
|
||||
use crate::core_crypto::commons::traits::ContainerMut;
|
||||
use crate::core_crypto::entities::lwe_secret_key::{LweSecretKey, LweSecretKeyBase};
|
||||
use crate::core_crypto::specification::parameters::LweDimension;
|
||||
|
||||
pub fn allocate_and_generate_new_binary_lwe_secret_key<Scalar, Gen>(
|
||||
lwe_dimension: LweDimension,
|
||||
generator: &mut SecretRandomGenerator<Gen>,
|
||||
) -> LweSecretKey<Scalar>
|
||||
where
|
||||
Scalar: RandomGenerable<UniformBinary> + Numeric,
|
||||
Gen: ByteRandomGenerator,
|
||||
{
|
||||
let mut lwe_secret_key = LweSecretKey::from_container(vec![Scalar::ZERO; lwe_dimension.0]);
|
||||
|
||||
generate_binary_lwe_secret_key(&mut lwe_secret_key, generator);
|
||||
|
||||
lwe_secret_key
|
||||
}
|
||||
|
||||
pub fn generate_binary_lwe_secret_key<Scalar, InCont, Gen>(
|
||||
lwe_secret_key: &mut LweSecretKeyBase<InCont>,
|
||||
generator: &mut SecretRandomGenerator<Gen>,
|
||||
) where
|
||||
Scalar: RandomGenerable<UniformBinary>,
|
||||
InCont: ContainerMut<Element = Scalar>,
|
||||
Gen: ByteRandomGenerator,
|
||||
{
|
||||
generator.fill_slice_with_random_uniform_binary(lwe_secret_key.as_mut())
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
pub mod glwe_secret_key_generation;
|
||||
pub mod lwe_encryption;
|
||||
pub mod lwe_linear_algebra;
|
||||
pub mod lwe_secret_key_generation;
|
||||
pub mod slice_algorithms;
|
||||
|
||||
@@ -49,6 +49,12 @@ impl DefaultEngine {
|
||||
) -> &mut ImplEncryptionRandomGenerator<ActivatedRandomGenerator> {
|
||||
&mut self.encryption_generator
|
||||
}
|
||||
|
||||
pub fn get_secret_generator(
|
||||
&mut self,
|
||||
) -> &mut ImplSecretRandomGenerator<ActivatedRandomGenerator> {
|
||||
&mut self.secret_generator
|
||||
}
|
||||
}
|
||||
|
||||
impl AbstractEngine for DefaultEngine {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::core_crypto::commons::math::random::{
|
||||
ByteRandomGenerator, Gaussian, RandomGenerable, RandomGenerator, Seed,
|
||||
ByteRandomGenerator, Gaussian, RandomGenerable, RandomGenerator, Seed, UniformBinary,
|
||||
};
|
||||
use crate::core_crypto::commons::math::tensor::Tensor;
|
||||
use crate::core_crypto::commons::math::torus::UnsignedTorus;
|
||||
@@ -52,4 +52,11 @@ impl<G: ByteRandomGenerator> SecretRandomGenerator<G> {
|
||||
self.0
|
||||
.random_gaussian_tensor(length, 0.0, Scalar::GAUSSIAN_KEY_LOG_STD.get_standard_dev())
|
||||
}
|
||||
|
||||
pub(crate) fn fill_slice_with_random_uniform_binary<Scalar>(&mut self, slice: &mut [Scalar])
|
||||
where
|
||||
Scalar: RandomGenerable<UniformBinary>,
|
||||
{
|
||||
self.0.fill_slice_with_random_uniform_binary(slice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,6 +252,13 @@ impl<G: ByteRandomGenerator> RandomGenerator<G> {
|
||||
Scalar::fill_tensor(self, UniformBinary, output);
|
||||
}
|
||||
|
||||
pub fn fill_slice_with_random_uniform_binary<Scalar>(&mut self, output: &mut [Scalar])
|
||||
where
|
||||
Scalar: RandomGenerable<UniformBinary>,
|
||||
{
|
||||
Scalar::fill_slice(self, UniformBinary, output);
|
||||
}
|
||||
|
||||
/// Generates a tensor of random binary values of a given size.
|
||||
///
|
||||
/// # Example
|
||||
|
||||
75
tfhe/src/core_crypto/entities/glwe_secret_key.rs
Normal file
75
tfhe/src/core_crypto/entities/glwe_secret_key.rs
Normal file
@@ -0,0 +1,75 @@
|
||||
use crate::core_crypto::commons::traits::{Container, ContainerMut};
|
||||
use crate::core_crypto::entities::lwe_secret_key::LweSecretKeyBase;
|
||||
use crate::core_crypto::specification::parameters::{GlweDimension, PolynomialSize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct GlweSecretKeyBase<C: Container> {
|
||||
data: C,
|
||||
polynomial_size: PolynomialSize,
|
||||
}
|
||||
|
||||
impl<T, C: Container<Element = T>> AsRef<[T]> for GlweSecretKeyBase<C> {
|
||||
fn as_ref(&self) -> &[T] {
|
||||
self.data.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C: ContainerMut<Element = T>> AsMut<[T]> for GlweSecretKeyBase<C> {
|
||||
fn as_mut(&mut self) -> &mut [T] {
|
||||
self.data.as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Scalar, C: Container<Element = Scalar>> GlweSecretKeyBase<C> {
|
||||
pub fn from_container(container: C, polynomial_size: PolynomialSize) -> Self {
|
||||
assert!(
|
||||
container.container_len() % polynomial_size.0 == 0,
|
||||
"The provided container length is not valid. \
|
||||
It needs to be dividable by polynomial_size. \
|
||||
Got container length: {} and polynomial_size: {polynomial_size:?}",
|
||||
container.container_len()
|
||||
);
|
||||
GlweSecretKeyBase {
|
||||
data: container,
|
||||
polynomial_size,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn polynomial_size(&self) -> PolynomialSize {
|
||||
self.polynomial_size
|
||||
}
|
||||
|
||||
pub fn glwe_dimension(&self) -> GlweDimension {
|
||||
GlweDimension(self.data.container_len() / self.polynomial_size.0)
|
||||
}
|
||||
|
||||
pub fn into_lwe_secret_key(self) -> LweSecretKeyBase<C> {
|
||||
LweSecretKeyBase::from_container(self.data)
|
||||
}
|
||||
}
|
||||
|
||||
pub type GlweSecretKey<Scalar> = GlweSecretKeyBase<Vec<Scalar>>;
|
||||
|
||||
// TODO REFACTOR
|
||||
// Remove the back and forth conversions
|
||||
impl From<GlweSecretKey<u64>> for crate::core_crypto::prelude::GlweSecretKey64 {
|
||||
fn from(new_glwe_secret_key: GlweSecretKey<u64>) -> Self {
|
||||
use crate::core_crypto::commons::crypto::secret::GlweSecretKey as PrivateGlweSecretKey;
|
||||
use crate::core_crypto::prelude::GlweSecretKey64;
|
||||
GlweSecretKey64(PrivateGlweSecretKey::binary_from_container(
|
||||
new_glwe_secret_key.data,
|
||||
new_glwe_secret_key.polynomial_size,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::core_crypto::prelude::GlweSecretKey64> for GlweSecretKey<u64> {
|
||||
fn from(old_glwe_secret_key: crate::core_crypto::prelude::GlweSecretKey64) -> Self {
|
||||
use crate::core_crypto::commons::math::tensor::IntoTensor;
|
||||
let polynomial_size = old_glwe_secret_key.0.polynomial_size();
|
||||
GlweSecretKey::<u64>::from_container(
|
||||
old_glwe_secret_key.0.into_tensor().into_container(),
|
||||
polynomial_size,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod cleartext;
|
||||
pub mod encoded;
|
||||
pub mod glwe_secret_key;
|
||||
pub mod lwe_ciphertext;
|
||||
pub mod lwe_secret_key;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! Module with the definition of the ClientKey.
|
||||
|
||||
use crate::core_crypto::entities::glwe_secret_key::GlweSecretKey;
|
||||
use crate::core_crypto::entities::lwe_secret_key::LweSecretKey;
|
||||
use crate::core_crypto::prelude::*;
|
||||
use crate::shortint::ciphertext::Ciphertext;
|
||||
@@ -20,7 +21,7 @@ use std::fmt::Debug;
|
||||
pub struct ClientKey {
|
||||
/// The actual encryption / decryption key
|
||||
pub(crate) lwe_secret_key: LweSecretKey<u64>,
|
||||
pub(crate) glwe_secret_key: GlweSecretKey64,
|
||||
pub(crate) glwe_secret_key: GlweSecretKey<u64>,
|
||||
/// Key used as the output of the keyswitch operation
|
||||
pub(crate) lwe_secret_key_after_ks: LweSecretKey<u64>,
|
||||
pub parameters: Parameters,
|
||||
@@ -341,11 +342,13 @@ impl Serialize for ClientKey {
|
||||
let tmp_lwe_secret_key_after_ks: LweSecretKey64 =
|
||||
self.lwe_secret_key_after_ks.clone().into();
|
||||
|
||||
let tmp_glwe_secret_key: GlweSecretKey64 = self.glwe_secret_key.clone().into();
|
||||
|
||||
let lwe_secret_key = ser_eng
|
||||
.serialize(&tmp_lwe_secret_key)
|
||||
.map_err(serde::ser::Error::custom)?;
|
||||
let glwe_secret_key = ser_eng
|
||||
.serialize(&self.glwe_secret_key)
|
||||
.serialize(&tmp_glwe_secret_key)
|
||||
.map_err(serde::ser::Error::custom)?;
|
||||
let lwe_secret_key_after_ks = ser_eng
|
||||
.serialize(&tmp_lwe_secret_key_after_ks)
|
||||
@@ -379,11 +382,13 @@ impl<'de> Deserialize<'de> for ClientKey {
|
||||
.deserialize(thing.lwe_secret_key_after_ks.as_slice())
|
||||
.map_err(serde::de::Error::custom)?;
|
||||
|
||||
let tmp_glwe_secret_key: GlweSecretKey64 = de_eng
|
||||
.deserialize(thing.glwe_secret_key.as_slice())
|
||||
.map_err(serde::de::Error::custom)?;
|
||||
|
||||
Ok(Self {
|
||||
lwe_secret_key: tmp_lwe_secret_key.into(),
|
||||
glwe_secret_key: de_eng
|
||||
.deserialize(thing.glwe_secret_key.as_slice())
|
||||
.map_err(serde::de::Error::custom)?,
|
||||
glwe_secret_key: tmp_glwe_secret_key.into(),
|
||||
lwe_secret_key_after_ks: tmp_lwe_secret_key_after_ks.into(),
|
||||
parameters: thing.parameters,
|
||||
})
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//! All the `ShortintEngine` method related to client side (encrypt / decrypt)
|
||||
use super::{EngineResult, ShortintEngine};
|
||||
use crate::core_crypto::algorithms::glwe_secret_key_generation::allocate_and_generate_new_binary_glwe_secret_key;
|
||||
use crate::core_crypto::algorithms::lwe_encryption::{
|
||||
allocate_and_encrypt_new_lwe_ciphertext, decrypt_lwe_ciphertext,
|
||||
};
|
||||
use crate::core_crypto::algorithms::lwe_secret_key_generation::allocate_and_generate_new_binary_lwe_secret_key;
|
||||
use crate::core_crypto::entities::encoded::Encoded;
|
||||
use crate::core_crypto::prelude::*;
|
||||
use crate::shortint::ciphertext::Degree;
|
||||
use crate::shortint::parameters::{CarryModulus, MessageModulus};
|
||||
use crate::shortint::{Ciphertext, ClientKey, Parameters};
|
||||
@@ -12,24 +13,25 @@ use crate::shortint::{Ciphertext, ClientKey, Parameters};
|
||||
impl ShortintEngine {
|
||||
pub fn new_client_key(&mut self, parameters: Parameters) -> EngineResult<ClientKey> {
|
||||
// generate the lwe secret key
|
||||
let small_lwe_secret_key: LweSecretKey64 = self
|
||||
.engine
|
||||
.generate_new_lwe_secret_key(parameters.lwe_dimension)?;
|
||||
let small_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
parameters.lwe_dimension,
|
||||
self.engine.get_secret_generator(),
|
||||
);
|
||||
|
||||
// generate the rlwe secret key
|
||||
let glwe_secret_key: GlweSecretKey64 = self
|
||||
.engine
|
||||
.generate_new_glwe_secret_key(parameters.glwe_dimension, parameters.polynomial_size)?;
|
||||
let glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
parameters.glwe_dimension,
|
||||
parameters.polynomial_size,
|
||||
self.engine.get_secret_generator(),
|
||||
);
|
||||
|
||||
let large_lwe_secret_key = self
|
||||
.engine
|
||||
.transform_glwe_secret_key_to_lwe_secret_key(glwe_secret_key.clone())?;
|
||||
let large_lwe_secret_key = glwe_secret_key.clone().into_lwe_secret_key();
|
||||
|
||||
// pack the keys in the client key set
|
||||
Ok(ClientKey {
|
||||
lwe_secret_key: large_lwe_secret_key.into(),
|
||||
lwe_secret_key: large_lwe_secret_key,
|
||||
glwe_secret_key,
|
||||
lwe_secret_key_after_ks: small_lwe_secret_key.into(),
|
||||
lwe_secret_key_after_ks: small_lwe_secret_key,
|
||||
parameters,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ impl ShortintEngine {
|
||||
// Remove the clone + into
|
||||
let bootstrap_key: LweBootstrapKey64 = self.par_engine.generate_new_lwe_bootstrap_key(
|
||||
&cks.lwe_secret_key_after_ks.clone().into(),
|
||||
&cks.glwe_secret_key,
|
||||
&cks.glwe_secret_key.clone().into(),
|
||||
cks.parameters.pbs_base_log,
|
||||
cks.parameters.pbs_level,
|
||||
var_rlwe,
|
||||
|
||||
@@ -23,7 +23,7 @@ impl ShortintEngine {
|
||||
.engine
|
||||
.generate_new_lwe_circuit_bootstrap_private_functional_packing_keyswitch_keys(
|
||||
&cks.lwe_secret_key.clone().into(),
|
||||
&cks.glwe_secret_key,
|
||||
&cks.glwe_secret_key.clone().into(),
|
||||
cks.parameters.pfks_base_log,
|
||||
cks.parameters.pfks_level,
|
||||
Variance(cks.parameters.pfks_modular_std_dev.get_variance()),
|
||||
|
||||
Reference in New Issue
Block a user