use crate::integer::keycache::KEY_CACHE;
use crate::integer::parameters::IntegerCompactCiphertextListExpansionMode;
use crate::integer::tests::create_parameterized_test;
use crate::integer::{gen_keys, CompressedPublicKey, IntegerKeyKind, PublicKey, RadixCiphertext};
#[cfg(tarpaulin)]
use crate::shortint::parameters::coverage_parameters::*;
use crate::shortint::parameters::test_params::*;
use crate::shortint::parameters::*;
use rand::Rng;
create_parameterized_test!(big_radix_encrypt_decrypt_128_bits {
coverage => {
COVERAGE_PARAM_MESSAGE_2_CARRY_2_KS_PBS,
},
no_coverage => {
PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
}
}
);
create_parameterized_test!(
radix_encrypt_decrypt_compressed_128_bits {
coverage => {
COVERAGE_PARAM_MESSAGE_2_CARRY_2_KS_PBS,
},
no_coverage => {
PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
}
}
);
create_parameterized_test!(
big_radix_encrypt_decrypt_compact_128_bits_list {
coverage => {
COVERAGE_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS_GAUSSIAN_2M64,
},
no_coverage => {
TEST_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS_GAUSSIAN_2M128,
}
}
);
create_parameterized_test!(
small_radix_encrypt_decrypt_compact_128_bits_list {
coverage => {
COVERAGE_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_PBS_KS_GAUSSIAN_2M64,
},
no_coverage => {
TEST_PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_PBS_KS_GAUSSIAN_2M128,
}
}
);
fn big_radix_encrypt_decrypt_128_bits(param: ClassicPBSParameters) {
let (cks, _) = KEY_CACHE.get_from_params(param, IntegerKeyKind::Radix);
let public_key = PublicKey::new(&cks);
let mut rng = rand::thread_rng();
let num_block = (128f64 / (param.message_modulus.0 as f64).log(2.0)).ceil() as usize;
let clear = rng.gen::<u128>();
let ct = public_key.encrypt_radix(clear, num_block);
let dec: u128 = cks.decrypt_radix(&ct);
assert_eq!(clear, dec);
}
fn radix_encrypt_decrypt_compressed_128_bits(param: ClassicPBSParameters) {
let (cks, _) = KEY_CACHE.get_from_params(param, IntegerKeyKind::Radix);
let public_key = CompressedPublicKey::new(&cks);
let mut rng = rand::thread_rng();
let num_block = (128f64 / (param.message_modulus.0 as f64).log(2.0)).ceil() as usize;
let clear = rng.gen::<u128>();
let ct = public_key.encrypt_radix(clear, num_block);
let dec: u128 = cks.decrypt_radix(&ct);
assert_eq!(clear, dec);
}
fn big_radix_encrypt_decrypt_compact_128_bits_list(params: ClassicPBSParameters) {
radix_encrypt_decrypt_compact_128_bits_list(params);
}
fn small_radix_encrypt_decrypt_compact_128_bits_list(params: ClassicPBSParameters) {
radix_encrypt_decrypt_compact_128_bits_list(params);
}
fn radix_encrypt_decrypt_compact_128_bits_list(params: ClassicPBSParameters) {
let (cks, sks) = gen_keys(params, IntegerKeyKind::Radix);
let pk = crate::integer::public_key::CompactPublicKey::new(&cks);
let mut rng = rand::thread_rng();
let num_block = (128f64 / (params.message_modulus.0 as f64).log(2.0)).ceil() as usize;
const MAX_CT: usize = 20;
let mut clear_vec = Vec::with_capacity(MAX_CT);
for _ in 0..25 {
let num_ct_for_this_iter = rng.gen_range(1..=MAX_CT);
clear_vec.truncate(0);
for _ in 0..num_ct_for_this_iter {
let clear = rng.gen::<u128>();
clear_vec.push(clear);
}
let mut builder = crate::integer::ciphertext::CompactCiphertextList::builder(&pk);
builder.extend_with_num_blocks(clear_vec.iter().copied(), num_block);
let compact_lists = [builder.build(), builder.build_packed().unwrap()];
assert!(!compact_lists[0].is_packed());
assert!(compact_lists[1].is_packed());
for compact_encrypted_list in compact_lists {
let expander = compact_encrypted_list
.expand(
IntegerCompactCiphertextListExpansionMode::UnpackAndSanitizeIfNecessary(&sks),
)
.unwrap();
let mut ciphertext_vec = Vec::with_capacity(num_ct_for_this_iter);
for i in 0..num_ct_for_this_iter {
let radix = expander.get::<RadixCiphertext>(i).unwrap().unwrap();
assert_eq!(radix.blocks.len(), num_block);
ciphertext_vec.push(radix);
}
for (ciphertext, clear) in ciphertext_vec.iter().zip(clear_vec.iter().copied()) {
let decrypted: u128 = cks.decrypt_radix(ciphertext);
assert_eq!(decrypted, clear);
}
}
}
}