mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-10 07:08:03 -05:00
refactor(tfhe)!: update key level order for better performance
- use natural order for decomposition levels in bsk co-authored-by: Agnes Leroy <agnes.leroy@zama.ai>
This commit is contained in:
@@ -75,8 +75,7 @@ keyswitch(Torus *lwe_array_out, const Torus *__restrict__ lwe_output_indexes,
|
||||
level_count);
|
||||
Torus state = a_i >> (sizeof(Torus) * 8 - base_log * level_count);
|
||||
|
||||
for (int j = level_count - 1; j >= 0; j--) {
|
||||
// Levels are stored in reverse order
|
||||
for (int j = 0; j < level_count; j++) {
|
||||
auto ksk_block =
|
||||
get_ith_block(ksk, i, j, lwe_dimension_out, level_count);
|
||||
Torus decomposed = decompose_one<Torus>(state, mask_mod_b, base_log);
|
||||
@@ -209,8 +208,7 @@ __device__ void packing_keyswitch_lwe_ciphertext_into_glwe_ciphertext(
|
||||
|
||||
// block of key for current lwe coefficient (cur_input_lwe[i])
|
||||
auto ksk_block = &fp_ksk[i * ksk_block_size];
|
||||
for (int j = level_count - 1; j >= 0; j--) {
|
||||
// Levels are stored in reverse order
|
||||
for (int j = 0; j < level_count; j++) {
|
||||
auto ksk_glwe = &ksk_block[j * glwe_size * polynomial_size];
|
||||
// Iterate through each level and multiply by the ksk piece
|
||||
auto ksk_glwe_chunk = &ksk_glwe[poly_id * coef_per_block];
|
||||
|
||||
@@ -24,8 +24,8 @@ __device__ const T *get_ith_mask_kth_block(const T *ptr, int i, int k,
|
||||
uint32_t level_count) {
|
||||
return &ptr[get_start_ith_ggsw(i, polynomial_size, glwe_dimension,
|
||||
level_count) +
|
||||
level * polynomial_size / 2 * (glwe_dimension + 1) *
|
||||
(glwe_dimension + 1) +
|
||||
(level_count - level - 1) * polynomial_size / 2 *
|
||||
(glwe_dimension + 1) * (glwe_dimension + 1) +
|
||||
k * polynomial_size / 2 * (glwe_dimension + 1)];
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ __device__ T *get_ith_mask_kth_block(T *ptr, int i, int k, int level,
|
||||
int glwe_dimension, uint32_t level_count) {
|
||||
return &ptr[get_start_ith_ggsw(i, polynomial_size, glwe_dimension,
|
||||
level_count) +
|
||||
level * polynomial_size / 2 * (glwe_dimension + 1) *
|
||||
(glwe_dimension + 1) +
|
||||
(level_count - level - 1) * polynomial_size / 2 *
|
||||
(glwe_dimension + 1) * (glwe_dimension + 1) +
|
||||
k * polynomial_size / 2 * (glwe_dimension + 1)];
|
||||
}
|
||||
template <typename T>
|
||||
@@ -45,8 +45,8 @@ __device__ T *get_ith_body_kth_block(T *ptr, int i, int k, int level,
|
||||
int glwe_dimension, uint32_t level_count) {
|
||||
return &ptr[get_start_ith_ggsw(i, polynomial_size, glwe_dimension,
|
||||
level_count) +
|
||||
level * polynomial_size / 2 * (glwe_dimension + 1) *
|
||||
(glwe_dimension + 1) +
|
||||
(level_count - level - 1) * polynomial_size / 2 *
|
||||
(glwe_dimension + 1) * (glwe_dimension + 1) +
|
||||
k * polynomial_size / 2 * (glwe_dimension + 1) +
|
||||
glwe_dimension * polynomial_size / 2];
|
||||
}
|
||||
|
||||
@@ -136,12 +136,13 @@ pub fn encrypt_constant_ggsw_ciphertext<Scalar, NoiseDistribution, KeyCont, Outp
|
||||
.expect("Failed to split generator into ggsw levels");
|
||||
|
||||
let decomp_base_log = output.decomposition_base_log();
|
||||
let decomp_level_count = output.decomposition_level_count();
|
||||
let ciphertext_modulus = output.ciphertext_modulus();
|
||||
|
||||
for (level_index, (mut level_matrix, mut generator)) in
|
||||
for (output_index, (mut level_matrix, mut generator)) in
|
||||
output.iter_mut().zip(gen_iter).enumerate()
|
||||
{
|
||||
let decomp_level = DecompositionLevel(level_index + 1);
|
||||
let decomp_level = DecompositionLevel(decomp_level_count.0 - output_index);
|
||||
let factor = ggsw_encryption_multiplicative_factor(
|
||||
ciphertext_modulus,
|
||||
decomp_level,
|
||||
@@ -269,11 +270,12 @@ pub fn par_encrypt_constant_ggsw_ciphertext<Scalar, NoiseDistribution, KeyCont,
|
||||
.expect("Failed to split generator into ggsw levels");
|
||||
|
||||
let decomp_base_log = output.decomposition_base_log();
|
||||
let decomp_level_count = output.decomposition_level_count();
|
||||
let ciphertext_modulus = output.ciphertext_modulus();
|
||||
|
||||
output.par_iter_mut().zip(gen_iter).enumerate().for_each(
|
||||
|(level_index, (mut level_matrix, mut generator))| {
|
||||
let decomp_level = DecompositionLevel(level_index + 1);
|
||||
|(output_index, (mut level_matrix, mut generator))| {
|
||||
let decomp_level = DecompositionLevel(decomp_level_count.0 - output_index);
|
||||
let factor = ggsw_encryption_multiplicative_factor(
|
||||
ciphertext_modulus,
|
||||
decomp_level,
|
||||
@@ -401,12 +403,13 @@ pub fn encrypt_constant_seeded_ggsw_ciphertext_with_existing_generator<
|
||||
.expect("Failed to split generator into ggsw levels");
|
||||
|
||||
let decomp_base_log = output.decomposition_base_log();
|
||||
let decomp_level_count = output.decomposition_level_count();
|
||||
let ciphertext_modulus = output.ciphertext_modulus();
|
||||
|
||||
for (level_index, (mut level_matrix, mut loop_generator)) in
|
||||
for (output_index, (mut level_matrix, mut loop_generator)) in
|
||||
output.iter_mut().zip(gen_iter).enumerate()
|
||||
{
|
||||
let decomp_level = DecompositionLevel(level_index + 1);
|
||||
let decomp_level = DecompositionLevel(decomp_level_count.0 - output_index);
|
||||
let factor = ggsw_encryption_multiplicative_factor(
|
||||
ciphertext_modulus,
|
||||
decomp_level,
|
||||
@@ -581,11 +584,12 @@ pub fn par_encrypt_constant_seeded_ggsw_ciphertext_with_existing_generator<
|
||||
.expect("Failed to split generator into ggsw levels");
|
||||
|
||||
let decomp_base_log = output.decomposition_base_log();
|
||||
let decomp_level_count = output.decomposition_level_count();
|
||||
let ciphertext_modulus = output.ciphertext_modulus();
|
||||
|
||||
output.par_iter_mut().zip(gen_iter).enumerate().for_each(
|
||||
|(level_index, (mut level_matrix, mut generator))| {
|
||||
let decomp_level = DecompositionLevel(level_index + 1);
|
||||
|(output_index, (mut level_matrix, mut generator))| {
|
||||
let decomp_level = DecompositionLevel(decomp_level_count.0 - output_index);
|
||||
let factor = ggsw_encryption_multiplicative_factor(
|
||||
ciphertext_modulus,
|
||||
decomp_level,
|
||||
@@ -881,7 +885,7 @@ where
|
||||
glwe_secret_key.glwe_dimension()
|
||||
);
|
||||
|
||||
let level_matrix = ggsw_ciphertext.last().unwrap();
|
||||
let level_matrix = ggsw_ciphertext.first().unwrap();
|
||||
let level_matrix_as_glwe_list = level_matrix.as_glwe_list();
|
||||
let last_row = level_matrix_as_glwe_list.last().unwrap();
|
||||
let decomp_level = ggsw_ciphertext.decomposition_level_count();
|
||||
|
||||
@@ -216,8 +216,7 @@ pub fn keyswitch_lwe_ciphertext_native_mod_compatible<Scalar, KSKCont, InputCont
|
||||
{
|
||||
let decomposition_iter = decomposer.decompose(input_mask_element);
|
||||
// Loop over the levels
|
||||
for (level_key_ciphertext, decomposed) in
|
||||
keyswitch_key_block.iter().rev().zip(decomposition_iter)
|
||||
for (level_key_ciphertext, decomposed) in keyswitch_key_block.iter().zip(decomposition_iter)
|
||||
{
|
||||
slice_wrapping_sub_scalar_mul_assign(
|
||||
output_lwe_ciphertext.as_mut(),
|
||||
@@ -305,8 +304,7 @@ pub fn keyswitch_lwe_ciphertext_other_mod<Scalar, KSKCont, InputCont, OutputCont
|
||||
{
|
||||
let decomposition_iter = decomposer.decompose(input_mask_element);
|
||||
// Loop over the levels
|
||||
for (level_key_ciphertext, decomposed) in
|
||||
keyswitch_key_block.iter().rev().zip(decomposition_iter)
|
||||
for (level_key_ciphertext, decomposed) in keyswitch_key_block.iter().zip(decomposition_iter)
|
||||
{
|
||||
slice_wrapping_sub_scalar_mul_assign_custom_modulus(
|
||||
output_lwe_ciphertext.as_mut(),
|
||||
@@ -438,8 +436,7 @@ pub fn keyswitch_lwe_ciphertext_with_scalar_change<
|
||||
{
|
||||
let decomposition_iter = input_decomposer.decompose(input_mask_element);
|
||||
// Loop over the levels
|
||||
for (level_key_ciphertext, decomposed) in
|
||||
keyswitch_key_block.iter().rev().zip(decomposition_iter)
|
||||
for (level_key_ciphertext, decomposed) in keyswitch_key_block.iter().zip(decomposition_iter)
|
||||
{
|
||||
slice_wrapping_sub_scalar_mul_assign(
|
||||
output_lwe_ciphertext.as_mut(),
|
||||
@@ -802,7 +799,7 @@ pub fn par_keyswitch_lwe_ciphertext_with_thread_count_native_mod_compatible<
|
||||
let decomposition_iter = decomposer.decompose(input_mask_element);
|
||||
// Loop over the levels
|
||||
for (level_key_ciphertext, decomposed) in
|
||||
keyswitch_key_block.iter().rev().zip(decomposition_iter)
|
||||
keyswitch_key_block.iter().zip(decomposition_iter)
|
||||
{
|
||||
slice_wrapping_sub_scalar_mul_assign(
|
||||
buffer.as_mut(),
|
||||
@@ -949,7 +946,7 @@ pub fn par_keyswitch_lwe_ciphertext_with_thread_count_other_mod<
|
||||
let decomposition_iter = decomposer.decompose(input_mask_element);
|
||||
// Loop over the levels
|
||||
for (level_key_ciphertext, decomposed) in
|
||||
keyswitch_key_block.iter().rev().zip(decomposition_iter)
|
||||
keyswitch_key_block.iter().zip(decomposition_iter)
|
||||
{
|
||||
slice_wrapping_sub_scalar_mul_assign_custom_modulus(
|
||||
buffer.as_mut(),
|
||||
|
||||
@@ -160,6 +160,7 @@ pub fn generate_lwe_keyswitch_key_native_mod_compatible<
|
||||
// We fill the buffer with the powers of the key elements
|
||||
for (level, message) in (1..=decomp_level_count.0)
|
||||
.map(DecompositionLevel)
|
||||
.rev()
|
||||
.zip(decomposition_plaintexts_buffer.iter_mut())
|
||||
{
|
||||
// Here we take the decomposition term from the native torus, bring it to the torus we
|
||||
@@ -234,6 +235,7 @@ pub fn generate_lwe_keyswitch_key_other_mod<
|
||||
// We fill the buffer with the powers of the key elements
|
||||
for (level, message) in (1..=decomp_level_count.0)
|
||||
.map(DecompositionLevel)
|
||||
.rev()
|
||||
.zip(decomposition_plaintexts_buffer.iter_mut())
|
||||
{
|
||||
// Here we take the decomposition term from the native torus, bring it to the torus we
|
||||
@@ -415,6 +417,7 @@ pub fn generate_seeded_lwe_keyswitch_key<
|
||||
// We fill the buffer with the powers of the key elmements
|
||||
for (level, message) in (1..=decomp_level_count.0)
|
||||
.map(DecompositionLevel)
|
||||
.rev()
|
||||
.zip(decomposition_plaintexts_buffer.iter_mut())
|
||||
{
|
||||
// Here we take the decomposition term from the native torus, bring it to the torus we
|
||||
|
||||
@@ -177,7 +177,7 @@ pub fn keyswitch_lwe_ciphertext_into_glwe_ciphertext<Scalar, KeyCont, InputCont,
|
||||
// Loop over the number of levels:
|
||||
// We compute the multiplication of a ciphertext from the private functional
|
||||
// keyswitching key with a piece of the decomposition and subtract it to the buffer
|
||||
for (level_key_cipher, decomposed) in keyswitch_key_block.iter().rev().zip(decomp) {
|
||||
for (level_key_cipher, decomposed) in keyswitch_key_block.iter().zip(decomp) {
|
||||
slice_wrapping_sub_scalar_mul_assign(
|
||||
output_glwe_ciphertext.as_mut(),
|
||||
level_key_cipher.as_ref(),
|
||||
|
||||
@@ -135,6 +135,7 @@ pub fn generate_lwe_packing_keyswitch_key<
|
||||
// We fill the buffer with the powers of the key elements
|
||||
for (level, mut messages) in (1..=decomp_level_count.0)
|
||||
.map(DecompositionLevel)
|
||||
.rev()
|
||||
.zip(decomposition_plaintexts_buffer.chunks_exact_mut(polynomial_size.0))
|
||||
{
|
||||
// Here we take the decomposition term from the native torus, bring it to the torus we
|
||||
@@ -330,6 +331,7 @@ pub fn generate_seeded_lwe_packing_keyswitch_key<
|
||||
// We fill the buffer with the powers of the key elements
|
||||
for (level, mut messages) in (1..=decomp_level_count.0)
|
||||
.map(DecompositionLevel)
|
||||
.rev()
|
||||
.zip(decomposition_plaintexts_buffer.chunks_exact_mut(polynomial_size.0))
|
||||
{
|
||||
// Here we take the decomposition term from the native torus, bring it to the torus we
|
||||
|
||||
@@ -77,7 +77,7 @@ pub fn private_functional_keyswitch_lwe_ciphertext_into_glwe_ciphertext<
|
||||
// Loop over the number of levels:
|
||||
// We compute the multiplication of a ciphertext from the private functional
|
||||
// keyswitching key with a piece of the decomposition and subtract it to the buffer
|
||||
for (level_key_cipher, decomposed) in keyswitch_key_block.iter().rev().zip(decomp) {
|
||||
for (level_key_cipher, decomposed) in keyswitch_key_block.iter().zip(decomp) {
|
||||
slice_wrapping_sub_scalar_mul_assign(
|
||||
output_glwe_ciphertext.as_mut(),
|
||||
level_key_cipher.as_ref(),
|
||||
@@ -208,7 +208,7 @@ pub fn par_private_functional_keyswitch_lwe_ciphertext_into_glwe_ciphertext_with
|
||||
// Loop over the number of levels:
|
||||
// We compute the multiplication of a ciphertext from the private functional
|
||||
// keyswitching key with a piece of the decomposition and subtract it to the buffer
|
||||
for (level_key_cipher, decomposed) in keyswitch_key_block.iter().rev().zip(decomp) {
|
||||
for (level_key_cipher, decomposed) in keyswitch_key_block.iter().zip(decomp) {
|
||||
slice_wrapping_sub_scalar_mul_assign(
|
||||
glwe_buffer.as_mut(),
|
||||
level_key_cipher.as_ref(),
|
||||
|
||||
@@ -105,6 +105,7 @@ pub fn generate_lwe_private_functional_packing_keyswitch_key<
|
||||
// We fill the buffer with the powers of the key bits
|
||||
for (level, mut message) in (1..=decomp_level_count.0)
|
||||
.map(DecompositionLevel)
|
||||
.rev()
|
||||
.zip(messages.chunks_exact_mut(polynomial_size.0))
|
||||
{
|
||||
slice_wrapping_add_scalar_mul_assign(
|
||||
@@ -219,6 +220,7 @@ pub fn par_generate_lwe_private_functional_packing_keyswitch_key<
|
||||
// We fill the buffer with the powers of the key bits
|
||||
for (level, mut message) in (1..=decomp_level_count.0)
|
||||
.map(DecompositionLevel)
|
||||
.rev()
|
||||
.zip(messages.chunks_exact_mut(polynomial_size.0))
|
||||
{
|
||||
slice_wrapping_add_scalar_mul_assign(
|
||||
|
||||
@@ -584,7 +584,7 @@ pub(crate) fn add_external_product_ntt64_assign<InputGlweCont>(
|
||||
);
|
||||
|
||||
// We loop through the levels (we reverse to match the order of the decomposition iterator.)
|
||||
ggsw.into_levels().rev().for_each(|ggsw_decomp_matrix| {
|
||||
ggsw.into_levels().for_each(|ggsw_decomp_matrix| {
|
||||
// We retrieve the decomposition of this level.
|
||||
let (glwe_level, glwe_decomp_term, mut substack2) =
|
||||
decomposition.collect_next_term(&mut substack1, align);
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{Container, GgswCiphertext, UnsignedInteger};
|
||||
|
||||
impl<C: Container> Deprecable for GgswCiphertext<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "GgswCiphertext";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum GgswCiphertextVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(GgswCiphertext<C>),
|
||||
V0(Deprecated<GgswCiphertext<C>>),
|
||||
V1(GgswCiphertext<C>),
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{Container, GgswCiphertextList, UnsignedInteger};
|
||||
|
||||
impl<C: Container> Deprecable for GgswCiphertextList<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "GgswCiphertextList";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum GgswCiphertextListVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(GgswCiphertextList<C>),
|
||||
V0(Deprecated<GgswCiphertextList<C>>),
|
||||
V1(GgswCiphertextList<C>),
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{Container, LweBootstrapKey, UnsignedInteger};
|
||||
|
||||
impl<C: Container> Deprecable for LweBootstrapKey<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "LweBootstrapKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum LweBootstrapKeyVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(LweBootstrapKey<C>),
|
||||
V0(Deprecated<LweBootstrapKey<C>>),
|
||||
V1(LweBootstrapKey<C>),
|
||||
}
|
||||
|
||||
@@ -1,50 +1,14 @@
|
||||
use tfhe_versionable::{Upgrade, Version, VersionsDispatch};
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{
|
||||
CiphertextModulus, Container, ContainerMut, ContiguousEntityContainerMut, DecompositionBaseLog,
|
||||
DecompositionLevelCount, LweKeyswitchKey, LweSize, UnsignedInteger,
|
||||
};
|
||||
use crate::core_crypto::prelude::{Container, LweKeyswitchKey, UnsignedInteger};
|
||||
|
||||
#[derive(Version)]
|
||||
pub struct LweKeyswitchKeyV0<C: Container>
|
||||
impl<C: Container> Deprecable for LweKeyswitchKey<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
data: C,
|
||||
decomp_base_log: DecompositionBaseLog,
|
||||
decomp_level_count: DecompositionLevelCount,
|
||||
output_lwe_size: LweSize,
|
||||
ciphertext_modulus: CiphertextModulus<C::Element>,
|
||||
}
|
||||
|
||||
impl<Scalar: UnsignedInteger, C: ContainerMut<Element = Scalar>> Upgrade<LweKeyswitchKey<C>>
|
||||
for LweKeyswitchKeyV0<C>
|
||||
{
|
||||
type Error = std::convert::Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<LweKeyswitchKey<C>, Self::Error> {
|
||||
let Self {
|
||||
data,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
output_lwe_size,
|
||||
ciphertext_modulus,
|
||||
} = self;
|
||||
let mut new_ksk = LweKeyswitchKey::from_container(
|
||||
data,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
output_lwe_size,
|
||||
ciphertext_modulus,
|
||||
);
|
||||
|
||||
// Invert levels
|
||||
for mut ksk_block in new_ksk.iter_mut() {
|
||||
ksk_block.reverse();
|
||||
}
|
||||
|
||||
Ok(new_ksk)
|
||||
}
|
||||
const TYPE_NAME: &'static str = "LweKeyswitchKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
@@ -52,6 +16,7 @@ pub enum LweKeyswitchKeyVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(LweKeyswitchKeyV0<C>),
|
||||
V1(LweKeyswitchKey<C>),
|
||||
V0(Deprecated<LweKeyswitchKey<C>>),
|
||||
V1(Deprecated<LweKeyswitchKey<C>>),
|
||||
V2(LweKeyswitchKey<C>),
|
||||
}
|
||||
|
||||
@@ -1,19 +1,35 @@
|
||||
use concrete_fft::c64;
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{
|
||||
Container, FourierLweMultiBitBootstrapKey, LweMultiBitBootstrapKey, UnsignedInteger,
|
||||
};
|
||||
|
||||
impl<C: Container> Deprecable for LweMultiBitBootstrapKey<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "LweMultiBitBootstrapKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum LweMultiBitBootstrapKeyVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(LweMultiBitBootstrapKey<C>),
|
||||
V0(Deprecated<LweMultiBitBootstrapKey<C>>),
|
||||
V1(LweMultiBitBootstrapKey<C>),
|
||||
}
|
||||
|
||||
impl<C: Container<Element = c64>> Deprecable for FourierLweMultiBitBootstrapKey<C> {
|
||||
const TYPE_NAME: &'static str = "FourierLweMultiBitBootstrapKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum FourierLweMultiBitBootstrapKeyVersions<C: Container<Element = c64>> {
|
||||
V0(FourierLweMultiBitBootstrapKey<C>),
|
||||
V0(Deprecated<FourierLweMultiBitBootstrapKey<C>>),
|
||||
V1(FourierLweMultiBitBootstrapKey<C>),
|
||||
}
|
||||
|
||||
@@ -1,53 +1,14 @@
|
||||
use tfhe_versionable::{Upgrade, Version, VersionsDispatch};
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{
|
||||
CiphertextModulus, Container, ContainerMut, ContiguousEntityContainerMut, DecompositionBaseLog,
|
||||
DecompositionLevelCount, GlweSize, LwePackingKeyswitchKey, PolynomialSize, UnsignedInteger,
|
||||
};
|
||||
use crate::core_crypto::prelude::{Container, LwePackingKeyswitchKey, UnsignedInteger};
|
||||
|
||||
#[derive(Version)]
|
||||
pub struct LwePackingKeyswitchKeyV0<C: Container>
|
||||
impl<C: Container> Deprecable for LwePackingKeyswitchKey<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
data: C,
|
||||
decomp_base_log: DecompositionBaseLog,
|
||||
decomp_level_count: DecompositionLevelCount,
|
||||
output_glwe_size: GlweSize,
|
||||
output_polynomial_size: PolynomialSize,
|
||||
ciphertext_modulus: CiphertextModulus<C::Element>,
|
||||
}
|
||||
|
||||
impl<Scalar: UnsignedInteger, C: ContainerMut<Element = Scalar>> Upgrade<LwePackingKeyswitchKey<C>>
|
||||
for LwePackingKeyswitchKeyV0<C>
|
||||
{
|
||||
type Error = std::convert::Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<LwePackingKeyswitchKey<C>, Self::Error> {
|
||||
let Self {
|
||||
data,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
output_glwe_size,
|
||||
output_polynomial_size,
|
||||
ciphertext_modulus,
|
||||
} = self;
|
||||
let mut new_pksk = LwePackingKeyswitchKey::from_container(
|
||||
data,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
output_glwe_size,
|
||||
output_polynomial_size,
|
||||
ciphertext_modulus,
|
||||
);
|
||||
|
||||
// Invert levels
|
||||
for mut pksk_block in new_pksk.iter_mut() {
|
||||
pksk_block.reverse();
|
||||
}
|
||||
|
||||
Ok(new_pksk)
|
||||
}
|
||||
const TYPE_NAME: &'static str = "LwePackingKeyswitchKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
@@ -55,6 +16,7 @@ pub enum LwePackingKeyswitchKeyVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(LwePackingKeyswitchKeyV0<C>),
|
||||
V1(LwePackingKeyswitchKey<C>),
|
||||
V0(Deprecated<LwePackingKeyswitchKey<C>>),
|
||||
V1(Deprecated<LwePackingKeyswitchKey<C>>),
|
||||
V2(LwePackingKeyswitchKey<C>),
|
||||
}
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{
|
||||
Container, LwePrivateFunctionalPackingKeyswitchKey, UnsignedInteger,
|
||||
};
|
||||
|
||||
impl<C: Container> Deprecable for LwePrivateFunctionalPackingKeyswitchKey<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "LwePrivateFunctionalPackingKeyswitchKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum LwePrivateFunctionalPackingKeyswitchKeyVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(LwePrivateFunctionalPackingKeyswitchKey<C>),
|
||||
V0(Deprecated<LwePrivateFunctionalPackingKeyswitchKey<C>>),
|
||||
V1(LwePrivateFunctionalPackingKeyswitchKey<C>),
|
||||
}
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{
|
||||
Container, LwePrivateFunctionalPackingKeyswitchKeyList, UnsignedInteger,
|
||||
};
|
||||
|
||||
impl<C: Container> Deprecable for LwePrivateFunctionalPackingKeyswitchKeyList<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "LwePrivateFunctionalPackingKeyswitchKeyList";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum LwePrivateFunctionalPackingKeyswitchKeyListVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(LwePrivateFunctionalPackingKeyswitchKeyList<C>),
|
||||
V0(Deprecated<LwePrivateFunctionalPackingKeyswitchKeyList<C>>),
|
||||
V1(LwePrivateFunctionalPackingKeyswitchKeyList<C>),
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{Container, NttGgswCiphertext, UnsignedInteger};
|
||||
|
||||
impl<C: Container> Deprecable for NttGgswCiphertext<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "NttGgswCiphertext";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum NttGgswCiphertextVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(NttGgswCiphertext<C>),
|
||||
V0(Deprecated<NttGgswCiphertext<C>>),
|
||||
V1(NttGgswCiphertext<C>),
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{Container, NttGgswCiphertextList, UnsignedInteger};
|
||||
|
||||
impl<C: Container> Deprecable for NttGgswCiphertextList<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "NttGgswCiphertextList";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum NttGgswCiphertextListVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(NttGgswCiphertextList<C>),
|
||||
V0(Deprecated<NttGgswCiphertextList<C>>),
|
||||
V1(NttGgswCiphertextList<C>),
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{Container, NttLweBootstrapKey, UnsignedInteger};
|
||||
|
||||
impl<C: Container> Deprecable for NttLweBootstrapKey<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "NttLweBootstrapKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum NttLweBootstrapKeyVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(NttLweBootstrapKey<C>),
|
||||
V0(Deprecated<NttLweBootstrapKey<C>>),
|
||||
V1(NttLweBootstrapKey<C>),
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{Container, SeededGgswCiphertext, UnsignedInteger};
|
||||
|
||||
impl<C: Container> Deprecable for SeededGgswCiphertext<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "SeededGgswCiphertext";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum SeededGgswCiphertextVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(SeededGgswCiphertext<C>),
|
||||
V0(Deprecated<SeededGgswCiphertext<C>>),
|
||||
V1(SeededGgswCiphertext<C>),
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{Container, SeededGgswCiphertextList, UnsignedInteger};
|
||||
|
||||
impl<C: Container> Deprecable for SeededGgswCiphertextList<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "SeededGgswCiphertextList";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum SeededGgswCiphertextListVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(SeededGgswCiphertextList<C>),
|
||||
V0(Deprecated<SeededGgswCiphertextList<C>>),
|
||||
V1(SeededGgswCiphertextList<C>),
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{Container, SeededLweBootstrapKey, UnsignedInteger};
|
||||
|
||||
impl<C: Container> Deprecable for SeededLweBootstrapKey<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "SeededLweBootstrapKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum SeededLweBootstrapKeyVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(SeededLweBootstrapKey<C>),
|
||||
V0(Deprecated<SeededLweBootstrapKey<C>>),
|
||||
V1(SeededLweBootstrapKey<C>),
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "SeededLweKeyswitchKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.9";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
@@ -17,5 +17,6 @@ where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(Deprecated<SeededLweKeyswitchKey<C>>),
|
||||
V1(SeededLweKeyswitchKey<C>),
|
||||
V1(Deprecated<SeededLweKeyswitchKey<C>>),
|
||||
V2(SeededLweKeyswitchKey<C>),
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::core_crypto::prelude::{Container, SeededLweMultiBitBootstrapKey, UnsignedInteger};
|
||||
|
||||
impl<C: Container> Deprecable for SeededLweMultiBitBootstrapKey<C>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "SeededLweMultiBitBootstrapKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum SeededLweMultiBitBootstrapKeyVersions<C: Container>
|
||||
where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(SeededLweMultiBitBootstrapKey<C>),
|
||||
V0(Deprecated<SeededLweMultiBitBootstrapKey<C>>),
|
||||
V1(SeededLweMultiBitBootstrapKey<C>),
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
const TYPE_NAME: &'static str = "SeededLwePackingKeyswitchKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.9";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
@@ -17,5 +17,6 @@ where
|
||||
C::Element: UnsignedInteger,
|
||||
{
|
||||
V0(Deprecated<SeededLwePackingKeyswitchKey<C>>),
|
||||
V1(SeededLwePackingKeyswitchKey<C>),
|
||||
V1(Deprecated<SeededLwePackingKeyswitchKey<C>>),
|
||||
V2(SeededLwePackingKeyswitchKey<C>),
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use aligned_vec::ABox;
|
||||
@@ -60,22 +61,46 @@ impl<C: IntoContainerOwned<Element = c64>> From<FourierPolynomialListVersionedOw
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Container<Element = c64>> Deprecable for FourierLweBootstrapKey<C> {
|
||||
const TYPE_NAME: &'static str = "FourierLweBootstrapKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum FourierLweBootstrapKeyVersions<C: Container<Element = c64>> {
|
||||
V0(FourierLweBootstrapKey<C>),
|
||||
V0(Deprecated<FourierLweBootstrapKey<C>>),
|
||||
V1(FourierLweBootstrapKey<C>),
|
||||
}
|
||||
|
||||
impl<C: Container<Element = c64>> Deprecable for FourierGgswCiphertext<C> {
|
||||
const TYPE_NAME: &'static str = "FourierGgswCiphertext";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum FourierGgswCiphertextVersions<C: Container<Element = c64>> {
|
||||
V0(FourierGgswCiphertext<C>),
|
||||
V0(Deprecated<FourierGgswCiphertext<C>>),
|
||||
V1(FourierGgswCiphertext<C>),
|
||||
}
|
||||
|
||||
impl<C: Container<Element = f64>> Deprecable for Fourier128LweBootstrapKey<C> {
|
||||
const TYPE_NAME: &'static str = "Fourier128LweBootstrapKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum Fourier128LweBootstrapKeyVersions<C: Container<Element = f64>> {
|
||||
V0(Fourier128LweBootstrapKey<C>),
|
||||
V0(Deprecated<Fourier128LweBootstrapKey<C>>),
|
||||
V1(Fourier128LweBootstrapKey<C>),
|
||||
}
|
||||
|
||||
impl<C: Container<Element = f64>> Deprecable for Fourier128GgswCiphertext<C> {
|
||||
const TYPE_NAME: &'static str = "Fourier128GgswCiphertext";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum Fourier128GgswCiphertextVersions<C: Container<Element = f64>> {
|
||||
V0(Fourier128GgswCiphertext<C>),
|
||||
V0(Deprecated<Fourier128GgswCiphertext<C>>),
|
||||
V1(Fourier128GgswCiphertext<C>),
|
||||
}
|
||||
|
||||
@@ -187,6 +187,16 @@ pub trait ContiguousEntityContainer: AsRef<[Self::Element]> {
|
||||
Self::SelfView::<'_>::create_from(sub_container, self_meta)
|
||||
}
|
||||
|
||||
fn first(&self) -> Option<Self::EntityView<'_>> {
|
||||
let entity_count = self.entity_count();
|
||||
|
||||
if entity_count == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(self.get(0))
|
||||
}
|
||||
}
|
||||
|
||||
fn last(&self) -> Option<Self::EntityView<'_>> {
|
||||
let entity_count = self.entity_count();
|
||||
|
||||
|
||||
@@ -176,16 +176,17 @@ impl<Scalar: UnsignedInteger, C: Container<Element = Scalar>> NttGgswCiphertext<
|
||||
pub fn into_levels(
|
||||
&self,
|
||||
) -> impl DoubleEndedIterator<Item = NttGgswLevelMatrixView<'_, Scalar>> {
|
||||
let decomposition_level_count = self.decomposition_level_count.0;
|
||||
self.data
|
||||
.as_ref()
|
||||
.split_into(self.decomposition_level_count.0)
|
||||
.split_into(decomposition_level_count)
|
||||
.enumerate()
|
||||
.map(move |(i, slice)| {
|
||||
NttGgswLevelMatrixView::from_container(
|
||||
slice,
|
||||
self.glwe_size,
|
||||
self.polynomial_size,
|
||||
DecompositionLevel(i + 1),
|
||||
DecompositionLevel(decomposition_level_count - i),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ pub fn glwe_fast_keyswitch<Scalar, OutputGlweCont, InputGlweCont, GgswCont>(
|
||||
|
||||
// We loop through the levels (we reverse to match the order of the decomposition
|
||||
// iterator.)
|
||||
ggsw.into_levels().rev().for_each(|ggsw_decomp_matrix| {
|
||||
ggsw.into_levels().for_each(|ggsw_decomp_matrix| {
|
||||
// We retrieve the decomposition of this level.
|
||||
let (glwe_level, glwe_decomp_term, mut substack2) =
|
||||
collect_next_term(&mut decomposition, &mut substack1, align);
|
||||
|
||||
@@ -174,8 +174,7 @@ pub fn shrinking_keyswitch_lwe_ciphertext<Scalar, KSKCont, InputCont, OutputCont
|
||||
{
|
||||
let decomposition_iter = decomposer.decompose(input_mask_element);
|
||||
// Loop over the levels
|
||||
for (level_key_ciphertext, decomposed) in
|
||||
keyswitch_key_block.iter().rev().zip(decomposition_iter)
|
||||
for (level_key_ciphertext, decomposed) in keyswitch_key_block.iter().zip(decomposition_iter)
|
||||
{
|
||||
slice_wrapping_sub_scalar_mul_assign(
|
||||
output_lwe_ciphertext.as_mut(),
|
||||
|
||||
@@ -41,12 +41,13 @@ pub fn encrypt_pseudo_ggsw_ciphertext<Scalar, NoiseDistribution, KeyCont, Output
|
||||
.expect("Failed to split generator into pseudo ggsw levels");
|
||||
|
||||
let decomp_base_log = output.decomposition_base_log();
|
||||
let decomp_level_count = output.decomposition_level_count();
|
||||
let ciphertext_modulus = output.ciphertext_modulus();
|
||||
|
||||
for (level_index, (mut level_matrix, mut generator)) in
|
||||
for (output_index, (mut level_matrix, mut generator)) in
|
||||
output.iter_mut().zip(gen_iter).enumerate()
|
||||
{
|
||||
let decomp_level = DecompositionLevel(level_index + 1);
|
||||
let decomp_level = DecompositionLevel(decomp_level_count.0 - output_index);
|
||||
// We scale the factor down from the native torus to whatever our torus is, the
|
||||
// encryption process will scale it back up
|
||||
let encoded = Scalar::ONE;
|
||||
|
||||
@@ -240,9 +240,10 @@ impl<'a> PseudoFourierGgswCiphertextView<'a> {
|
||||
pub fn into_levels(
|
||||
self,
|
||||
) -> impl DoubleEndedIterator<Item = PseudoFourierGgswLevelMatrixView<'a>> {
|
||||
let decomposition_level_count = self.decomposition_level_count.0;
|
||||
self.fourier
|
||||
.data
|
||||
.split_into(self.decomposition_level_count.0)
|
||||
.split_into(decomposition_level_count)
|
||||
.enumerate()
|
||||
.map(move |(i, slice)| {
|
||||
PseudoFourierGgswLevelMatrixView::new(
|
||||
@@ -250,7 +251,7 @@ impl<'a> PseudoFourierGgswCiphertextView<'a> {
|
||||
self.glwe_size_in,
|
||||
self.glwe_size_out,
|
||||
self.fourier.polynomial_size,
|
||||
DecompositionLevel(i + 1),
|
||||
DecompositionLevel(decomposition_level_count - i),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -148,11 +148,12 @@ impl<C: Container<Element = f64>> Fourier128GgswCiphertext<C> {
|
||||
where
|
||||
C: Split,
|
||||
{
|
||||
let decomposition_level_count = self.decomposition_level_count.0;
|
||||
izip!(
|
||||
self.data_re0.split_into(self.decomposition_level_count.0),
|
||||
self.data_re1.split_into(self.decomposition_level_count.0),
|
||||
self.data_im0.split_into(self.decomposition_level_count.0),
|
||||
self.data_im1.split_into(self.decomposition_level_count.0)
|
||||
self.data_re0.split_into(decomposition_level_count),
|
||||
self.data_re1.split_into(decomposition_level_count),
|
||||
self.data_im0.split_into(decomposition_level_count),
|
||||
self.data_im1.split_into(decomposition_level_count)
|
||||
)
|
||||
.enumerate()
|
||||
.map(move |(i, (data_re0, data_re1, data_im0, data_im1))| {
|
||||
@@ -163,7 +164,7 @@ impl<C: Container<Element = f64>> Fourier128GgswCiphertext<C> {
|
||||
data_im1,
|
||||
self.polynomial_size,
|
||||
self.glwe_size,
|
||||
DecompositionLevel(i + 1),
|
||||
DecompositionLevel(decomposition_level_count - i),
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -426,7 +427,7 @@ pub fn add_external_product_assign<Scalar, ContOut, ContGgsw, ContGlwe>(
|
||||
|
||||
// We loop through the levels (we reverse to match the order of the decomposition
|
||||
// iterator.)
|
||||
for ggsw_decomp_matrix in ggsw.into_levels().rev() {
|
||||
for ggsw_decomp_matrix in ggsw.into_levels() {
|
||||
// We retrieve the decomposition of this level.
|
||||
let (glwe_level, glwe_decomp_term, mut substack2) =
|
||||
collect_next_term(&mut decomposition, &mut substack1, align);
|
||||
|
||||
@@ -108,7 +108,7 @@ pub fn add_external_product_assign_split<ContOutLo, ContOutHi, ContGgsw, ContGlw
|
||||
|
||||
// We loop through the levels (we reverse to match the order of the decomposition
|
||||
// iterator.)
|
||||
for ggsw_decomp_matrix in ggsw.into_levels().rev() {
|
||||
for ggsw_decomp_matrix in ggsw.into_levels() {
|
||||
// We retrieve the decomposition of this level.
|
||||
assert_ne!(current_level, 0);
|
||||
let glwe_level = DecompositionLevel(current_level);
|
||||
|
||||
@@ -229,16 +229,17 @@ impl<C: Container<Element = c64>> FourierGgswLevelRow<C> {
|
||||
impl<'a> FourierGgswCiphertextView<'a> {
|
||||
/// Return an iterator over the level matrices.
|
||||
pub fn into_levels(self) -> impl DoubleEndedIterator<Item = FourierGgswLevelMatrixView<'a>> {
|
||||
let decomposition_level_count = self.decomposition_level_count.0;
|
||||
self.fourier
|
||||
.data
|
||||
.split_into(self.decomposition_level_count.0)
|
||||
.split_into(decomposition_level_count)
|
||||
.enumerate()
|
||||
.map(move |(i, slice)| {
|
||||
FourierGgswLevelMatrixView::new(
|
||||
slice,
|
||||
self.glwe_size,
|
||||
self.fourier.polynomial_size,
|
||||
DecompositionLevel(i + 1),
|
||||
DecompositionLevel(decomposition_level_count - i),
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -524,7 +525,7 @@ pub fn add_external_product_assign<Scalar>(
|
||||
);
|
||||
|
||||
// We loop through the levels (we reverse to match the order of the decomposition iterator.)
|
||||
ggsw.into_levels().rev().for_each(|ggsw_decomp_matrix| {
|
||||
ggsw.into_levels().for_each(|ggsw_decomp_matrix| {
|
||||
// We retrieve the decomposition of this level.
|
||||
let (glwe_level, glwe_decomp_term, mut substack2) =
|
||||
collect_next_term(&mut decomposition, &mut substack1, align);
|
||||
|
||||
@@ -314,8 +314,8 @@ pub fn circuit_bootstrap_boolean<Scalar: UnsignedTorus + CastInto<usize>>(
|
||||
let mut lwe_out_bs_buffer =
|
||||
LweCiphertext::from_container(&mut *lwe_out_bs_buffer_data, lwe_in.ciphertext_modulus());
|
||||
|
||||
for (decomposition_level_minus_one, mut ggsw_level_matrix) in ggsw_out.iter_mut().enumerate() {
|
||||
let decomposition_level = DecompositionLevel(decomposition_level_minus_one + 1);
|
||||
for (output_index, mut ggsw_level_matrix) in ggsw_out.iter_mut().enumerate() {
|
||||
let decomposition_level = DecompositionLevel(level_cbs.0 - output_index);
|
||||
homomorphic_shift_boolean(
|
||||
fourier_bsk,
|
||||
lwe_out_bs_buffer.as_mut_view(),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::high_level_api::keys::*;
|
||||
use crate::Tag;
|
||||
use std::convert::Infallible;
|
||||
use std::sync::Arc;
|
||||
use tfhe_versionable::deprecation::{Deprecable, Deprecated};
|
||||
use tfhe_versionable::{Upgrade, Version, VersionsDispatch};
|
||||
|
||||
@@ -28,66 +27,29 @@ impl Upgrade<ClientKey> for ClientKeyV0 {
|
||||
}
|
||||
}
|
||||
|
||||
// This type was previously versioned using a manual implementation with a conversion
|
||||
// to a type where the inner key was name `integer_key`
|
||||
#[derive(Version)]
|
||||
pub struct ServerKeyV0 {
|
||||
pub(crate) integer_key: Arc<IntegerServerKey>,
|
||||
}
|
||||
|
||||
impl Upgrade<ServerKeyV1> for ServerKeyV0 {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<ServerKeyV1, Self::Error> {
|
||||
Ok(ServerKeyV1 {
|
||||
key: self.integer_key,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Version)]
|
||||
pub struct ServerKeyV1 {
|
||||
pub(crate) key: Arc<IntegerServerKey>,
|
||||
}
|
||||
|
||||
impl Upgrade<ServerKey> for ServerKeyV1 {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<ServerKey, Self::Error> {
|
||||
Ok(ServerKey {
|
||||
key: self.key,
|
||||
tag: Tag::default(),
|
||||
})
|
||||
}
|
||||
impl Deprecable for ServerKey {
|
||||
const TYPE_NAME: &'static str = "ServerKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum ServerKeyVersions {
|
||||
V0(ServerKeyV0),
|
||||
V1(ServerKeyV1),
|
||||
V2(ServerKey),
|
||||
V0(Deprecated<ServerKey>),
|
||||
V1(Deprecated<ServerKey>),
|
||||
V2(Deprecated<ServerKey>),
|
||||
V3(ServerKey),
|
||||
}
|
||||
|
||||
#[derive(Version)]
|
||||
pub struct CompressedServerKeyV0 {
|
||||
pub(crate) integer_key: IntegerCompressedServerKey,
|
||||
}
|
||||
|
||||
impl Upgrade<CompressedServerKey> for CompressedServerKeyV0 {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<CompressedServerKey, Self::Error> {
|
||||
Ok(CompressedServerKey {
|
||||
integer_key: self.integer_key,
|
||||
tag: Tag::default(),
|
||||
})
|
||||
}
|
||||
impl Deprecable for CompressedServerKey {
|
||||
const TYPE_NAME: &'static str = "CompressedServerKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum CompressedServerKeyVersions {
|
||||
V0(CompressedServerKeyV0),
|
||||
V1(CompressedServerKey),
|
||||
V0(Deprecated<CompressedServerKey>),
|
||||
V1(Deprecated<CompressedServerKey>),
|
||||
V2(CompressedServerKey),
|
||||
}
|
||||
|
||||
#[derive(Version)]
|
||||
@@ -221,52 +183,28 @@ pub(crate) enum IntegerClientKeyVersions {
|
||||
|
||||
impl Deprecable for IntegerServerKey {
|
||||
const TYPE_NAME: &'static str = "IntegerServerKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.8";
|
||||
}
|
||||
|
||||
#[derive(Version)]
|
||||
pub struct IntegerServerKeyV2 {
|
||||
pub(crate) key: crate::integer::ServerKey,
|
||||
pub(crate) cpk_key_switching_key_material:
|
||||
Option<crate::integer::key_switching_key::KeySwitchingKeyMaterial>,
|
||||
pub(crate) compression_key: Option<crate::shortint::list_compression::CompressionKey>,
|
||||
pub(crate) decompression_key: Option<crate::shortint::list_compression::DecompressionKey>,
|
||||
}
|
||||
|
||||
impl Upgrade<IntegerServerKey> for IntegerServerKeyV2 {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<IntegerServerKey, Self::Error> {
|
||||
Ok(IntegerServerKey {
|
||||
key: self.key,
|
||||
cpk_key_switching_key_material: self.cpk_key_switching_key_material,
|
||||
compression_key: self
|
||||
.compression_key
|
||||
.map(|key| crate::integer::compression_keys::CompressionKey { key }),
|
||||
decompression_key: self
|
||||
.decompression_key
|
||||
.map(|key| crate::integer::compression_keys::DecompressionKey { key }),
|
||||
})
|
||||
}
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum IntegerServerKeyVersions {
|
||||
V0(Deprecated<IntegerServerKey>),
|
||||
V1(Deprecated<IntegerServerKey>),
|
||||
V2(IntegerServerKeyV2),
|
||||
V3(IntegerServerKey),
|
||||
V2(Deprecated<IntegerServerKey>),
|
||||
V3(Deprecated<IntegerServerKey>),
|
||||
V4(IntegerServerKey),
|
||||
}
|
||||
|
||||
impl Deprecable for IntegerCompressedServerKey {
|
||||
const TYPE_NAME: &'static str = "IntegerCompressedServerKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.9";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum IntegerCompressedServerKeyVersions {
|
||||
V0(Deprecated<IntegerCompressedServerKey>),
|
||||
V1(IntegerCompressedServerKey),
|
||||
V1(Deprecated<IntegerCompressedServerKey>),
|
||||
V2(IntegerCompressedServerKey),
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
@@ -281,7 +219,13 @@ pub(in crate::high_level_api) enum IntegerCompressedCompactPublicKeyVersions {
|
||||
V0(IntegerCompressedCompactPublicKey),
|
||||
}
|
||||
|
||||
impl Deprecable for KeySwitchingKey {
|
||||
const TYPE_NAME: &'static str = "KeySwitchingKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum KeySwitchingKeyVersions {
|
||||
V0(KeySwitchingKey),
|
||||
V0(Deprecated<KeySwitchingKey>),
|
||||
V1(KeySwitchingKey),
|
||||
}
|
||||
|
||||
@@ -18,22 +18,24 @@ pub enum KeySwitchingKeyVersions {
|
||||
|
||||
impl Deprecable for CompressedKeySwitchingKeyMaterial {
|
||||
const TYPE_NAME: &'static str = "CompressedKeySwitchingKeyMaterial";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.9";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum CompressedKeySwitchingKeyMaterialVersions {
|
||||
V0(Deprecated<CompressedKeySwitchingKeyMaterial>),
|
||||
V1(CompressedKeySwitchingKeyMaterial),
|
||||
V1(Deprecated<CompressedKeySwitchingKeyMaterial>),
|
||||
V2(CompressedKeySwitchingKeyMaterial),
|
||||
}
|
||||
|
||||
impl Deprecable for CompressedKeySwitchingKey {
|
||||
const TYPE_NAME: &'static str = "CompressedKeySwitchingKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.9";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum CompressedKeySwitchingKeyVersions {
|
||||
V0(Deprecated<CompressedKeySwitchingKey>),
|
||||
V1(CompressedKeySwitchingKey),
|
||||
V1(Deprecated<CompressedKeySwitchingKey>),
|
||||
V2(CompressedKeySwitchingKey),
|
||||
}
|
||||
|
||||
@@ -17,18 +17,25 @@ pub enum DecompressionKeyVersions {
|
||||
|
||||
impl Deprecable for CompressedCompressionKey {
|
||||
const TYPE_NAME: &'static str = "CompressedCompressionKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.9";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum CompressedCompressionKeyVersions {
|
||||
V0(Deprecated<CompressedCompressionKey>),
|
||||
V1(CompressedCompressionKey),
|
||||
V1(Deprecated<CompressedCompressionKey>),
|
||||
V2(CompressedCompressionKey),
|
||||
}
|
||||
|
||||
impl Deprecable for CompressedDecompressionKey {
|
||||
const TYPE_NAME: &'static str = "CompressedDecompressionKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum CompressedDecompressionKeyVersions {
|
||||
V0(CompressedDecompressionKey),
|
||||
V0(Deprecated<CompressedDecompressionKey>),
|
||||
V1(CompressedDecompressionKey),
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
|
||||
@@ -3,18 +3,25 @@ use tfhe_versionable::VersionsDispatch;
|
||||
|
||||
use crate::integer::{CompressedServerKey, ServerKey};
|
||||
|
||||
impl Deprecable for ServerKey {
|
||||
const TYPE_NAME: &'static str = "ServerKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum ServerKeyVersions {
|
||||
V0(ServerKey),
|
||||
V0(Deprecated<ServerKey>),
|
||||
V1(ServerKey),
|
||||
}
|
||||
|
||||
impl Deprecable for CompressedServerKey {
|
||||
const TYPE_NAME: &'static str = "CompressedServerKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.9";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum CompressedServerKeyVersions {
|
||||
V0(Deprecated<CompressedServerKey>),
|
||||
V1(CompressedServerKey),
|
||||
V1(Deprecated<CompressedServerKey>),
|
||||
V2(CompressedServerKey),
|
||||
}
|
||||
|
||||
@@ -18,22 +18,24 @@ pub enum KeySwitchingKeyVersions {
|
||||
|
||||
impl Deprecable for CompressedKeySwitchingKeyMaterial {
|
||||
const TYPE_NAME: &'static str = "CompressedKeySwitchingKeyMaterial";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.9";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum CompressedKeySwitchingKeyMaterialVersions {
|
||||
V0(Deprecated<CompressedKeySwitchingKeyMaterial>),
|
||||
V1(CompressedKeySwitchingKeyMaterial),
|
||||
V1(Deprecated<CompressedKeySwitchingKeyMaterial>),
|
||||
V2(CompressedKeySwitchingKeyMaterial),
|
||||
}
|
||||
|
||||
impl Deprecable for CompressedKeySwitchingKey {
|
||||
const TYPE_NAME: &'static str = "CompressedKeySwitchingKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.9";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum CompressedKeySwitchingKeyVersions {
|
||||
V0(Deprecated<CompressedKeySwitchingKey>),
|
||||
V1(CompressedKeySwitchingKey),
|
||||
V1(Deprecated<CompressedKeySwitchingKey>),
|
||||
V2(CompressedKeySwitchingKey),
|
||||
}
|
||||
|
||||
@@ -18,18 +18,25 @@ pub enum DecompressionKeyVersions {
|
||||
|
||||
impl Deprecable for CompressedCompressionKey {
|
||||
const TYPE_NAME: &'static str = "CompressedCompressionKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.9";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum CompressedCompressionKeyVersions {
|
||||
V0(Deprecated<CompressedCompressionKey>),
|
||||
V1(CompressedCompressionKey),
|
||||
V1(Deprecated<CompressedCompressionKey>),
|
||||
V2(CompressedCompressionKey),
|
||||
}
|
||||
|
||||
impl Deprecable for CompressedDecompressionKey {
|
||||
const TYPE_NAME: &'static str = "CompressedDecompressionKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum CompressedDecompressionKeyVersions {
|
||||
V0(CompressedDecompressionKey),
|
||||
V0(Deprecated<CompressedDecompressionKey>),
|
||||
V1(CompressedDecompressionKey),
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
|
||||
@@ -9,23 +9,36 @@ pub enum SerializableShortintBootstrappingKeyVersions<C: Container<Element = con
|
||||
V0(SerializableShortintBootstrappingKey<C>),
|
||||
}
|
||||
|
||||
impl Deprecable for ServerKey {
|
||||
const TYPE_NAME: &'static str = "ServerKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum ServerKeyVersions {
|
||||
V0(ServerKey),
|
||||
V0(Deprecated<ServerKey>),
|
||||
V1(ServerKey),
|
||||
}
|
||||
|
||||
impl Deprecable for ShortintCompressedBootstrappingKey {
|
||||
const TYPE_NAME: &'static str = "ShortintCompressedBootstrappingKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum ShortintCompressedBootstrappingKeyVersions {
|
||||
V0(ShortintCompressedBootstrappingKey),
|
||||
V0(Deprecated<ShortintCompressedBootstrappingKey>),
|
||||
V1(ShortintCompressedBootstrappingKey),
|
||||
}
|
||||
|
||||
impl Deprecable for CompressedServerKey {
|
||||
const TYPE_NAME: &'static str = "CompressedServerKey";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.9";
|
||||
const MIN_SUPPORTED_APP_VERSION: &'static str = "TFHE-rs v0.10";
|
||||
}
|
||||
|
||||
#[derive(VersionsDispatch)]
|
||||
pub enum CompressedServerKeyVersions {
|
||||
V0(Deprecated<CompressedServerKey>),
|
||||
V1(CompressedServerKey),
|
||||
V1(Deprecated<CompressedServerKey>),
|
||||
V2(CompressedServerKey),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user