From 040e28d82281b492a17c7ca6c663917f96570ce3 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 11 Sep 2024 12:08:56 -0300 Subject: [PATCH] chore(gpu): downgrade compression conversion tests to become doc tests --- .../gpu/entities/glwe_ciphertext_list.rs | 45 +-- .../ciphertext/compressed_ciphertext_list.rs | 341 +++++++++--------- .../gpu/list_compression/server_keys.rs | 65 ++-- 3 files changed, 195 insertions(+), 256 deletions(-) diff --git a/tfhe/src/core_crypto/gpu/entities/glwe_ciphertext_list.rs b/tfhe/src/core_crypto/gpu/entities/glwe_ciphertext_list.rs index d7eb6b8f37..bde72221b1 100644 --- a/tfhe/src/core_crypto/gpu/entities/glwe_ciphertext_list.rs +++ b/tfhe/src/core_crypto/gpu/entities/glwe_ciphertext_list.rs @@ -2,7 +2,7 @@ use crate::core_crypto::gpu::vec::CudaVec; use crate::core_crypto::gpu::{CudaGlweList, CudaStreams}; use crate::core_crypto::prelude::{ glwe_ciphertext_size, CiphertextModulus, Container, GlweCiphertext, GlweCiphertextCount, - GlweCiphertextList, GlweDimension, GlweSize, PolynomialSize, UnsignedInteger, + GlweCiphertextList, GlweDimension, PolynomialSize, UnsignedInteger, }; /// A structure representing a vector of GLWE ciphertexts with 64 bits of precision on the GPU. @@ -68,49 +68,6 @@ impl CudaGlweCiphertextList { Self(cuda_glwe_list) } - pub fn from_container>( - container: &C, - glwe_size: GlweSize, - polynomial_size: PolynomialSize, - ciphertext_modulus: CiphertextModulus, - streams: &CudaStreams, - ) -> Self { - assert!( - container.container_len() % glwe_ciphertext_size(glwe_size, polynomial_size) == 0, - "The provided container length is not valid. \ - It needs to be dividable by glwe_size * polynomial_size. \ - Got container length: {}, glwe_size: {glwe_size:?}, polynomial_size: {polynomial_size:?}.", - container.container_len() - ); - - let glwe_dimension = glwe_size.to_glwe_dimension(); - let glwe_ciphertext_count = GlweCiphertextCount( - container.container_len() / glwe_ciphertext_size(glwe_size, polynomial_size), - ); - - let mut d_vec = CudaVec::new( - glwe_ciphertext_size(glwe_dimension.to_glwe_size(), polynomial_size) - * glwe_ciphertext_count.0, - streams, - 0, - ); - // Copy to the GPU - unsafe { - d_vec.copy_from_cpu_async(container.as_ref(), streams, 0); - } - streams.synchronize(); - - let cuda_glwe_list = CudaGlweList { - d_vec, - glwe_ciphertext_count, - glwe_dimension, - polynomial_size, - ciphertext_modulus, - }; - - Self(cuda_glwe_list) - } - pub(crate) fn to_glwe_ciphertext_list( &self, streams: &CudaStreams, diff --git a/tfhe/src/integer/gpu/ciphertext/compressed_ciphertext_list.rs b/tfhe/src/integer/gpu/ciphertext/compressed_ciphertext_list.rs index f22e300ab8..1153e114b3 100644 --- a/tfhe/src/integer/gpu/ciphertext/compressed_ciphertext_list.rs +++ b/tfhe/src/integer/gpu/ciphertext/compressed_ciphertext_list.rs @@ -1,4 +1,5 @@ use crate::core_crypto::entities::packed_integers::PackedIntegers; +use crate::core_crypto::entities::GlweCiphertextList; use crate::core_crypto::gpu::glwe_ciphertext_list::CudaGlweCiphertextList; use crate::core_crypto::gpu::CudaStreams; use crate::core_crypto::prelude::compressed_modulus_switched_glwe_ciphertext::CompressedModulusSwitchedGlweCiphertext; @@ -7,17 +8,14 @@ use crate::core_crypto::prelude::{ }; use crate::integer::ciphertext::{CompressedCiphertextList, DataKind}; use crate::integer::gpu::ciphertext::boolean_value::CudaBooleanBlock; -use crate::integer::gpu::ciphertext::info::CudaBlockInfo; use crate::integer::gpu::ciphertext::{ CudaRadixCiphertext, CudaSignedRadixCiphertext, CudaUnsignedRadixCiphertext, }; use crate::integer::gpu::list_compression::server_keys::{ CudaCompressionKey, CudaDecompressionKey, CudaPackedGlweCiphertext, }; -use crate::shortint::ciphertext::{ - CompressedCiphertextList as ShortintCompressedCiphertextList, NoiseLevel, -}; -use crate::shortint::server_key::generate_lookup_table; +use crate::shortint::ciphertext::CompressedCiphertextList as ShortintCompressedCiphertextList; +use crate::shortint::PBSOrder; use itertools::Itertools; pub struct CudaCompressedCiphertextList { @@ -59,6 +57,91 @@ impl CudaCompressedCiphertextList { ) } + /// ```rust + /// use tfhe::core_crypto::gpu::CudaStreams; + /// use tfhe::integer::{BooleanBlock, ClientKey, RadixCiphertext, SignedRadixCiphertext}; + /// use tfhe::integer::ciphertext::CompressedCiphertextListBuilder; + /// use tfhe::integer::gpu::ciphertext::boolean_value::CudaBooleanBlock; + /// use tfhe::integer::gpu::ciphertext::compressed_ciphertext_list::CudaCompressedCiphertextListBuilder; + /// use tfhe::integer::gpu::ciphertext::{CudaSignedRadixCiphertext, CudaUnsignedRadixCiphertext}; + /// use tfhe::integer::gpu::gen_keys_radix_gpu; + /// use tfhe::shortint::parameters::list_compression::COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64; + /// use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64; + /// + /// let cks = ClientKey::new(PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64); + /// + /// let private_compression_key = + /// cks.new_compression_private_key(COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64); + /// + /// let streams = CudaStreams::new_multi_gpu(); + /// + /// let num_blocks = 32; + /// let (radix_cks, _) = gen_keys_radix_gpu( + /// PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64, + /// num_blocks, + /// &streams, + /// ); + /// let (compressed_compression_key, compressed_decompression_key) = + /// radix_cks.new_compressed_compression_decompression_keys(&private_compression_key); + /// + /// let cuda_compression_key = compressed_compression_key.decompress_to_cuda(&streams); + /// + /// let compression_key = compressed_compression_key.decompress(); + /// let decompression_key = compressed_decompression_key.decompress(); + /// + /// let ct1 = radix_cks.encrypt(3_u32); + /// let ct2 = radix_cks.encrypt_signed(-2); + /// let ct3 = radix_cks.encrypt_bool(true); + /// + /// /// Copy to GPU + /// let d_ct1 = CudaUnsignedRadixCiphertext::from_radix_ciphertext(&ct1, &streams); + /// let d_ct2 = CudaSignedRadixCiphertext::from_signed_radix_ciphertext(&ct2, &streams); + /// let d_ct3 = CudaBooleanBlock::from_boolean_block(&ct3, &streams); + /// + /// let cuda_compressed = CudaCompressedCiphertextListBuilder::new() + /// .push(d_ct1, &streams) + /// .push(d_ct2, &streams) + /// .push(d_ct3, &streams) + /// .build(&cuda_compression_key, &streams); + /// + /// let reference_compressed = CompressedCiphertextListBuilder::new() + /// .push(ct1) + /// .push(ct2) + /// .push(ct3) + /// .build(&compression_key); + /// + /// let converted_compressed = cuda_compressed.to_compressed_ciphertext_list(&streams); + /// + /// let decompressed1: RadixCiphertext = converted_compressed + /// .get(0, &decompression_key) + /// .unwrap() + /// .unwrap(); + /// let reference_decompressed1 = reference_compressed + /// .get(0, &decompression_key) + /// .unwrap() + /// .unwrap(); + /// assert_eq!(decompressed1, reference_decompressed1); + /// + /// let decompressed2: SignedRadixCiphertext = converted_compressed + /// .get(1, &decompression_key) + /// .unwrap() + /// .unwrap(); + /// let reference_decompressed2 = reference_compressed + /// .get(1, &decompression_key) + /// .unwrap() + /// .unwrap(); + /// assert_eq!(decompressed2, reference_decompressed2); + /// + /// let decompressed3: BooleanBlock = converted_compressed + /// .get(2, &decompression_key) + /// .unwrap() + /// .unwrap(); + /// let reference_decompressed3 = reference_compressed + /// .get(2, &decompression_key) + /// .unwrap() + /// .unwrap(); + /// assert_eq!(decompressed3, reference_decompressed3); + /// ``` pub fn to_compressed_ciphertext_list(&self, streams: &CudaStreams) -> CompressedCiphertextList { let glwe_list = self .packed_list @@ -66,10 +149,8 @@ impl CudaCompressedCiphertextList { .to_glwe_ciphertext_list(streams); let ciphertext_modulus = self.packed_list.glwe_ciphertext_list.ciphertext_modulus(); - let first_element = self.packed_list.block_info.first().unwrap(); - let message_modulus = first_element.message_modulus; - let carry_modulus = first_element.carry_modulus; - let pbs_order = first_element.pbs_order; + let message_modulus = self.packed_list.message_modulus; + let carry_modulus = self.packed_list.carry_modulus; let lwe_per_glwe = self.packed_list.lwe_per_glwe; let storage_log_modulus = self.packed_list.storage_log_modulus; @@ -97,6 +178,7 @@ impl CudaCompressedCiphertextList { .collect_vec(); let count = CiphertextCount(self.packed_list.bodies_count); + let pbs_order = PBSOrder::KeyswitchBootstrap; let packed_list = ShortintCompressedCiphertextList { modulus_switched_glwe_ciphertext_list, ciphertext_modulus, @@ -115,6 +197,70 @@ impl CudaCompressedCiphertextList { } impl CompressedCiphertextList { + /// ```rust + /// use tfhe::core_crypto::gpu::CudaStreams; + /// use tfhe::integer::ciphertext::CompressedCiphertextListBuilder; + /// use tfhe::integer::ClientKey; + /// use tfhe::integer::gpu::ciphertext::{CudaSignedRadixCiphertext, CudaUnsignedRadixCiphertext}; + /// use tfhe::integer::gpu::ciphertext::boolean_value::CudaBooleanBlock; + /// use tfhe::integer::gpu::gen_keys_radix_gpu; + /// use tfhe::shortint::parameters::list_compression::COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64; + /// use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64; + /// + /// let cks = ClientKey::new(PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64); + /// + /// let private_compression_key = + /// cks.new_compression_private_key(COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64); + /// + /// let streams = CudaStreams::new_multi_gpu(); + /// + /// let num_blocks = 32; + /// let (radix_cks, _) = gen_keys_radix_gpu( + /// PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64, + /// num_blocks, + /// &streams, + /// ); + /// let (compressed_compression_key, compressed_decompression_key) = + /// radix_cks.new_compressed_compression_decompression_keys(&private_compression_key); + /// + /// let cuda_decompression_key = + /// compressed_decompression_key.decompress_to_cuda(radix_cks.parameters(), &streams); + /// + /// let compression_key = compressed_compression_key.decompress(); + /// + /// let ct1 = radix_cks.encrypt(3_u32); + /// let ct2 = radix_cks.encrypt_signed(-2); + /// let ct3 = radix_cks.encrypt_bool(true); + /// + /// let compressed = CompressedCiphertextListBuilder::new() + /// .push(ct1) + /// .push(ct2) + /// .push(ct3) + /// .build(&compression_key); + /// + /// let cuda_compressed = compressed.to_cuda_compressed_ciphertext_list(&streams); + /// + /// let d_decompressed1 = CudaUnsignedRadixCiphertext { + /// ciphertext: cuda_compressed.get(0, &cuda_decompression_key, &streams), + /// }; + /// let decompressed1 = d_decompressed1.to_radix_ciphertext(&streams); + /// let decrypted: u32 = radix_cks.decrypt(&decompressed1); + /// assert_eq!(decrypted, 3_u32); + /// + /// let d_decompressed2 = CudaSignedRadixCiphertext { + /// ciphertext: cuda_compressed.get(1, &cuda_decompression_key, &streams), + /// }; + /// let decompressed2 = d_decompressed2.to_signed_radix_ciphertext(&streams); + /// let decrypted: i32 = radix_cks.decrypt_signed(&decompressed2); + /// assert_eq!(decrypted, -2); + /// + /// let d_decompressed3 = CudaBooleanBlock::from_cuda_radix_ciphertext( + /// cuda_compressed.get(2, &cuda_decompression_key, &streams), + /// ); + /// let decompressed3 = d_decompressed3.to_boolean_block(&streams); + /// let decrypted = radix_cks.decrypt_bool(&decompressed3); + /// assert!(decrypted); + /// ``` pub fn to_cuda_compressed_ciphertext_list( &self, streams: &CudaStreams, @@ -129,25 +275,8 @@ impl CompressedCiphertextList { let initial_len = first_ct.packed_integers.initial_len; let bodies_count = first_ct.bodies_count.0; - // To-do: is there a better way to calculate degree? - let carry_extract = generate_lookup_table( - first_ct.glwe_dimension.to_glwe_size(), - first_ct.polynomial_size, - self.packed_list.ciphertext_modulus, - self.packed_list.message_modulus, - self.packed_list.carry_modulus, - |x| x / self.packed_list.message_modulus.0 as u64, - ); - - let first_block_info = CudaBlockInfo { - degree: carry_extract.degree, - message_modulus: self.packed_list.message_modulus, - carry_modulus: self.packed_list.carry_modulus, - pbs_order: self.packed_list.pbs_order, - noise_level: NoiseLevel::NOMINAL, - }; - - let block_info = vec![first_block_info; bodies_count]; + let message_modulus = self.packed_list.message_modulus; + let carry_modulus = self.packed_list.carry_modulus; let mut data = modulus_switched_glwe_ciphertext_list .iter() @@ -161,16 +290,20 @@ impl CompressedCiphertextList { self.packed_list.modulus_switched_glwe_ciphertext_list.len() * glwe_ciphertext_size, 0, ); + let glwe_ciphertext_list = GlweCiphertextList::from_container( + data.as_slice(), + first_ct.glwe_dimension.to_glwe_size(), + first_ct.polynomial_size, + self.packed_list.ciphertext_modulus, + ); CudaCompressedCiphertextList { packed_list: CudaPackedGlweCiphertext { - glwe_ciphertext_list: CudaGlweCiphertextList::from_container( - &data, - first_ct.glwe_dimension.to_glwe_size(), - first_ct.polynomial_size, - self.packed_list.ciphertext_modulus, + glwe_ciphertext_list: CudaGlweCiphertextList::from_glwe_ciphertext_list( + &glwe_ciphertext_list, streams, ), - block_info, + message_modulus, + carry_modulus, bodies_count, storage_log_modulus, lwe_per_glwe, @@ -270,9 +403,8 @@ impl CudaCompressedCiphertextListBuilder { #[cfg(test)] mod tests { use super::*; - use crate::integer::ciphertext::CompressedCiphertextListBuilder; use crate::integer::gpu::gen_keys_radix_gpu; - use crate::integer::{BooleanBlock, ClientKey, RadixCiphertext, SignedRadixCiphertext}; + use crate::integer::ClientKey; use crate::shortint::parameters::list_compression::COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64; use crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64; @@ -325,143 +457,6 @@ mod tests { let decrypted: i32 = radix_cks.decrypt_signed(&decompressed2); assert_eq!(decrypted, -2); - let d_decompressed3 = CudaBooleanBlock::from_cuda_radix_ciphertext( - cuda_compressed.get(2, &cuda_decompression_key, &streams), - ); - let decompressed3 = d_decompressed3.to_boolean_block(&streams); - let decrypted = radix_cks.decrypt_bool(&decompressed3); - assert!(decrypted); - } - } - #[test] - fn test_gpu_compressed_ciphertext_conversion_to_cpu() { - let cks = ClientKey::new(PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64); - - let private_compression_key = - cks.new_compression_private_key(COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64); - - let streams = CudaStreams::new_multi_gpu(); - - let num_blocks = 32; - let (radix_cks, _) = gen_keys_radix_gpu( - PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64, - num_blocks, - &streams, - ); - let (compressed_compression_key, compressed_decompression_key) = - radix_cks.new_compressed_compression_decompression_keys(&private_compression_key); - - let cuda_compression_key = compressed_compression_key.decompress_to_cuda(&streams); - - let compression_key = compressed_compression_key.decompress(); - let decompression_key = compressed_decompression_key.decompress(); - - for _ in 0..NB_TESTS { - let ct1 = radix_cks.encrypt(3_u32); - let ct2 = radix_cks.encrypt_signed(-2); - let ct3 = radix_cks.encrypt_bool(true); - - // Copy to GPU - let d_ct1 = CudaUnsignedRadixCiphertext::from_radix_ciphertext(&ct1, &streams); - let d_ct2 = CudaSignedRadixCiphertext::from_signed_radix_ciphertext(&ct2, &streams); - let d_ct3 = CudaBooleanBlock::from_boolean_block(&ct3, &streams); - - let cuda_compressed = CudaCompressedCiphertextListBuilder::new() - .push(d_ct1, &streams) - .push(d_ct2, &streams) - .push(d_ct3, &streams) - .build(&cuda_compression_key, &streams); - - let reference_compressed = CompressedCiphertextListBuilder::new() - .push(ct1) - .push(ct2) - .push(ct3) - .build(&compression_key); - - let converted_compressed = cuda_compressed.to_compressed_ciphertext_list(&streams); - - let decompressed1: RadixCiphertext = converted_compressed - .get(0, &decompression_key) - .unwrap() - .unwrap(); - let reference_decompressed1 = reference_compressed - .get(0, &decompression_key) - .unwrap() - .unwrap(); - assert_eq!(decompressed1, reference_decompressed1); - - let decompressed2: SignedRadixCiphertext = converted_compressed - .get(1, &decompression_key) - .unwrap() - .unwrap(); - let reference_decompressed2 = reference_compressed - .get(1, &decompression_key) - .unwrap() - .unwrap(); - assert_eq!(decompressed2, reference_decompressed2); - - let decompressed3: BooleanBlock = converted_compressed - .get(2, &decompression_key) - .unwrap() - .unwrap(); - let reference_decompressed3 = reference_compressed - .get(2, &decompression_key) - .unwrap() - .unwrap(); - assert_eq!(decompressed3, reference_decompressed3); - } - } - - #[test] - fn test_gpu_compressed_ciphertext_conversion_to_gpu() { - let cks = ClientKey::new(PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64); - - let private_compression_key = - cks.new_compression_private_key(COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64); - - let streams = CudaStreams::new_multi_gpu(); - - let num_blocks = 32; - let (radix_cks, _) = gen_keys_radix_gpu( - PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64, - num_blocks, - &streams, - ); - let (compressed_compression_key, compressed_decompression_key) = - radix_cks.new_compressed_compression_decompression_keys(&private_compression_key); - - let cuda_decompression_key = - compressed_decompression_key.decompress_to_cuda(radix_cks.parameters(), &streams); - - let compression_key = compressed_compression_key.decompress(); - - for _ in 0..NB_TESTS { - let ct1 = radix_cks.encrypt(3_u32); - let ct2 = radix_cks.encrypt_signed(-2); - let ct3 = radix_cks.encrypt_bool(true); - - let compressed = CompressedCiphertextListBuilder::new() - .push(ct1) - .push(ct2) - .push(ct3) - .build(&compression_key); - - let cuda_compressed = compressed.to_cuda_compressed_ciphertext_list(&streams); - - let d_decompressed1 = CudaUnsignedRadixCiphertext { - ciphertext: cuda_compressed.get(0, &cuda_decompression_key, &streams), - }; - let decompressed1 = d_decompressed1.to_radix_ciphertext(&streams); - let decrypted: u32 = radix_cks.decrypt(&decompressed1); - assert_eq!(decrypted, 3_u32); - - let d_decompressed2 = CudaSignedRadixCiphertext { - ciphertext: cuda_compressed.get(1, &cuda_decompression_key, &streams), - }; - let decompressed2 = d_decompressed2.to_signed_radix_ciphertext(&streams); - let decrypted: i32 = radix_cks.decrypt_signed(&decompressed2); - assert_eq!(decrypted, -2); - let d_decompressed3 = CudaBooleanBlock::from_cuda_radix_ciphertext( cuda_compressed.get(2, &cuda_decompression_key, &streams), ); diff --git a/tfhe/src/integer/gpu/list_compression/server_keys.rs b/tfhe/src/integer/gpu/list_compression/server_keys.rs index 1f147462a2..826096111c 100644 --- a/tfhe/src/integer/gpu/list_compression/server_keys.rs +++ b/tfhe/src/integer/gpu/list_compression/server_keys.rs @@ -12,8 +12,8 @@ use crate::integer::gpu::server_key::CudaBootstrappingKey; use crate::integer::gpu::{ compress_integer_radix_async, cuda_memcpy_async_gpu_to_gpu, decompress_integer_radix_async, }; -use crate::shortint::ciphertext::Degree; -use crate::shortint::PBSParameters; +use crate::shortint::ciphertext::{Degree, NoiseLevel}; +use crate::shortint::{CarryModulus, MessageModulus, PBSOrder, PBSParameters}; use itertools::Itertools; #[derive(Debug)] @@ -31,7 +31,8 @@ pub struct CudaDecompressionKey { pub struct CudaPackedGlweCiphertext { pub glwe_ciphertext_list: CudaGlweCiphertextList, - pub block_info: Vec, + pub message_modulus: MessageModulus, + pub carry_modulus: CarryModulus, pub bodies_count: usize, pub storage_log_modulus: CiphertextModulusLog, pub lwe_per_glwe: LweCiphertextCount, @@ -53,7 +54,7 @@ impl CudaCompressionKey { unsafe fn flatten_async( vec_ciphertexts: &[CudaRadixCiphertext], streams: &CudaStreams, - ) -> (CudaLweCiphertextList, Vec) { + ) -> CudaLweCiphertextList { let first_ct = &vec_ciphertexts.first().unwrap().d_blocks; // We assume all ciphertexts will have the same lwe dimension @@ -96,15 +97,7 @@ impl CudaCompressionKey { d_vec }; - let flattened_ciphertexts = - CudaLweCiphertextList::from_cuda_vec(d_vec, lwe_ciphertext_count, ciphertext_modulus); - - let info = vec_ciphertexts - .iter() - .flat_map(|x| x.info.blocks.clone()) - .collect_vec(); - - (flattened_ciphertexts, info) + CudaLweCiphertextList::from_cuda_vec(d_vec, lwe_ciphertext_count, ciphertext_modulus) } pub fn compress_ciphertexts_into_list( @@ -140,8 +133,8 @@ impl CudaCompressionKey { streams, ); - let info = unsafe { - let (input_lwes, info) = Self::flatten_async(ciphertexts, streams); + unsafe { + let input_lwes = Self::flatten_async(ciphertexts, streams); compress_integer_radix_async( streams, @@ -161,8 +154,6 @@ impl CudaCompressionKey { ); streams.synchronize(); - - info }; let initial_len = @@ -170,7 +161,8 @@ impl CudaCompressionKey { CudaPackedGlweCiphertext { glwe_ciphertext_list: output_glwe, - block_info: info, + message_modulus, + carry_modulus, bodies_count: num_lwes, storage_log_modulus: self.storage_log_modulus, lwe_per_glwe: LweCiphertextCount(compress_polynomial_size.0), @@ -243,27 +235,22 @@ impl CudaDecompressionKey { streams.synchronize(); - let blocks = packed_list.block_info[start_block_index..=end_block_index] - .iter() - .map(|info| { - let degree = match kind { - DataKind::Unsigned(_) | DataKind::Signed(_) => info.degree, - DataKind::Boolean => Degree::new(1), - }; - let mut cloned_info = *info; - cloned_info.degree = degree; - cloned_info - }) - .collect_vec(); - - assert_eq!( - blocks.len(), - output_lwe.lwe_ciphertext_count().0, - "Mismatch between \ - the number of output LWEs ({:?}) and number of info blocks ({:?})", - output_lwe.lwe_ciphertext_count().0, - blocks.len(), - ); + let degree = match kind { + DataKind::Unsigned(_) | DataKind::Signed(_) => { + Degree::new(message_modulus.0 * carry_modulus.0 - 1) + } + DataKind::Boolean => Degree::new(1), + }; + + let first_block_info = CudaBlockInfo { + degree, + message_modulus, + carry_modulus, + pbs_order: PBSOrder::KeyswitchBootstrap, + noise_level: NoiseLevel::NOMINAL, + }; + + let blocks = vec![first_block_info; output_lwe.0.lwe_ciphertext_count.0]; CudaRadixCiphertext { d_blocks: output_lwe,