diff --git a/tfhe/src/core_crypto/commons/parameters.rs b/tfhe/src/core_crypto/commons/parameters.rs index 6e648d234b..5db189200f 100644 --- a/tfhe/src/core_crypto/commons/parameters.rs +++ b/tfhe/src/core_crypto/commons/parameters.rs @@ -106,6 +106,10 @@ impl GlweSize { pub fn to_glwe_dimension(&self) -> GlweDimension { GlweDimension(self.0 - 1) } + + pub const fn to_glwe_ct_size(self, poly_size: PolynomialSize) -> usize { + self.0 * poly_size.0 + } } /// The number of polynomials of a GLWE mask, or the size of a GLWE secret key. diff --git a/tfhe/src/core_crypto/entities/glwe_ciphertext.rs b/tfhe/src/core_crypto/entities/glwe_ciphertext.rs index dd813441a6..eef29f1eec 100644 --- a/tfhe/src/core_crypto/entities/glwe_ciphertext.rs +++ b/tfhe/src/core_crypto/entities/glwe_ciphertext.rs @@ -643,9 +643,19 @@ where &self, glwe_ct_parameters: &GlweCiphertextConformanceParameters, ) -> bool { + let Self { + data, + polynomial_size, + ciphertext_modulus, + } = self; + check_encrypted_content_respects_mod(self, glwe_ct_parameters.ct_modulus) - && self.glwe_size() == glwe_ct_parameters.glwe_dim.to_glwe_size() - && self.polynomial_size() == glwe_ct_parameters.polynomial_size - && self.ciphertext_modulus() == glwe_ct_parameters.ct_modulus + && data.container_len() + == glwe_ct_parameters + .glwe_dim + .to_glwe_size() + .to_glwe_ct_size(glwe_ct_parameters.polynomial_size) + && *polynomial_size == glwe_ct_parameters.polynomial_size + && *ciphertext_modulus == glwe_ct_parameters.ct_modulus } } diff --git a/tfhe/src/core_crypto/entities/lwe_ciphertext.rs b/tfhe/src/core_crypto/entities/lwe_ciphertext.rs index 3396a2d4f9..fdabadeb60 100644 --- a/tfhe/src/core_crypto/entities/lwe_ciphertext.rs +++ b/tfhe/src/core_crypto/entities/lwe_ciphertext.rs @@ -761,9 +761,14 @@ where type ParameterSet = LweCiphertextParameters; fn is_conformant(&self, lwe_ct_parameters: &LweCiphertextParameters) -> bool { - check_encrypted_content_respects_mod(self, lwe_ct_parameters.ct_modulus) + let Self { + data, + ciphertext_modulus, + } = self; + + check_encrypted_content_respects_mod(data, lwe_ct_parameters.ct_modulus) && self.lwe_size() == lwe_ct_parameters.lwe_dim.to_lwe_size() - && self.ciphertext_modulus() == lwe_ct_parameters.ct_modulus + && *ciphertext_modulus == lwe_ct_parameters.ct_modulus } } diff --git a/tfhe/src/core_crypto/entities/lwe_compact_ciphertext_list.rs b/tfhe/src/core_crypto/entities/lwe_compact_ciphertext_list.rs index 2c26931f2c..0dc81b4e71 100644 --- a/tfhe/src/core_crypto/entities/lwe_compact_ciphertext_list.rs +++ b/tfhe/src/core_crypto/entities/lwe_compact_ciphertext_list.rs @@ -343,17 +343,24 @@ impl ParameterSetConformant for LweCompactCiphertextListOwne type ParameterSet = LweCiphertextListParameters; fn is_conformant(&self, param: &LweCiphertextListParameters) -> bool { + let LweCompactCiphertextListOwned { + data, + lwe_size, + lwe_ciphertext_count, + ciphertext_modulus, + } = self; + param .lwe_ciphertext_count_constraint - .is_valid(self.lwe_ciphertext_count.0) - && self.data.len() + .is_valid(lwe_ciphertext_count.0) + && data.len() == lwe_compact_ciphertext_list_size( - self.lwe_size.to_lwe_dimension(), - self.lwe_ciphertext_count, + lwe_size.to_lwe_dimension(), + *lwe_ciphertext_count, ) && check_encrypted_content_respects_mod(self, param.ct_modulus) - && self.lwe_size == param.lwe_dim.to_lwe_size() - && self.ciphertext_modulus == param.ct_modulus + && *lwe_size == param.lwe_dim.to_lwe_size() + && *ciphertext_modulus == param.ct_modulus } } diff --git a/tfhe/src/core_crypto/entities/seeded_lwe_ciphertext.rs b/tfhe/src/core_crypto/entities/seeded_lwe_ciphertext.rs index 1b8ea8c47a..16f7c1b5d6 100644 --- a/tfhe/src/core_crypto/entities/seeded_lwe_ciphertext.rs +++ b/tfhe/src/core_crypto/entities/seeded_lwe_ciphertext.rs @@ -25,11 +25,18 @@ impl ParameterSetConformant for SeededLweCiphertext { type ParameterSet = LweCiphertextParameters; fn is_conformant(&self, lwe_ct_parameters: &LweCiphertextParameters) -> bool { + let Self { + data, + lwe_size, + compression_seed: _, + ciphertext_modulus, + } = self; + check_encrypted_content_respects_mod::( - &std::slice::from_ref(self.get_body().data), + &std::slice::from_ref(data), lwe_ct_parameters.ct_modulus, - ) && self.lwe_size == lwe_ct_parameters.lwe_dim.to_lwe_size() - && self.ciphertext_modulus() == lwe_ct_parameters.ct_modulus + ) && *lwe_size == lwe_ct_parameters.lwe_dim.to_lwe_size() + && *ciphertext_modulus == lwe_ct_parameters.ct_modulus } } diff --git a/tfhe/src/high_level_api/booleans/base.rs b/tfhe/src/high_level_api/booleans/base.rs index 69da74aaa1..0723a0efe2 100644 --- a/tfhe/src/high_level_api/booleans/base.rs +++ b/tfhe/src/high_level_api/booleans/base.rs @@ -81,7 +81,11 @@ impl ParameterSetConformant for FheBool { type ParameterSet = FheBoolConformanceParams; fn is_conformant(&self, params: &FheBoolConformanceParams) -> bool { - self.ciphertext.on_cpu().0.is_conformant(¶ms.0) + let Self { ciphertext } = self; + + let BooleanBlock(block) = &*ciphertext.on_cpu(); + + block.is_conformant(¶ms.0) } } diff --git a/tfhe/src/high_level_api/compact_list.rs b/tfhe/src/high_level_api/compact_list.rs index d774243ce0..9d48b3bc5a 100644 --- a/tfhe/src/high_level_api/compact_list.rs +++ b/tfhe/src/high_level_api/compact_list.rs @@ -91,7 +91,9 @@ impl ParameterSetConformant for CompactCiphertextList { type ParameterSet = CompactCiphertextListConformanceParams; fn is_conformant(&self, parameter_set: &Self::ParameterSet) -> bool { - self.0.is_conformant(parameter_set) + let Self(list) = self; + + list.is_conformant(parameter_set) } } diff --git a/tfhe/src/high_level_api/integers/signed/base.rs b/tfhe/src/high_level_api/integers/signed/base.rs index abe998b121..671b215b5e 100644 --- a/tfhe/src/high_level_api/integers/signed/base.rs +++ b/tfhe/src/high_level_api/integers/signed/base.rs @@ -75,7 +75,9 @@ impl ParameterSetConformant for FheInt { type ParameterSet = FheIntConformanceParams; fn is_conformant(&self, params: &FheIntConformanceParams) -> bool { - self.ciphertext.on_cpu().is_conformant(¶ms.params) + let Self { ciphertext, id: _ } = self; + + ciphertext.on_cpu().is_conformant(¶ms.params) } } diff --git a/tfhe/src/high_level_api/integers/signed/compressed.rs b/tfhe/src/high_level_api/integers/signed/compressed.rs index 0e7cf6ee7e..2529e75f63 100644 --- a/tfhe/src/high_level_api/integers/signed/compressed.rs +++ b/tfhe/src/high_level_api/integers/signed/compressed.rs @@ -108,7 +108,9 @@ impl ParameterSetConformant for CompressedFheInt { type ParameterSet = FheIntConformanceParams; fn is_conformant(&self, params: &FheIntConformanceParams) -> bool { - self.ciphertext.is_conformant(¶ms.params) + let Self { ciphertext, id: _ } = self; + + ciphertext.is_conformant(¶ms.params) } } diff --git a/tfhe/src/high_level_api/integers/unsigned/base.rs b/tfhe/src/high_level_api/integers/unsigned/base.rs index 2f58b43fba..9ee843aed1 100644 --- a/tfhe/src/high_level_api/integers/unsigned/base.rs +++ b/tfhe/src/high_level_api/integers/unsigned/base.rs @@ -114,7 +114,9 @@ impl ParameterSetConformant for FheUint { type ParameterSet = FheUintConformanceParams; fn is_conformant(&self, params: &FheUintConformanceParams) -> bool { - self.ciphertext.on_cpu().is_conformant(¶ms.params) + let Self { ciphertext, id: _ } = self; + + ciphertext.on_cpu().is_conformant(¶ms.params) } } diff --git a/tfhe/src/high_level_api/integers/unsigned/compressed.rs b/tfhe/src/high_level_api/integers/unsigned/compressed.rs index 92c1ba532c..078c6be333 100644 --- a/tfhe/src/high_level_api/integers/unsigned/compressed.rs +++ b/tfhe/src/high_level_api/integers/unsigned/compressed.rs @@ -112,7 +112,9 @@ impl ParameterSetConformant for CompressedFheUint { type ParameterSet = FheUintConformanceParams; fn is_conformant(&self, params: &FheUintConformanceParams) -> bool { - self.ciphertext.is_conformant(¶ms.params) + let Self { ciphertext, id: _ } = self; + + ciphertext.is_conformant(¶ms.params) } } diff --git a/tfhe/src/integer/ciphertext/compact_list.rs b/tfhe/src/integer/ciphertext/compact_list.rs index 57b779e027..18b0470b06 100644 --- a/tfhe/src/integer/ciphertext/compact_list.rs +++ b/tfhe/src/integer/ciphertext/compact_list.rs @@ -307,7 +307,9 @@ impl ParameterSetConformant for CompactCiphertextList { type ParameterSet = CompactCiphertextListConformanceParams; fn is_conformant(&self, params: &CompactCiphertextListConformanceParams) -> bool { - if !params.num_elements_constraint.is_valid(self.info.len()) { + let Self { ct_list: _, info } = self; + + if !params.num_elements_constraint.is_valid(info.len()) { return false; } @@ -520,7 +522,9 @@ impl CompactCiphertextList { &self, shortint_params: CiphertextConformanceParams, ) -> bool { - let mut num_blocks: usize = self.info.iter().copied().map(DataKind::num_blocks).sum(); + let Self { ct_list, info } = self; + + let mut num_blocks: usize = info.iter().copied().map(DataKind::num_blocks).sum(); // This expects packing, halve the number of blocks with enough capacity if shortint_params.degree.get() == (shortint_params.message_modulus.0 * shortint_params.carry_modulus.0) - 1 @@ -529,7 +533,7 @@ impl CompactCiphertextList { } let shortint_list_params = shortint_params .to_ct_list_conformance_parameters(ListSizeConstraint::exact_size(num_blocks)); - self.ct_list.is_conformant(&shortint_list_params) + ct_list.is_conformant(&shortint_list_params) } } diff --git a/tfhe/src/integer/ciphertext/compressed_modulus_switched_ciphertext.rs b/tfhe/src/integer/ciphertext/compressed_modulus_switched_ciphertext.rs index f0174ef1bb..c90be4043e 100644 --- a/tfhe/src/integer/ciphertext/compressed_modulus_switched_ciphertext.rs +++ b/tfhe/src/integer/ciphertext/compressed_modulus_switched_ciphertext.rs @@ -46,7 +46,9 @@ impl ParameterSetConformant for CompressedModulusSwitchedRadixCiphertext { type ParameterSet = RadixCiphertextConformanceParams; fn is_conformant(&self, params: &RadixCiphertextConformanceParams) -> bool { - self.0.is_conformant(params) + let Self(ct) = self; + + ct.is_conformant(params) } } @@ -86,7 +88,9 @@ impl ParameterSetConformant for CompressedModulusSwitchedSignedRadixCiphertext { type ParameterSet = RadixCiphertextConformanceParams; fn is_conformant(&self, params: &RadixCiphertextConformanceParams) -> bool { - self.0.is_conformant(params) + let Self(ct) = self; + + ct.is_conformant(params) } } @@ -101,6 +105,11 @@ impl ParameterSetConformant for CompressedModulusSwitchedRadixCiphertextGeneric type ParameterSet = RadixCiphertextConformanceParams; fn is_conformant(&self, params: &RadixCiphertextConformanceParams) -> bool { + let Self { + paired_blocks, + last_block, + } = self; + let mut shortint_params = params.shortint_params; shortint_params.degree = Degree::new( @@ -111,15 +120,14 @@ impl ParameterSetConformant for CompressedModulusSwitchedRadixCiphertextGeneric .get(), ); - let paired_blocks_len_ok = self.paired_blocks.len() == params.num_blocks_per_integer / 2; + let paired_blocks_len_ok = paired_blocks.len() == params.num_blocks_per_integer / 2; - let paired_blocks_ok = self - .paired_blocks + let paired_blocks_ok = paired_blocks .iter() .all(|block| block.is_conformant(&shortint_params)); let last_item_ok = if params.num_blocks_per_integer % 2 == 1 { - self.last_block.as_ref().map_or(false, |last_block| { + last_block.as_ref().map_or(false, |last_block| { last_block.is_conformant(¶ms.shortint_params) }) } else { diff --git a/tfhe/src/shortint/ciphertext/compact_list.rs b/tfhe/src/shortint/ciphertext/compact_list.rs index ccdd4d5480..0b350ded1e 100644 --- a/tfhe/src/shortint/ciphertext/compact_list.rs +++ b/tfhe/src/shortint/ciphertext/compact_list.rs @@ -39,6 +39,7 @@ impl ParameterSetConformant for CompactCiphertextList { expansion_kind, noise_level, } = self; + let CiphertextListConformanceParams { ct_list_params, message_modulus: param_message_modulus, @@ -47,6 +48,7 @@ impl ParameterSetConformant for CompactCiphertextList { noise_level: param_noise_level, expansion_kind: param_expansion_kind, } = param; + ct_list.is_conformant(ct_list_params) && *message_modulus == *param_message_modulus && *carry_modulus == *param_carry_modulus diff --git a/tfhe/src/shortint/ciphertext/compressed.rs b/tfhe/src/shortint/ciphertext/compressed.rs index 6643e305f5..cbc592c852 100644 --- a/tfhe/src/shortint/ciphertext/compressed.rs +++ b/tfhe/src/shortint/ciphertext/compressed.rs @@ -27,12 +27,21 @@ impl ParameterSetConformant for CompressedCiphertext { type ParameterSet = CiphertextConformanceParams; fn is_conformant(&self, param: &CiphertextConformanceParams) -> bool { - self.ct.is_conformant(¶m.ct_params) - && self.message_modulus == param.message_modulus - && self.carry_modulus == param.carry_modulus - && self.pbs_order == param.pbs_order - && self.degree == param.degree - && self.noise_level == param.noise_level + let Self { + ct, + degree, + message_modulus, + carry_modulus, + pbs_order, + noise_level, + } = self; + + ct.is_conformant(¶m.ct_params) + && *message_modulus == param.message_modulus + && *carry_modulus == param.carry_modulus + && *pbs_order == param.pbs_order + && *degree == param.degree + && *noise_level == param.noise_level } } diff --git a/tfhe/src/shortint/ciphertext/compressed_ciphertext_list.rs b/tfhe/src/shortint/ciphertext/compressed_ciphertext_list.rs index 892a992fbc..304df183e7 100644 --- a/tfhe/src/shortint/ciphertext/compressed_ciphertext_list.rs +++ b/tfhe/src/shortint/ciphertext/compressed_ciphertext_list.rs @@ -23,37 +23,44 @@ impl ParameterSetConformant for CompressedCiphertextList { type ParameterSet = CompressedCiphertextConformanceParams; fn is_conformant(&self, params: &CompressedCiphertextConformanceParams) -> bool { - let len = self.modulus_switched_glwe_ciphertext_list.len(); + let Self { + modulus_switched_glwe_ciphertext_list, + ciphertext_modulus, + message_modulus, + carry_modulus, + pbs_order, + lwe_per_glwe, + count, + } = self; + + let len = modulus_switched_glwe_ciphertext_list.len(); if len == 0 { return true; } - let count_is_ok = self.modulus_switched_glwe_ciphertext_list[..len - 1] - .iter() - .all(|a| a.bodies_count() == params.lwe_per_glwe) - && self - .modulus_switched_glwe_ciphertext_list - .last() - .unwrap() - .bodies_count() - .0 - <= params.lwe_per_glwe.0; + let last_body_count = modulus_switched_glwe_ciphertext_list + .last() + .unwrap() + .bodies_count() + .0; + + let count_is_ok = count.0.div_ceil(lwe_per_glwe.0) == len + && modulus_switched_glwe_ciphertext_list[..len - 1] + .iter() + .all(|a| a.bodies_count() == params.lwe_per_glwe) + && last_body_count <= params.lwe_per_glwe.0 + && (len - 1) * params.lwe_per_glwe.0 + last_body_count == count.0; count_is_ok - && self - .modulus_switched_glwe_ciphertext_list + && modulus_switched_glwe_ciphertext_list .iter() - .all(|glwe| { - glwe.glwe_dimension() == params.ct_params.glwe_dim - && glwe.polynomial_size() == params.ct_params.polynomial_size - && glwe.uncompressed_ciphertext_modulus() == params.ct_params.ct_modulus - }) - && self.lwe_per_glwe.0 <= params.ct_params.polynomial_size.0 - && self.lwe_per_glwe == params.lwe_per_glwe - && self.ciphertext_modulus == params.ct_params.ct_modulus - && self.message_modulus == params.message_modulus - && self.carry_modulus == params.carry_modulus - && self.pbs_order == params.pbs_order + .all(|glwe| glwe.is_conformant(¶ms.ct_params)) + && lwe_per_glwe.0 <= params.ct_params.polynomial_size.0 + && *lwe_per_glwe == params.lwe_per_glwe + && *ciphertext_modulus == params.ct_params.ct_modulus + && *message_modulus == params.message_modulus + && *carry_modulus == params.carry_modulus + && *pbs_order == params.pbs_order } } diff --git a/tfhe/src/shortint/ciphertext/compressed_modulus_switched_ciphertext.rs b/tfhe/src/shortint/ciphertext/compressed_modulus_switched_ciphertext.rs index d65fd71f8e..8a9b59675c 100644 --- a/tfhe/src/shortint/ciphertext/compressed_modulus_switched_ciphertext.rs +++ b/tfhe/src/shortint/ciphertext/compressed_modulus_switched_ciphertext.rs @@ -52,12 +52,19 @@ impl ParameterSetConformant for CompressedModulusSwitchedCiphertext { type ParameterSet = CiphertextConformanceParams; fn is_conformant(&self, param: &CiphertextConformanceParams) -> bool { - self.compressed_modulus_switched_lwe_ciphertext - .is_conformant(¶m.ct_params) - && self.message_modulus == param.message_modulus - && self.carry_modulus == param.carry_modulus - && self.pbs_order == param.pbs_order - && self.degree == param.degree + let Self { + compressed_modulus_switched_lwe_ciphertext, + degree, + message_modulus, + carry_modulus, + pbs_order, + } = self; + + compressed_modulus_switched_lwe_ciphertext.is_conformant(¶m.ct_params) + && *message_modulus == param.message_modulus + && *carry_modulus == param.carry_modulus + && *pbs_order == param.pbs_order + && *degree == param.degree } } diff --git a/tfhe/src/shortint/ciphertext/standard.rs b/tfhe/src/shortint/ciphertext/standard.rs index 21c9ee9652..c93d7a78c7 100644 --- a/tfhe/src/shortint/ciphertext/standard.rs +++ b/tfhe/src/shortint/ciphertext/standard.rs @@ -29,12 +29,21 @@ impl ParameterSetConformant for Ciphertext { type ParameterSet = CiphertextConformanceParams; fn is_conformant(&self, param: &CiphertextConformanceParams) -> bool { - self.ct.is_conformant(¶m.ct_params) - && self.message_modulus == param.message_modulus - && self.carry_modulus == param.carry_modulus - && self.pbs_order == param.pbs_order - && self.degree == param.degree - && self.noise_level == param.noise_level + let Self { + ct, + degree, + noise_level, + message_modulus, + carry_modulus, + pbs_order, + } = self; + + ct.is_conformant(¶m.ct_params) + && *message_modulus == param.message_modulus + && *carry_modulus == param.carry_modulus + && *pbs_order == param.pbs_order + && *degree == param.degree + && *noise_level == param.noise_level } }