feat(integer): add CompressedSquashedNoiseCiphertextList

This commit is contained in:
tmontaigu
2025-06-17 17:31:10 +02:00
parent 0a738c368a
commit dbd158c641
8 changed files with 542 additions and 27 deletions

View File

@@ -1,3 +1,7 @@
use crate::integer::ciphertext::{
CompressedNoiseSquashingCompressionKey, CompressedSquashedNoiseCiphertextList,
NoiseSquashingCompressionKey, NoiseSquashingCompressionPrivateKey,
};
use crate::integer::compression_keys::{
CompressedCompressionKey, CompressedDecompressionKey, CompressionKey, CompressionPrivateKeys,
DecompressionKey,
@@ -42,3 +46,23 @@ pub enum CompressedDecompressionKeyVersions {
pub enum CompressionPrivateKeysVersions {
V0(CompressionPrivateKeys),
}
#[derive(VersionsDispatch)]
pub enum NoiseSquashingCompressionKeyVersions {
V0(NoiseSquashingCompressionKey),
}
#[derive(VersionsDispatch)]
pub enum NoiseSquashingCompressionPrivateKeyVersions {
V0(NoiseSquashingCompressionPrivateKey),
}
#[derive(VersionsDispatch)]
pub enum CompressedNoiseSquashingCompressionKeyVersions {
V0(CompressedNoiseSquashingCompressionKey),
}
#[derive(VersionsDispatch)]
pub enum CompressedSquashedNoiseCiphertextListVersions {
V0(CompressedSquashedNoiseCiphertextList),
}

View File

@@ -0,0 +1,409 @@
use super::{
DataKind, SquashedNoiseBooleanBlock, SquashedNoiseRadixCiphertext,
SquashedNoiseSignedRadixCiphertext,
};
use crate::core_crypto::commons::math::random::{Deserialize, Serialize};
use crate::integer::backward_compatibility::list_compression::{
CompressedNoiseSquashingCompressionKeyVersions, CompressedSquashedNoiseCiphertextListVersions,
NoiseSquashingCompressionPrivateKeyVersions,
};
use crate::integer::noise_squashing::{NoiseSquashingPrivateKey, NoiseSquashingPrivateKeyView};
use crate::named::Named;
use crate::shortint::ciphertext::{
CompressedSquashedNoiseCiphertextList as ShortintCompressedSquashedNoiseCiphertextList,
SquashedNoiseCiphertext,
};
use crate::shortint::list_compression::{
CompressedNoiseSquashingCompressionKey as ShortintCompressedNoiseSquashingCompressionKey,
NoiseSquashingCompressionKey as ShortintNoiseSquashingCompressionKey,
NoiseSquashingCompressionPrivateKey as ShortintNoiseSquashingCompressionPrivateKey,
};
use crate::shortint::parameters::NoiseSquashingCompressionParameters;
use crate::Versionize;
use crate::integer::backward_compatibility::list_compression::NoiseSquashingCompressionKeyVersions;
#[derive(Clone, Debug, Serialize, Deserialize, Versionize)]
#[versionize(NoiseSquashingCompressionPrivateKeyVersions)]
pub struct NoiseSquashingCompressionPrivateKey {
pub(crate) key: ShortintNoiseSquashingCompressionPrivateKey,
}
impl Named for NoiseSquashingCompressionPrivateKey {
const NAME: &'static str = "integer::NoiseSquashingCompressionPrivateKey";
}
impl NoiseSquashingCompressionPrivateKey {
pub fn new(params: NoiseSquashingCompressionParameters) -> Self {
let key = ShortintNoiseSquashingCompressionPrivateKey::new(params);
Self { key }
}
pub fn private_key_view(&self) -> NoiseSquashingPrivateKeyView {
NoiseSquashingPrivateKeyView {
key: (&self.key).into(),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize, Versionize)]
#[versionize(CompressedNoiseSquashingCompressionKeyVersions)]
pub struct CompressedNoiseSquashingCompressionKey {
pub(crate) key: ShortintCompressedNoiseSquashingCompressionKey,
}
impl CompressedNoiseSquashingCompressionKey {
pub fn decompress(&self) -> NoiseSquashingCompressionKey {
let key = self.key.decompress();
NoiseSquashingCompressionKey { key }
}
}
impl Named for CompressedNoiseSquashingCompressionKey {
const NAME: &'static str = "integer::CompressedNoiseSquashingCompressionKey";
}
#[derive(Clone, Debug, Serialize, Deserialize, Versionize)]
#[versionize(NoiseSquashingCompressionKeyVersions)]
pub struct NoiseSquashingCompressionKey {
pub(crate) key: ShortintNoiseSquashingCompressionKey,
}
impl Named for NoiseSquashingCompressionKey {
const NAME: &'static str = "integer::NoiseSquashingCompressionKey";
}
impl NoiseSquashingPrivateKey {
pub fn new_noise_squashing_compression_key(
&self,
private_compression_key: &NoiseSquashingCompressionPrivateKey,
) -> NoiseSquashingCompressionKey {
let key = self
.key
.new_noise_squashing_compression_key(&private_compression_key.key);
NoiseSquashingCompressionKey { key }
}
pub fn new_compressed_noise_squashing_compression_key(
&self,
private_compression_key: &NoiseSquashingCompressionPrivateKey,
) -> CompressedNoiseSquashingCompressionKey {
let key = self
.key
.new_compressed_noise_squashing_compression_key(&private_compression_key.key);
CompressedNoiseSquashingCompressionKey { key }
}
}
/// List that stores compressed noise squashed ciphertext
#[derive(Clone, Debug, Serialize, Deserialize, Versionize)]
#[versionize(CompressedSquashedNoiseCiphertextListVersions)]
pub struct CompressedSquashedNoiseCiphertextList {
list: ShortintCompressedSquashedNoiseCiphertextList,
info: Vec<DataKind>,
}
impl Named for CompressedSquashedNoiseCiphertextList {
const NAME: &'static str = "integer::CompressedSquashedNoiseCiphertextList";
}
impl CompressedSquashedNoiseCiphertextList {
/// Returns a builder to create a list
pub fn builder() -> CompressedSquashedNoiseCiphertextListBuilder {
CompressedSquashedNoiseCiphertextListBuilder::new()
}
/// Returns the number of squashed noise ciphertext that are stored
pub fn len(&self) -> usize {
self.info.len()
}
// Returns whether the list is empty
pub fn is_empty(&self) -> bool {
self.len() == 0
}
fn blocks_of(&self, index: usize) -> Option<(Vec<SquashedNoiseCiphertext>, DataKind)> {
let preceding_infos = self.info.get(..index)?;
let current_info = self.info.get(index).copied()?;
let message_modulus = self.list.message_modulus().unwrap();
let start_block_index: usize = preceding_infos
.iter()
.copied()
.map(|kind| kind.num_blocks(message_modulus).div_ceil(2))
.sum();
let end_block_index =
start_block_index + current_info.num_blocks(message_modulus).div_ceil(2);
Some((
(start_block_index..end_block_index)
.map(|i| self.list.unpack(i).unwrap())
.collect(),
current_info,
))
}
pub fn get_kind_of(&self, index: usize) -> Option<DataKind> {
self.info.get(index).copied()
}
/// Decompress the squashed noise ciphertext at the given index slot
///
/// # Note
///
/// After decompression, the resulting ciphertext is under the parameters
/// of the [NoiseSquashingCompressionKey].
pub fn get<T>(&self, index: usize) -> crate::Result<Option<T>>
where
T: SquashedNoiseExpandable,
{
self.blocks_of(index)
.map(|(ns_blocks, data_kind)| T::from_expanded_blocks(ns_blocks, data_kind))
.transpose()
}
}
mod sealed {
use super::*;
pub trait Sealed {}
impl Sealed for SquashedNoiseRadixCiphertext {}
impl Sealed for SquashedNoiseSignedRadixCiphertext {}
impl Sealed for SquashedNoiseBooleanBlock {}
}
pub trait SquashedNoiseCompressible: sealed::Sealed {
fn compress_into(self, messages: &mut Vec<SquashedNoiseCiphertext>) -> DataKind;
}
impl SquashedNoiseCompressible for SquashedNoiseRadixCiphertext {
fn compress_into(mut self, messages: &mut Vec<SquashedNoiseCiphertext>) -> DataKind {
messages.append(&mut self.packed_blocks);
DataKind::Unsigned(self.original_block_count)
}
}
impl SquashedNoiseCompressible for SquashedNoiseSignedRadixCiphertext {
fn compress_into(mut self, messages: &mut Vec<SquashedNoiseCiphertext>) -> DataKind {
messages.append(&mut self.packed_blocks);
DataKind::Signed(self.original_block_count)
}
}
impl SquashedNoiseCompressible for SquashedNoiseBooleanBlock {
fn compress_into(self, messages: &mut Vec<SquashedNoiseCiphertext>) -> DataKind {
messages.push(self.ciphertext);
DataKind::Boolean
}
}
pub trait SquashedNoiseExpandable: Sized + sealed::Sealed {
fn from_expanded_blocks(
blocks: Vec<SquashedNoiseCiphertext>,
kind: DataKind,
) -> crate::Result<Self>;
}
fn create_error_message(tried: DataKind, actual: DataKind) -> crate::Error {
fn name(kind: DataKind) -> &'static str {
match kind {
DataKind::Unsigned(_) => "SquashedNoiseRadixCiphertext",
DataKind::Signed(_) => "SquashedNoiseSignedRadixCiphertext",
DataKind::Boolean => "SquashedNoiseBooleanBlock",
DataKind::String { .. } => "SquashedNoiseFheString",
}
}
crate::error!(
"Tried to expand a {}, but a {} is stored in this slot",
name(tried),
name(actual)
)
}
impl SquashedNoiseExpandable for SquashedNoiseRadixCiphertext {
fn from_expanded_blocks(
blocks: Vec<SquashedNoiseCiphertext>,
kind: DataKind,
) -> crate::Result<Self> {
if let DataKind::Unsigned(block_count) = kind {
Ok(Self {
packed_blocks: blocks,
original_block_count: block_count,
})
} else {
Err(create_error_message(DataKind::Unsigned(0), kind))
}
}
}
impl SquashedNoiseExpandable for SquashedNoiseSignedRadixCiphertext {
fn from_expanded_blocks(
blocks: Vec<SquashedNoiseCiphertext>,
kind: DataKind,
) -> crate::Result<Self> {
if let DataKind::Signed(block_count) = kind {
Ok(Self {
packed_blocks: blocks,
original_block_count: block_count,
})
} else {
Err(create_error_message(DataKind::Signed(0), kind))
}
}
}
impl SquashedNoiseExpandable for SquashedNoiseBooleanBlock {
fn from_expanded_blocks(
mut blocks: Vec<SquashedNoiseCiphertext>,
kind: DataKind,
) -> crate::Result<Self> {
if DataKind::Boolean == kind {
assert_eq!(blocks.len(), 1);
Ok(Self {
ciphertext: blocks.pop().unwrap(),
})
} else {
Err(create_error_message(DataKind::Boolean, kind))
}
}
}
pub struct CompressedSquashedNoiseCiphertextListBuilder {
list: Vec<SquashedNoiseCiphertext>,
info: Vec<DataKind>,
}
impl Default for CompressedSquashedNoiseCiphertextListBuilder {
fn default() -> Self {
Self::new()
}
}
impl CompressedSquashedNoiseCiphertextListBuilder {
pub fn new() -> Self {
Self {
list: vec![],
info: vec![],
}
}
pub fn push(&mut self, value: impl SquashedNoiseCompressible) -> &mut Self {
let n = self.list.len();
let kind = value.compress_into(&mut self.list);
// Check that the number of blocks that were added matches the
// number of blocks advertised by the DataKind
let num_blocks = self
.list
.last()
.map_or(0, |ct| kind.num_blocks(ct.message_modulus()))
.div_ceil(2); // Because blocks are packed when noise squashed
assert_eq!(n + num_blocks, self.list.len());
self.info.push(kind);
self
}
pub fn build(
&self,
comp_key: &NoiseSquashingCompressionKey,
) -> CompressedSquashedNoiseCiphertextList {
let list = comp_key
.key
.compress_noise_squashed_ciphertexts_into_list(&self.list);
CompressedSquashedNoiseCiphertextList {
list,
info: self.info.clone(),
}
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::integer::noise_squashing::NoiseSquashingKey;
use crate::shortint::parameters::test_params::{
TEST_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_PARAM_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_PARAM_NOISE_SQUASHING_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
};
use rand::Rng;
#[test]
fn test_compressed_noise_squashed_ciphertext_list() {
let param = TEST_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
let noise_squashing_parameters =
TEST_PARAM_NOISE_SQUASHING_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
// The goal is to test that encrypting a value stored in a type
// for which the bit count does not match the target block count of the encrypted
// radix properly applies upcasting/downcasting
let (cks, sks) = crate::integer::keycache::KEY_CACHE
.get_from_params(param, crate::integer::IntegerKeyKind::Radix);
let noise_squashing_private_key = NoiseSquashingPrivateKey::new(noise_squashing_parameters);
let noise_squashing_key = NoiseSquashingKey::new(&cks, &noise_squashing_private_key);
let noise_squashing_compression_private_key = NoiseSquashingCompressionPrivateKey::new(
TEST_PARAM_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
);
let compression_key = noise_squashing_private_key
.new_noise_squashing_compression_key(&noise_squashing_compression_private_key);
let mut rng = rand::thread_rng();
const NUM_BLOCKS: usize = 16;
let clear_a = rng.gen_range(0..=i32::MAX);
let clear_b = rng.gen_range(i32::MIN..=-1);
let clear_c = rng.gen::<u32>();
let clear_d = rng.gen::<bool>();
let ct_a = cks.encrypt_signed_radix(clear_a, NUM_BLOCKS);
let ct_b = cks.encrypt_signed_radix(clear_b, NUM_BLOCKS);
let ct_c = cks.encrypt_radix(clear_c, NUM_BLOCKS);
let ct_d = cks.encrypt_bool(clear_d);
let ns_ct_a = noise_squashing_key
.squash_signed_radix_ciphertext_noise(&sks, &ct_a)
.unwrap();
let ns_ct_b = noise_squashing_key
.squash_signed_radix_ciphertext_noise(&sks, &ct_b)
.unwrap();
let ns_ct_c = noise_squashing_key
.squash_radix_ciphertext_noise(&sks, &ct_c)
.unwrap();
let ns_ct_d = noise_squashing_key
.squash_boolean_block_noise(&sks, &ct_d)
.unwrap();
let list = CompressedSquashedNoiseCiphertextList::builder()
.push(ns_ct_a)
.push(ns_ct_b)
.push(ns_ct_c)
.push(ns_ct_d)
.build(&compression_key);
let ns_ct_a: SquashedNoiseSignedRadixCiphertext = list.get(0).unwrap().unwrap();
let ns_ct_b: SquashedNoiseSignedRadixCiphertext = list.get(1).unwrap().unwrap();
let ns_ct_c: SquashedNoiseRadixCiphertext = list.get(2).unwrap().unwrap();
let ns_ct_d: SquashedNoiseBooleanBlock = list.get(3).unwrap().unwrap();
let decryption_key = noise_squashing_compression_private_key.private_key_view();
let d_clear_a: i32 = decryption_key.decrypt_signed_radix(&ns_ct_a).unwrap();
let d_clear_b: i32 = decryption_key.decrypt_signed_radix(&ns_ct_b).unwrap();
let d_clear_c: u32 = decryption_key.decrypt_radix(&ns_ct_c).unwrap();
let d_clear_d = decryption_key.decrypt_bool(&ns_ct_d).unwrap();
assert_eq!(clear_a, d_clear_a);
assert_eq!(clear_b, d_clear_b);
assert_eq!(clear_c, d_clear_c);
assert_eq!(clear_d, d_clear_d);
}
}

View File

@@ -4,6 +4,7 @@ mod compact_list;
mod compressed;
mod compressed_ciphertext_list;
mod compressed_modulus_switched_ciphertext;
mod compressed_noise_squashed_ciphertext_list;
mod integer_ciphertext;
mod squashed_noise;
mod utils;
@@ -14,6 +15,7 @@ pub use compact_list::*;
pub use compressed::*;
pub use compressed_ciphertext_list::*;
pub use compressed_modulus_switched_ciphertext::*;
pub use compressed_noise_squashed_ciphertext_list::*;
pub use integer_ciphertext::*;
pub use squashed_noise::*;
pub use utils::*;

View File

@@ -21,6 +21,10 @@ pub struct NoiseSquashingPrivateKey {
pub(crate) key: crate::shortint::noise_squashing::NoiseSquashingPrivateKey,
}
pub struct NoiseSquashingPrivateKeyView<'a> {
pub(crate) key: crate::shortint::noise_squashing::NoiseSquashingPrivateKeyView<'a>,
}
#[derive(Clone, Debug, Serialize, Deserialize, Versionize)]
#[versionize(NoiseSquashingKeyVersions)]
pub struct NoiseSquashingKey {
@@ -33,10 +37,6 @@ pub struct CompressedNoiseSquashingKey {
pub(crate) key: crate::shortint::noise_squashing::CompressedNoiseSquashingKey,
}
impl Named for NoiseSquashingPrivateKey {
const NAME: &'static str = "integer::NoiseSquashingPrivateKey";
}
impl Named for NoiseSquashingKey {
const NAME: &'static str = "integer::NoiseSquashingKey";
}
@@ -45,6 +45,10 @@ impl Named for CompressedNoiseSquashingKey {
const NAME: &'static str = "integer::CompressedNoiseSquashingKey";
}
impl Named for NoiseSquashingPrivateKey {
const NAME: &'static str = "integer::NoiseSquashingPrivateKey";
}
impl CompressedNoiseSquashingKey {
pub fn decompress(&self) -> NoiseSquashingKey {
NoiseSquashingKey {
@@ -64,28 +68,7 @@ impl CompressedNoiseSquashingKey {
}
}
impl NoiseSquashingPrivateKey {
pub fn new_compressed_noise_squashing_key(
&self,
client_key: &ClientKey,
) -> CompressedNoiseSquashingKey {
client_key.new_compressed_noise_squashing_key(self)
}
pub fn new(params: NoiseSquashingParameters) -> Self {
assert!(
params.carry_modulus.0 >= params.message_modulus.0,
"NoiseSquashingPrivateKey requires its CarryModulus {:?} to be greater \
or equal to its MessageModulus {:?}",
params.carry_modulus.0,
params.message_modulus.0,
);
Self {
key: crate::shortint::noise_squashing::NoiseSquashingPrivateKey::new(params),
}
}
impl NoiseSquashingPrivateKeyView<'_> {
pub fn decrypt_radix<T>(&self, ct: &SquashedNoiseRadixCiphertext) -> crate::Result<T>
where
T: RecomposableFrom<u128> + UnsignedNumeric,
@@ -241,6 +224,56 @@ impl NoiseSquashingPrivateKey {
Ok(decrypted != 0)
}
}
impl NoiseSquashingPrivateKey {
pub fn new_compressed_noise_squashing_key(
&self,
client_key: &ClientKey,
) -> CompressedNoiseSquashingKey {
client_key.new_compressed_noise_squashing_key(self)
}
pub fn new(params: NoiseSquashingParameters) -> Self {
assert!(
params.carry_modulus.0 >= params.message_modulus.0,
"NoiseSquashingPrivateKey requires its CarryModulus {:?} to be greater \
or equal to its MessageModulus {:?}",
params.carry_modulus.0,
params.message_modulus.0,
);
Self {
key: crate::shortint::noise_squashing::NoiseSquashingPrivateKey::new(params),
}
}
pub(crate) fn as_view(&self) -> NoiseSquashingPrivateKeyView {
NoiseSquashingPrivateKeyView {
key: self.key.as_view(),
}
}
pub fn decrypt_radix<T>(&self, ct: &SquashedNoiseRadixCiphertext) -> crate::Result<T>
where
T: RecomposableFrom<u128> + UnsignedNumeric,
{
self.as_view().decrypt_radix(ct)
}
pub fn decrypt_signed_radix<T>(
&self,
ct: &SquashedNoiseSignedRadixCiphertext,
) -> crate::Result<T>
where
T: RecomposableFrom<u128> + SignExtendable,
{
self.as_view().decrypt_signed_radix(ct)
}
pub fn decrypt_bool(&self, ct: &SquashedNoiseBooleanBlock) -> crate::Result<bool> {
self.as_view().decrypt_bool(ct)
}
pub fn into_raw_parts(self) -> crate::shortint::noise_squashing::NoiseSquashingPrivateKey {
let Self { key } = self;

View File

@@ -232,4 +232,8 @@ impl CompressedSquashedNoiseCiphertextList {
Ok(extracted_lwe)
}
pub fn message_modulus(&self) -> Option<MessageModulus> {
self.meta.as_ref().map(|meta| meta.message_modulus)
}
}

View File

@@ -9,6 +9,7 @@ use crate::shortint::backward_compatibility::list_compression::{
use crate::shortint::client_key::atomic_pattern::AtomicPatternClientKey;
use crate::shortint::client_key::ClientKey;
use crate::shortint::engine::ShortintEngine;
use crate::shortint::list_compression::CompressedNoiseSquashingCompressionKey;
use crate::shortint::noise_squashing::NoiseSquashingPrivateKey;
use crate::shortint::parameters::{
CompressionParameters, ModulusSwitchType, NoiseSquashingCompressionParameters,
@@ -269,6 +270,31 @@ impl NoiseSquashingPrivateKey {
lwe_per_glwe: params.lwe_per_glwe,
}
}
pub fn new_compressed_noise_squashing_compression_key(
&self,
private_compression_key: &NoiseSquashingCompressionPrivateKey,
) -> CompressedNoiseSquashingCompressionKey {
let params = &private_compression_key.params;
let packing_key_switching_key =
crate::shortint::engine::ShortintEngine::with_thread_local_mut(|engine| {
allocate_and_generate_new_seeded_lwe_packing_keyswitch_key(
&self.post_noise_squashing_secret_key().as_lwe_secret_key(),
&private_compression_key.post_packing_ks_key,
params.packing_ks_base_log,
params.packing_ks_level,
params.packing_ks_key_noise_distribution,
params.ciphertext_modulus,
&mut engine.seeder,
)
});
CompressedNoiseSquashingCompressionKey {
packing_key_switching_key,
lwe_per_glwe: params.lwe_per_glwe,
}
}
}
pub struct NoiseSquashingCompressionKeyConformanceParams {

View File

@@ -78,6 +78,13 @@ pub(crate) struct NoiseSquashingPrivateKeyView<'a> {
params: NoiseSquashingParameters,
}
impl NoiseSquashingPrivateKeyView<'_> {
#[allow(unused, reason = "It's only used in integer module")]
pub fn noise_squashing_parameters(&self) -> NoiseSquashingParameters {
self.params
}
}
impl<'a> From<&'a NoiseSquashingPrivateKey> for NoiseSquashingPrivateKeyView<'a> {
fn from(value: &'a NoiseSquashingPrivateKey) -> Self {
Self {

View File

@@ -1,5 +1,8 @@
use super::current_params::*;
use super::{AtomicPatternParameters, KeySwitch32PBSParameters};
use super::{
AtomicPatternParameters, KeySwitch32PBSParameters, NoiseSquashingCompressionParameters,
NoiseSquashingParameters,
};
use super::{
ClassicPBSParameters, CompactPublicKeyEncryptionParameters, CompressionParameters,
@@ -221,3 +224,10 @@ pub const TEST_COMP_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFOR
// KS32 PBS AP
pub const TEST_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128: KeySwitch32PBSParameters =
V1_3_PARAM_MESSAGE_2_CARRY_2_KS32_PBS_TUNIFORM_2M128;
pub const TEST_PARAM_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
NoiseSquashingCompressionParameters =
V1_3_NOISE_SQUASHING_COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;
pub const TEST_PARAM_NOISE_SQUASHING_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128:
NoiseSquashingParameters = V1_3_NOISE_SQUASHING_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128;