mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-09 14:47:56 -05:00
chore(ci): add core_crypto layer to code coverage
This commit is contained in:
9
.github/workflows/code_coverage.yml
vendored
9
.github/workflows/code_coverage.yml
vendored
@@ -38,6 +38,7 @@ jobs:
|
||||
group: ${{ github.workflow }}_${{ github.ref }}_${{ inputs.instance_image_id }}_${{ inputs.instance_type }}
|
||||
cancel-in-progress: true
|
||||
runs-on: ${{ inputs.runner_name }}
|
||||
timeout-minutes: 1080
|
||||
steps:
|
||||
# Step used for log purpose.
|
||||
- name: Instance configuration used
|
||||
@@ -79,6 +80,12 @@ jobs:
|
||||
if: steps.changed-files.outputs.tfhe_any_changed == 'true'
|
||||
run: |
|
||||
make GEN_KEY_CACHE_COVERAGE_ONLY=TRUE gen_key_cache
|
||||
make gen_key_cache_core_crypto
|
||||
|
||||
- name: Run coverage for core_crypto
|
||||
if: steps.changed-files.outputs.tfhe_any_changed == 'true'
|
||||
run: |
|
||||
make test_core_crypto_cov AVX512_SUPPORT=ON
|
||||
|
||||
- name: Run coverage for boolean
|
||||
if: steps.changed-files.outputs.tfhe_any_changed == 'true'
|
||||
@@ -97,7 +104,7 @@ jobs:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
directory: ./coverage/
|
||||
fail_ci_if_error: true
|
||||
files: shortint/cobertura.xml,boolean/cobertura.xml
|
||||
files: shortint/cobertura.xml,boolean/cobertura.xml,core_crypto/cobertura.xml,core_crypto_avx512/cobertura.xml
|
||||
|
||||
- name: Slack Notification
|
||||
if: ${{ failure() }}
|
||||
|
||||
34
Makefile
34
Makefile
@@ -225,13 +225,6 @@ clippy_js_wasm_api clippy_tasks clippy_core clippy_concrete_csprng clippy_triviu
|
||||
clippy_fast: clippy clippy_all_targets clippy_c_api clippy_js_wasm_api clippy_tasks clippy_core \
|
||||
clippy_concrete_csprng
|
||||
|
||||
.PHONY: gen_key_cache # Run the script to generate keys and cache them for shortint tests
|
||||
gen_key_cache: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) run --profile $(CARGO_PROFILE) \
|
||||
--example generates_test_keys \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,internal-keycache -- \
|
||||
$(MULTI_BIT_ONLY) $(COVERAGE_ONLY)
|
||||
|
||||
.PHONY: build_core # Build core_crypto without experimental features
|
||||
build_core: install_rs_build_toolchain install_rs_check_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
|
||||
@@ -319,6 +312,21 @@ test_core_crypto: install_rs_build_toolchain install_rs_check_toolchain
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental,$(AVX512_FEATURE) -p $(TFHE_SPEC) -- core_crypto::; \
|
||||
fi
|
||||
|
||||
.PHONY: test_core_crypto_cov # Run the tests of the core_crypto module with code coverage
|
||||
test_core_crypto_cov: install_rs_build_toolchain install_rs_check_toolchain install_tarpaulin
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) tarpaulin --profile $(CARGO_PROFILE) \
|
||||
--out xml --output-dir coverage/core_crypto --line --engine llvm --timeout 500 \
|
||||
--implicit-test-threads $(COVERAGE_EXCLUDED_FILES) \
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental,internal-keycache,__coverage \
|
||||
-p tfhe -- core_crypto::
|
||||
@if [[ "$(AVX512_SUPPORT)" == "ON" ]]; then \
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) tarpaulin --profile $(CARGO_PROFILE) \
|
||||
--out xml --output-dir coverage/core_crypto_avx512 --line --engine llvm --timeout 500 \
|
||||
--implicit-test-threads $(COVERAGE_EXCLUDED_FILES) \
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental,internal-keycache,__coverage,$(AVX512_FEATURE) \
|
||||
-p tfhe -- core_crypto::; \
|
||||
fi
|
||||
|
||||
.PHONY: test_boolean # Run the tests of the boolean module
|
||||
test_boolean: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
|
||||
@@ -627,6 +635,18 @@ ci_bench_web_js_api_parallel: build_web_js_api_parallel
|
||||
#
|
||||
# Utility tools
|
||||
#
|
||||
.PHONY: gen_key_cache # Run the script to generate keys and cache them for shortint tests
|
||||
gen_key_cache: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) run --profile $(CARGO_PROFILE) \
|
||||
--example generates_test_keys \
|
||||
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,internal-keycache -- \
|
||||
$(MULTI_BIT_ONLY) $(COVERAGE_ONLY)
|
||||
|
||||
.PHONY: gen_key_cache_core_crypto # Run function to generate keys and cache them for core_crypto tests
|
||||
gen_key_cache_core_crypto: install_rs_build_toolchain
|
||||
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --tests --profile $(CARGO_PROFILE) \
|
||||
--features=$(TARGET_ARCH_FEATURE),experimental,internal-keycache -p tfhe -- --nocapture \
|
||||
core_crypto::keycache::generate_keys
|
||||
|
||||
.PHONY: measure_hlapi_compact_pk_ct_sizes # Measure sizes of public keys and ciphertext for high-level API
|
||||
measure_hlapi_compact_pk_ct_sizes: install_rs_check_toolchain
|
||||
|
||||
@@ -44,7 +44,7 @@ pub mod seeded_lwe_public_key_decompression;
|
||||
pub mod slice_algorithms;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
pub(crate) mod test;
|
||||
|
||||
// No pub use for slice and polynomial algorithms which would not interest higher level users
|
||||
// They can still be used via `use crate::core_crypto::algorithms::slice_algorithms::*;`
|
||||
|
||||
@@ -6,6 +6,11 @@ use crate::core_crypto::commons::generators::{
|
||||
use crate::core_crypto::commons::math::random::{ActivatedRandomGenerator, CompressionSeed};
|
||||
use crate::core_crypto::commons::test_tools;
|
||||
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn test_parallel_and_seeded_ggsw_encryption_equivalence<Scalar>(
|
||||
ciphertext_modulus: CiphertextModulus<Scalar>,
|
||||
) where
|
||||
@@ -27,8 +32,6 @@ fn test_parallel_and_seeded_ggsw_encryption_equivalence<Scalar>(
|
||||
let mut secret_generator =
|
||||
SecretRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed());
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
|
||||
for _ in 0..NB_TESTS {
|
||||
// Create the GlweSecretKey
|
||||
let glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
@@ -174,7 +177,7 @@ fn test_parallel_and_seeded_ggsw_encryption_equivalence_u64_custom_mod() {
|
||||
);
|
||||
}
|
||||
|
||||
fn ggsw_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn ggsw_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: ClassicTestParams<Scalar>) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -184,8 +187,6 @@ fn ggsw_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Sca
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
|
||||
let mut msg = Scalar::ONE << decomposition_base_log.0;
|
||||
|
||||
while msg != Scalar::ZERO {
|
||||
@@ -232,13 +233,18 @@ fn ggsw_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Sca
|
||||
|
||||
assert!(decoded.0 == msg);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(ggsw_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn ggsw_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Send + Sync>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
@@ -249,8 +255,6 @@ fn ggsw_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Send + Sync>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
|
||||
let mut msg = Scalar::ONE << decomposition_base_log.0;
|
||||
|
||||
while msg != Scalar::ZERO {
|
||||
@@ -297,12 +301,19 @@ fn ggsw_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Send + Sync>(
|
||||
|
||||
assert!(decoded.0 == msg);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(ggsw_par_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn ggsw_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn ggsw_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -312,8 +323,6 @@ fn ggsw_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPar
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
|
||||
let mut msg = Scalar::ONE << decomposition_base_log.0;
|
||||
|
||||
while msg != Scalar::ZERO {
|
||||
@@ -363,13 +372,18 @@ fn ggsw_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPar
|
||||
|
||||
assert!(decoded.0 == msg);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(ggsw_seeded_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn ggsw_seeded_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Sync + Send>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
@@ -380,8 +394,6 @@ fn ggsw_seeded_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Sync + Sen
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
|
||||
let mut msg = Scalar::ONE << decomposition_base_log.0;
|
||||
|
||||
while msg != Scalar::ZERO {
|
||||
@@ -431,6 +443,11 @@ fn ggsw_seeded_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Sync + Sen
|
||||
|
||||
assert!(decoded.0 == msg);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
use super::*;
|
||||
|
||||
fn glwe_encrypt_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn glwe_encrypt_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -10,7 +17,6 @@ fn glwe_encrypt_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPar
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -57,12 +63,17 @@ fn glwe_encrypt_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPar
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_encrypt_assign_decrypt_custom_mod);
|
||||
|
||||
fn glwe_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn glwe_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: ClassicTestParams<Scalar>) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -72,7 +83,6 @@ fn glwe_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Sca
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -123,12 +133,17 @@ fn glwe_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Sca
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn glwe_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn glwe_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: ClassicTestParams<Scalar>) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -139,7 +154,6 @@ fn glwe_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParam
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -195,12 +209,19 @@ fn glwe_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParam
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_list_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn glwe_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn glwe_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -209,7 +230,6 @@ fn glwe_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPa
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -254,13 +274,18 @@ fn glwe_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPa
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_trivial_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn glwe_allocate_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
@@ -270,7 +295,6 @@ fn glwe_allocate_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -308,12 +332,19 @@ fn glwe_allocate_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
assert!(output_plaintext_list.iter().all(|x| *x.0 == msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_allocate_trivial_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn glwe_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn glwe_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -323,7 +354,6 @@ fn glwe_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPar
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -384,12 +414,19 @@ fn glwe_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPar
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_seeded_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn glwe_seeded_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn glwe_seeded_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -400,7 +437,6 @@ fn glwe_seeded_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Te
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -459,6 +495,11 @@ fn glwe_seeded_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Te
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
use super::*;
|
||||
|
||||
fn glwe_encrypt_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn glwe_encrypt_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -10,7 +17,6 @@ fn glwe_encrypt_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Tes
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -70,12 +76,17 @@ fn glwe_encrypt_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Tes
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == (msg + msg) % msg_modulus));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_encrypt_add_assign_decrypt_custom_mod);
|
||||
|
||||
fn glwe_encrypt_add_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn glwe_encrypt_add_decrypt_custom_mod<Scalar: UnsignedTorus>(params: ClassicTestParams<Scalar>) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -85,7 +96,6 @@ fn glwe_encrypt_add_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -147,13 +157,18 @@ fn glwe_encrypt_add_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == (msg + msg) % msg_modulus));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_encrypt_add_decrypt_custom_mod);
|
||||
|
||||
fn glwe_encrypt_plaintext_list_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
@@ -164,7 +179,6 @@ fn glwe_encrypt_plaintext_list_add_assign_decrypt_custom_mod<Scalar: UnsignedTor
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -222,13 +236,18 @@ fn glwe_encrypt_plaintext_list_add_assign_decrypt_custom_mod<Scalar: UnsignedTor
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == (msg + msg) % msg_modulus));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_encrypt_plaintext_list_add_assign_decrypt_custom_mod);
|
||||
|
||||
fn glwe_encrypt_plaintext_list_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
@@ -239,7 +258,6 @@ fn glwe_encrypt_plaintext_list_sub_assign_decrypt_custom_mod<Scalar: UnsignedTor
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -297,13 +315,18 @@ fn glwe_encrypt_plaintext_list_sub_assign_decrypt_custom_mod<Scalar: UnsignedTor
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == Scalar::ZERO));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_encrypt_plaintext_list_sub_assign_decrypt_custom_mod);
|
||||
|
||||
fn glwe_encrypt_plaintext_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
@@ -314,7 +337,6 @@ fn glwe_encrypt_plaintext_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -373,13 +395,18 @@ fn glwe_encrypt_plaintext_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == (msg + msg) % msg_modulus));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_encrypt_plaintext_add_assign_decrypt_custom_mod);
|
||||
|
||||
fn glwe_encrypt_plaintext_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
@@ -390,7 +417,6 @@ fn glwe_encrypt_plaintext_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -449,13 +475,18 @@ fn glwe_encrypt_plaintext_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == Scalar::ZERO));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_encrypt_plaintext_sub_assign_decrypt_custom_mod);
|
||||
|
||||
fn glwe_encrypt_opposite_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
@@ -466,7 +497,6 @@ fn glwe_encrypt_opposite_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -526,13 +556,18 @@ fn glwe_encrypt_opposite_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
.iter()
|
||||
.all(|&x| x == msg.wrapping_neg() % msg_modulus));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_encrypt_opposite_assign_decrypt_custom_mod);
|
||||
|
||||
fn glwe_encrypt_cleartext_mul_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
@@ -543,7 +578,6 @@ fn glwe_encrypt_cleartext_mul_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -604,13 +638,18 @@ fn glwe_encrypt_cleartext_mul_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
.iter()
|
||||
.all(|&x| x == (msg * cleartext.0) % msg_modulus));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_encrypt_cleartext_mul_assign_decrypt_custom_mod);
|
||||
|
||||
fn glwe_encrypt_cleartext_mul_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
@@ -621,7 +660,6 @@ fn glwe_encrypt_cleartext_mul_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -684,12 +722,19 @@ fn glwe_encrypt_cleartext_mul_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
.iter()
|
||||
.all(|&x| x == (msg * cleartext.0) % msg_modulus));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_encrypt_cleartext_mul_decrypt_custom_mod);
|
||||
|
||||
fn glwe_encrypt_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn glwe_encrypt_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -699,7 +744,6 @@ fn glwe_encrypt_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Tes
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -759,12 +803,17 @@ fn glwe_encrypt_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Tes
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == Scalar::ZERO));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(glwe_encrypt_sub_assign_decrypt_custom_mod);
|
||||
|
||||
fn glwe_encrypt_sub_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn glwe_encrypt_sub_decrypt_custom_mod<Scalar: UnsignedTorus>(params: ClassicTestParams<Scalar>) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -774,7 +823,6 @@ fn glwe_encrypt_sub_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -836,6 +884,11 @@ fn glwe_encrypt_sub_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == Scalar::ZERO));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
use super::*;
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn glwe_encrypt_sample_extract_decrypt_custom_mod<Scalar: UnsignedTorus + Send + Sync>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
@@ -12,7 +16,6 @@ fn glwe_encrypt_sample_extract_decrypt_custom_mod<Scalar: UnsignedTorus + Send +
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -107,6 +110,11 @@ fn glwe_encrypt_sample_extract_decrypt_custom_mod<Scalar: UnsignedTorus + Send +
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,15 @@ use crate::core_crypto::commons::parameters::{
|
||||
use crate::core_crypto::commons::test_tools::new_secret_random_generator;
|
||||
use crate::core_crypto::entities::*;
|
||||
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn test_parallel_and_seeded_bsk_gen_equivalence<T: UnsignedTorus + Sync + Send>(
|
||||
ciphertext_modulus: CiphertextModulus<T>,
|
||||
) {
|
||||
for _ in 0..10 {
|
||||
for _ in 0..NB_TESTS {
|
||||
let lwe_dim =
|
||||
LweDimension(crate::core_crypto::commons::test_tools::random_usize_between(5..10));
|
||||
let glwe_dim =
|
||||
|
||||
@@ -5,6 +5,11 @@ use crate::core_crypto::commons::generators::{
|
||||
};
|
||||
use crate::core_crypto::commons::math::random::ActivatedRandomGenerator;
|
||||
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn test_seeded_lwe_cpk_gen_equivalence<Scalar: UnsignedTorus>(
|
||||
ciphertext_modulus: CiphertextModulus<Scalar>,
|
||||
) {
|
||||
@@ -22,9 +27,7 @@ fn test_seeded_lwe_cpk_gen_equivalence<Scalar: UnsignedTorus>(
|
||||
let mut secret_generator =
|
||||
SecretRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed());
|
||||
|
||||
const NB_TEST: usize = 10;
|
||||
|
||||
for _ in 0..NB_TEST {
|
||||
for _ in 0..NB_TESTS {
|
||||
// Create the LweSecretKey
|
||||
let input_lwe_secret_key =
|
||||
allocate_and_generate_new_binary_lwe_secret_key(lwe_dimension, &mut secret_generator);
|
||||
|
||||
@@ -2,8 +2,13 @@ use super::*;
|
||||
use crate::core_crypto::commons::generators::DeterministicSeeder;
|
||||
use crate::core_crypto::commons::test_tools;
|
||||
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn test_parallel_and_seeded_lwe_list_encryption_equivalence<Scalar: UnsignedTorus + Sync + Send>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
// DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct
|
||||
// computations
|
||||
@@ -21,8 +26,6 @@ fn test_parallel_and_seeded_lwe_list_encryption_equivalence<Scalar: UnsignedToru
|
||||
let mut secret_generator =
|
||||
SecretRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed());
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
|
||||
for _ in 0..NB_TESTS {
|
||||
// Create the LweSecretKey
|
||||
let lwe_secret_key =
|
||||
@@ -148,7 +151,7 @@ fn test_parallel_and_seeded_lwe_list_encryption_equivalence_non_native_power_of_
|
||||
test_parallel_and_seeded_lwe_list_encryption_equivalence(DUMMY_31_U32);
|
||||
}
|
||||
|
||||
fn lwe_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn lwe_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: ClassicTestParams<Scalar>) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -157,7 +160,6 @@ fn lwe_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scal
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -197,12 +199,19 @@ fn lwe_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scal
|
||||
|
||||
assert_eq!(msg, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn lwe_allocate_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn lwe_allocate_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -211,7 +220,6 @@ fn lwe_allocate_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPa
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -245,12 +253,19 @@ fn lwe_allocate_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPa
|
||||
|
||||
assert_eq!(msg, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_allocate_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn lwe_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn lwe_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
let message_modulus_log = params.message_modulus_log;
|
||||
@@ -258,7 +273,6 @@ fn lwe_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPar
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -292,12 +306,17 @@ fn lwe_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPar
|
||||
|
||||
assert_eq!(msg, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
create_parametrized_test!(lwe_trivial_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn lwe_allocate_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -306,7 +325,6 @@ fn lwe_allocate_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -338,12 +356,17 @@ fn lwe_allocate_trivial_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
assert_eq!(msg, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_allocate_trivial_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn lwe_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn lwe_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: ClassicTestParams<Scalar>) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -353,7 +376,6 @@ fn lwe_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -403,13 +425,18 @@ fn lwe_list_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_list_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn lwe_list_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Sync + Send>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
@@ -420,7 +447,6 @@ fn lwe_list_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Sync + Send>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -470,12 +496,17 @@ fn lwe_list_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Sync + Send>(
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_list_par_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn lwe_public_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn lwe_public_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: ClassicTestParams<Scalar>) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -485,7 +516,6 @@ fn lwe_public_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPara
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -532,12 +562,19 @@ fn lwe_public_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPara
|
||||
|
||||
assert_eq!(msg, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_public_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn lwe_seeded_public_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn lwe_seeded_public_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -547,7 +584,6 @@ fn lwe_seeded_public_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: T
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -601,13 +637,18 @@ fn lwe_seeded_public_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: T
|
||||
|
||||
assert_eq!(msg, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_seeded_public_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn lwe_seeded_list_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Sync + Send>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
@@ -618,7 +659,6 @@ fn lwe_seeded_list_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Sync +
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -680,12 +720,17 @@ fn lwe_seeded_list_par_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus + Sync +
|
||||
|
||||
assert!(decoded.iter().all(|&x| x == msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_seeded_list_par_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn lwe_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn lwe_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: ClassicTestParams<Scalar>) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -694,7 +739,6 @@ fn lwe_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPara
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -742,13 +786,18 @@ fn lwe_seeded_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestPara
|
||||
|
||||
assert_eq!(msg, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_seeded_encrypt_decrypt_custom_mod);
|
||||
|
||||
fn lwe_seeded_allocate_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
@@ -758,7 +807,6 @@ fn lwe_seeded_allocate_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -799,6 +847,11 @@ fn lwe_seeded_allocate_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
assert_eq!(msg, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -820,7 +873,6 @@ fn test_u128_encryption() {
|
||||
let mut secret_generator =
|
||||
SecretRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed());
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
const MSG_BITS: u32 = 4;
|
||||
|
||||
for _ in 0..NB_TESTS {
|
||||
@@ -870,7 +922,7 @@ fn test_u128_encryption() {
|
||||
}
|
||||
|
||||
fn lwe_compact_public_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = LweDimension(params.polynomial_size.0);
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -880,7 +932,6 @@ fn lwe_compact_public_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -929,6 +980,11 @@ fn lwe_compact_public_encrypt_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
assert_eq!(msg, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
use super::*;
|
||||
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn lwe_encrypt_ks_decrypt_custom_mod<Scalar: UnsignedTorus + Send + Sync>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
@@ -15,7 +20,6 @@ fn lwe_encrypt_ks_decrypt_custom_mod<Scalar: UnsignedTorus + Send + Sync>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -94,6 +98,11 @@ fn lwe_encrypt_ks_decrypt_custom_mod<Scalar: UnsignedTorus + Send + Sync>(
|
||||
|
||||
assert_eq!(msg, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,11 @@ use crate::core_crypto::commons::generators::{
|
||||
};
|
||||
use crate::core_crypto::commons::math::random::ActivatedRandomGenerator;
|
||||
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn test_seeded_lwe_ksk_gen_equivalence<Scalar: UnsignedTorus + Send + Sync>(
|
||||
ciphertext_modulus: CiphertextModulus<Scalar>,
|
||||
) {
|
||||
@@ -25,9 +30,7 @@ fn test_seeded_lwe_ksk_gen_equivalence<Scalar: UnsignedTorus + Send + Sync>(
|
||||
let mut secret_generator =
|
||||
SecretRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed());
|
||||
|
||||
const NB_TEST: usize = 10;
|
||||
|
||||
for _ in 0..NB_TEST {
|
||||
for _ in 0..NB_TESTS {
|
||||
// Create the LweSecretKey
|
||||
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
input_lwe_dimension,
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
use super::*;
|
||||
|
||||
fn lwe_encrypt_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn lwe_encrypt_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -9,7 +16,6 @@ fn lwe_encrypt_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Test
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -58,12 +64,17 @@ fn lwe_encrypt_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Test
|
||||
|
||||
assert_eq!((msg + msg) % msg_modulus, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_encrypt_add_assign_decrypt_custom_mod);
|
||||
|
||||
fn lwe_encrypt_add_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn lwe_encrypt_add_decrypt_custom_mod<Scalar: UnsignedTorus>(params: ClassicTestParams<Scalar>) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -72,7 +83,6 @@ fn lwe_encrypt_add_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -121,13 +131,18 @@ fn lwe_encrypt_add_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<
|
||||
|
||||
assert_eq!((msg + msg) % msg_modulus, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_encrypt_add_decrypt_custom_mod);
|
||||
|
||||
fn lwe_encrypt_plaintext_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
@@ -137,7 +152,6 @@ fn lwe_encrypt_plaintext_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -184,13 +198,18 @@ fn lwe_encrypt_plaintext_add_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
assert_eq!((msg + msg) % msg_modulus, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_encrypt_plaintext_add_assign_decrypt_custom_mod);
|
||||
|
||||
fn lwe_encrypt_plaintext_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
@@ -200,7 +219,6 @@ fn lwe_encrypt_plaintext_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -247,13 +265,18 @@ fn lwe_encrypt_plaintext_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
assert_eq!(Scalar::ZERO, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_encrypt_plaintext_sub_assign_decrypt_custom_mod);
|
||||
|
||||
fn lwe_encrypt_opposite_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
@@ -263,7 +286,6 @@ fn lwe_encrypt_opposite_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -310,13 +332,18 @@ fn lwe_encrypt_opposite_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
|
||||
assert_eq!(msg.wrapping_neg() % msg_modulus, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_encrypt_opposite_assign_decrypt_custom_mod);
|
||||
|
||||
fn lwe_encrypt_ciphertext_cleartext_mul_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
@@ -326,7 +353,6 @@ fn lwe_encrypt_ciphertext_cleartext_mul_assign_decrypt_custom_mod<Scalar: Unsign
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -374,12 +400,19 @@ fn lwe_encrypt_ciphertext_cleartext_mul_assign_decrypt_custom_mod<Scalar: Unsign
|
||||
|
||||
assert_eq!(msg * cleartext.0 % msg_modulus, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_encrypt_ciphertext_cleartext_mul_assign_decrypt_custom_mod);
|
||||
|
||||
fn lwe_encrypt_cleartext_mul_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn lwe_encrypt_cleartext_mul_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -388,7 +421,6 @@ fn lwe_encrypt_cleartext_mul_decrypt_custom_mod<Scalar: UnsignedTorus>(params: T
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -438,12 +470,19 @@ fn lwe_encrypt_cleartext_mul_decrypt_custom_mod<Scalar: UnsignedTorus>(params: T
|
||||
|
||||
assert_eq!((msg * cleartext.0) % msg_modulus, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_encrypt_cleartext_mul_decrypt_custom_mod);
|
||||
|
||||
fn lwe_encrypt_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn lwe_encrypt_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -452,7 +491,6 @@ fn lwe_encrypt_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Test
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -521,12 +559,17 @@ fn lwe_encrypt_sub_assign_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Test
|
||||
|
||||
assert_eq!(Scalar::ONE, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_encrypt_sub_assign_decrypt_custom_mod);
|
||||
|
||||
fn lwe_encrypt_sub_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
fn lwe_encrypt_sub_decrypt_custom_mod<Scalar: UnsignedTorus>(params: ClassicTestParams<Scalar>) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
@@ -535,7 +578,6 @@ fn lwe_encrypt_sub_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -606,6 +648,11 @@ fn lwe_encrypt_sub_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<
|
||||
|
||||
assert_eq!(Scalar::ONE, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,12 +11,17 @@ use crate::core_crypto::commons::test_tools::new_secret_random_generator;
|
||||
use crate::core_crypto::entities::*;
|
||||
use crate::core_crypto::prelude::CastFrom;
|
||||
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn test_parallel_and_seeded_multi_bit_bsk_gen_equivalence<
|
||||
T: UnsignedTorus + CastFrom<usize> + Sync + Send,
|
||||
>(
|
||||
ciphertext_modulus: CiphertextModulus<T>,
|
||||
) {
|
||||
for _ in 0..10 {
|
||||
for _ in 0..NB_TESTS {
|
||||
let mut lwe_dim =
|
||||
LweDimension(crate::core_crypto::commons::test_tools::random_usize_between(5..10));
|
||||
let glwe_dim =
|
||||
|
||||
@@ -1,36 +1,94 @@
|
||||
use super::*;
|
||||
use crate::core_crypto::keycache::KeyCacheAccess;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
|
||||
pub struct MultiBitParams<Scalar: UnsignedInteger> {
|
||||
pub input_lwe_dimension: LweDimension,
|
||||
pub lwe_modular_std_dev: StandardDev,
|
||||
pub decomp_base_log: DecompositionBaseLog,
|
||||
pub decomp_level_count: DecompositionLevelCount,
|
||||
pub glwe_dimension: GlweDimension,
|
||||
pub polynomial_size: PolynomialSize,
|
||||
pub glwe_modular_std_dev: StandardDev,
|
||||
pub message_modulus_log: CiphertextModulusLog,
|
||||
pub ciphertext_modulus: CiphertextModulus<Scalar>,
|
||||
pub grouping_factor: LweBskGroupingFactor,
|
||||
pub thread_count: ThreadCount,
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
// Divided by two compared to other tests, we are running the algorithm twice for determinism
|
||||
const NB_TESTS_LIGHT: usize = 5;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS_LIGHT: usize = 1;
|
||||
|
||||
pub fn generate_keys<
|
||||
Scalar: UnsignedTorus + Sync + Send + CastFrom<usize> + CastInto<usize> + Serialize + DeserializeOwned,
|
||||
>(
|
||||
params: MultiBitTestParams<Scalar>,
|
||||
rsc: &mut TestResources,
|
||||
) -> MultiBitBootstrapKeys<Scalar> {
|
||||
// Keygen is a bit slow on this one so we keep it out of the testing loop
|
||||
|
||||
// Create the LweSecretKey
|
||||
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
params.input_lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
params.glwe_dimension,
|
||||
params.polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_lwe_secret_key = output_glwe_secret_key.clone().into_lwe_secret_key();
|
||||
|
||||
let mut bsk = LweMultiBitBootstrapKey::new(
|
||||
Scalar::ZERO,
|
||||
params.glwe_dimension.to_glwe_size(),
|
||||
params.polynomial_size,
|
||||
params.decomp_base_log,
|
||||
params.decomp_level_count,
|
||||
params.input_lwe_dimension,
|
||||
params.grouping_factor,
|
||||
params.ciphertext_modulus,
|
||||
);
|
||||
|
||||
par_generate_lwe_multi_bit_bootstrap_key(
|
||||
&input_lwe_secret_key,
|
||||
&output_glwe_secret_key,
|
||||
&mut bsk,
|
||||
params.glwe_modular_std_dev,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
let mut fbsk = FourierLweMultiBitBootstrapKey::new(
|
||||
params.input_lwe_dimension,
|
||||
params.glwe_dimension.to_glwe_size(),
|
||||
params.polynomial_size,
|
||||
params.decomp_base_log,
|
||||
params.decomp_level_count,
|
||||
params.grouping_factor,
|
||||
);
|
||||
|
||||
par_convert_standard_lwe_multi_bit_bootstrap_key_to_fourier(&bsk, &mut fbsk);
|
||||
|
||||
MultiBitBootstrapKeys {
|
||||
small_lwe_sk: input_lwe_secret_key,
|
||||
big_lwe_sk: output_lwe_secret_key,
|
||||
bsk,
|
||||
fbsk,
|
||||
}
|
||||
}
|
||||
|
||||
fn lwe_encrypt_multi_bit_pbs_decrypt_custom_mod<
|
||||
Scalar: UnsignedTorus + Sync + Send + CastFrom<usize> + CastInto<usize>,
|
||||
>(
|
||||
params: MultiBitParams<Scalar>,
|
||||
) {
|
||||
let input_lwe_dimension = params.input_lwe_dimension;
|
||||
fn lwe_encrypt_multi_bit_pbs_decrypt_custom_mod<Scalar>(params: MultiBitTestParams<Scalar>)
|
||||
where
|
||||
Scalar: UnsignedTorus
|
||||
+ Sync
|
||||
+ Send
|
||||
+ CastFrom<usize>
|
||||
+ CastInto<usize>
|
||||
+ Serialize
|
||||
+ DeserializeOwned,
|
||||
MultiBitTestParams<Scalar>: KeyCacheAccess<Keys = MultiBitBootstrapKeys<Scalar>>,
|
||||
{
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
let message_modulus_log = params.message_modulus_log;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let encoding_with_padding = get_encoding_with_padding(ciphertext_modulus);
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let decomp_base_log = params.decomp_base_log;
|
||||
let decomp_level_count = params.decomp_level_count;
|
||||
let grouping_factor = params.grouping_factor;
|
||||
let thread_count = params.thread_count;
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
@@ -43,7 +101,6 @@ fn lwe_encrypt_multi_bit_pbs_decrypt_custom_mod<
|
||||
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
let mut msg = msg_modulus;
|
||||
const NB_TESTS: usize = 10;
|
||||
|
||||
let accumulator = generate_accumulator(
|
||||
polynomial_size,
|
||||
@@ -59,56 +116,17 @@ fn lwe_encrypt_multi_bit_pbs_decrypt_custom_mod<
|
||||
ciphertext_modulus
|
||||
));
|
||||
|
||||
// Keygen is a bit slow on this one so we keep it out of the testing loop
|
||||
// Create the LweSecretKey
|
||||
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
input_lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_lwe_secret_key = output_glwe_secret_key.clone().into_lwe_secret_key();
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
|
||||
let mut bsk = LweMultiBitBootstrapKey::new(
|
||||
Scalar::ZERO,
|
||||
glwe_dimension.to_glwe_size(),
|
||||
polynomial_size,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
input_lwe_dimension,
|
||||
grouping_factor,
|
||||
ciphertext_modulus,
|
||||
);
|
||||
|
||||
par_generate_lwe_multi_bit_bootstrap_key(
|
||||
&input_lwe_secret_key,
|
||||
&output_glwe_secret_key,
|
||||
&mut bsk,
|
||||
glwe_modular_std_dev,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let (input_lwe_secret_key, output_lwe_secret_key, bsk, fbsk) =
|
||||
(keys.small_lwe_sk, keys.big_lwe_sk, keys.bsk, keys.fbsk);
|
||||
|
||||
assert!(check_encrypted_content_respects_mod(
|
||||
&*bsk,
|
||||
ciphertext_modulus
|
||||
));
|
||||
|
||||
let mut fbsk = FourierLweMultiBitBootstrapKey::new(
|
||||
input_lwe_dimension,
|
||||
glwe_dimension.to_glwe_size(),
|
||||
polynomial_size,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
grouping_factor,
|
||||
);
|
||||
|
||||
par_convert_standard_lwe_multi_bit_bootstrap_key_to_fourier(&bsk, &mut fbsk);
|
||||
|
||||
drop(bsk);
|
||||
|
||||
while msg != Scalar::ZERO {
|
||||
msg = msg.wrapping_sub(Scalar::ONE);
|
||||
for _ in 0..NB_TESTS {
|
||||
@@ -152,26 +170,33 @@ fn lwe_encrypt_multi_bit_pbs_decrypt_custom_mod<
|
||||
|
||||
assert_eq!(decoded, f(msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fn lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod<
|
||||
Scalar: UnsignedTorus + Sync + Send + CastFrom<usize> + CastInto<usize>,
|
||||
>(
|
||||
params: MultiBitParams<Scalar>,
|
||||
) {
|
||||
let input_lwe_dimension = params.input_lwe_dimension;
|
||||
fn lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod<Scalar>(
|
||||
params: MultiBitTestParams<Scalar>,
|
||||
) where
|
||||
Scalar: UnsignedTorus
|
||||
+ Sync
|
||||
+ Send
|
||||
+ CastFrom<usize>
|
||||
+ CastInto<usize>
|
||||
+ Serialize
|
||||
+ DeserializeOwned,
|
||||
MultiBitTestParams<Scalar>: KeyCacheAccess<Keys = MultiBitBootstrapKeys<Scalar>>,
|
||||
{
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
let message_modulus_log = params.message_modulus_log;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let encoding_with_padding = get_encoding_with_padding(ciphertext_modulus);
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let decomp_base_log = params.decomp_base_log;
|
||||
let decomp_level_count = params.decomp_level_count;
|
||||
let grouping_factor = params.grouping_factor;
|
||||
let thread_count = params.thread_count;
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
@@ -184,8 +209,6 @@ fn lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod<
|
||||
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
let mut msg = msg_modulus;
|
||||
// Divided by two compared to other tests, we are running the algorithm twice for determinism
|
||||
const NB_TESTS: usize = 5;
|
||||
|
||||
let accumulator = generate_accumulator(
|
||||
polynomial_size,
|
||||
@@ -201,59 +224,20 @@ fn lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod<
|
||||
ciphertext_modulus
|
||||
));
|
||||
|
||||
// Keygen is a bit slow on this one so we keep it out of the testing loop
|
||||
// Create the LweSecretKey
|
||||
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
input_lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_lwe_secret_key = output_glwe_secret_key.clone().into_lwe_secret_key();
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
|
||||
let mut bsk = LweMultiBitBootstrapKey::new(
|
||||
Scalar::ZERO,
|
||||
glwe_dimension.to_glwe_size(),
|
||||
polynomial_size,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
input_lwe_dimension,
|
||||
grouping_factor,
|
||||
ciphertext_modulus,
|
||||
);
|
||||
|
||||
par_generate_lwe_multi_bit_bootstrap_key(
|
||||
&input_lwe_secret_key,
|
||||
&output_glwe_secret_key,
|
||||
&mut bsk,
|
||||
glwe_modular_std_dev,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let (input_lwe_secret_key, output_lwe_secret_key, bsk, fbsk) =
|
||||
(keys.small_lwe_sk, keys.big_lwe_sk, keys.bsk, keys.fbsk);
|
||||
|
||||
assert!(check_encrypted_content_respects_mod(
|
||||
&*bsk,
|
||||
ciphertext_modulus
|
||||
));
|
||||
|
||||
let mut fbsk = FourierLweMultiBitBootstrapKey::new(
|
||||
input_lwe_dimension,
|
||||
glwe_dimension.to_glwe_size(),
|
||||
polynomial_size,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
grouping_factor,
|
||||
);
|
||||
|
||||
par_convert_standard_lwe_multi_bit_bootstrap_key_to_fourier(&bsk, &mut fbsk);
|
||||
|
||||
drop(bsk);
|
||||
|
||||
while msg != Scalar::ZERO {
|
||||
msg = msg.wrapping_sub(Scalar::ONE);
|
||||
for _ in 0..NB_TESTS {
|
||||
for _ in 0..NB_TESTS_LIGHT {
|
||||
let plaintext = Plaintext(msg * delta);
|
||||
|
||||
let lwe_ciphertext_in = allocate_and_encrypt_new_lwe_ciphertext(
|
||||
@@ -318,26 +302,32 @@ fn lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod<
|
||||
|
||||
assert_eq!(out_pbs_ct_other, out_pbs_ct);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fn lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod<
|
||||
Scalar: UnsignedTorus + Sync + Send + CastFrom<usize> + CastInto<usize>,
|
||||
>(
|
||||
params: MultiBitParams<Scalar>,
|
||||
) {
|
||||
let input_lwe_dimension = params.input_lwe_dimension;
|
||||
fn lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod<Scalar>(params: MultiBitTestParams<Scalar>)
|
||||
where
|
||||
Scalar: UnsignedTorus
|
||||
+ Sync
|
||||
+ Send
|
||||
+ CastFrom<usize>
|
||||
+ CastInto<usize>
|
||||
+ Serialize
|
||||
+ DeserializeOwned,
|
||||
MultiBitTestParams<Scalar>: KeyCacheAccess<Keys = MultiBitBootstrapKeys<Scalar>>,
|
||||
{
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
let message_modulus_log = params.message_modulus_log;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let encoding_with_padding = get_encoding_with_padding(ciphertext_modulus);
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let decomp_base_log = params.decomp_base_log;
|
||||
let decomp_level_count = params.decomp_level_count;
|
||||
let grouping_factor = params.grouping_factor;
|
||||
let thread_count = params.thread_count;
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
@@ -350,7 +340,6 @@ fn lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod<
|
||||
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
let mut msg = msg_modulus;
|
||||
const NB_TESTS: usize = 10;
|
||||
|
||||
let accumulator = generate_accumulator(
|
||||
polynomial_size,
|
||||
@@ -366,37 +355,11 @@ fn lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod<
|
||||
ciphertext_modulus
|
||||
));
|
||||
|
||||
// Keygen is a bit slow on this one so we keep it out of the testing loop
|
||||
// Create the LweSecretKey
|
||||
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
input_lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_lwe_secret_key = output_glwe_secret_key.clone().into_lwe_secret_key();
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
|
||||
let mut bsk = LweMultiBitBootstrapKey::new(
|
||||
Scalar::ZERO,
|
||||
glwe_dimension.to_glwe_size(),
|
||||
polynomial_size,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
input_lwe_dimension,
|
||||
grouping_factor,
|
||||
ciphertext_modulus,
|
||||
);
|
||||
|
||||
par_generate_lwe_multi_bit_bootstrap_key(
|
||||
&input_lwe_secret_key,
|
||||
&output_glwe_secret_key,
|
||||
&mut bsk,
|
||||
glwe_modular_std_dev,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let (input_lwe_secret_key, output_lwe_secret_key, bsk) =
|
||||
(keys.small_lwe_sk, keys.big_lwe_sk, keys.bsk);
|
||||
|
||||
assert!(check_encrypted_content_respects_mod(
|
||||
&*bsk,
|
||||
@@ -446,26 +409,33 @@ fn lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod<
|
||||
|
||||
assert_eq!(decoded, f(msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fn std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod<
|
||||
Scalar: UnsignedTorus + Sync + Send + CastFrom<usize> + CastInto<usize>,
|
||||
>(
|
||||
params: MultiBitParams<Scalar>,
|
||||
) {
|
||||
let input_lwe_dimension = params.input_lwe_dimension;
|
||||
fn std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod<Scalar>(
|
||||
params: MultiBitTestParams<Scalar>,
|
||||
) where
|
||||
Scalar: UnsignedTorus
|
||||
+ Sync
|
||||
+ Send
|
||||
+ CastFrom<usize>
|
||||
+ CastInto<usize>
|
||||
+ Serialize
|
||||
+ DeserializeOwned,
|
||||
MultiBitTestParams<Scalar>: KeyCacheAccess<Keys = MultiBitBootstrapKeys<Scalar>>,
|
||||
{
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
let message_modulus_log = params.message_modulus_log;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let encoding_with_padding = get_encoding_with_padding(ciphertext_modulus);
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let decomp_base_log = params.decomp_base_log;
|
||||
let decomp_level_count = params.decomp_level_count;
|
||||
let grouping_factor = params.grouping_factor;
|
||||
let thread_count = params.thread_count;
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
@@ -478,8 +448,6 @@ fn std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod<
|
||||
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
let mut msg = msg_modulus;
|
||||
// Divided by two compared to other tests, we are running the algorithm twice for determinism
|
||||
const NB_TESTS: usize = 5;
|
||||
|
||||
let accumulator = generate_accumulator(
|
||||
polynomial_size,
|
||||
@@ -495,37 +463,11 @@ fn std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod<
|
||||
ciphertext_modulus
|
||||
));
|
||||
|
||||
// Keygen is a bit slow on this one so we keep it out of the testing loop
|
||||
// Create the LweSecretKey
|
||||
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
input_lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_lwe_secret_key = output_glwe_secret_key.clone().into_lwe_secret_key();
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
|
||||
let mut bsk = LweMultiBitBootstrapKey::new(
|
||||
Scalar::ZERO,
|
||||
glwe_dimension.to_glwe_size(),
|
||||
polynomial_size,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
input_lwe_dimension,
|
||||
grouping_factor,
|
||||
ciphertext_modulus,
|
||||
);
|
||||
|
||||
par_generate_lwe_multi_bit_bootstrap_key(
|
||||
&input_lwe_secret_key,
|
||||
&output_glwe_secret_key,
|
||||
&mut bsk,
|
||||
glwe_modular_std_dev,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let (input_lwe_secret_key, output_lwe_secret_key, bsk) =
|
||||
(keys.small_lwe_sk, keys.big_lwe_sk, keys.bsk);
|
||||
|
||||
assert!(check_encrypted_content_respects_mod(
|
||||
&*bsk,
|
||||
@@ -599,179 +541,98 @@ fn std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod<
|
||||
|
||||
assert_eq!(out_pbs_ct_other, out_pbs_ct);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield
|
||||
// correct computations
|
||||
const MULTI_BIT_2_2_2_PARAMS: MultiBitParams<u64> = MultiBitParams {
|
||||
input_lwe_dimension: LweDimension(818),
|
||||
lwe_modular_std_dev: StandardDev(0.000002226459789930014),
|
||||
decomp_base_log: DecompositionBaseLog(22),
|
||||
decomp_level_count: DecompositionLevelCount(1),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
glwe_modular_std_dev: StandardDev(0.0000000000000003152931493498455),
|
||||
message_modulus_log: CiphertextModulusLog(4),
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
grouping_factor: LweBskGroupingFactor(2),
|
||||
thread_count: ThreadCount(5),
|
||||
};
|
||||
|
||||
const MULTI_BIT_2_2_3_PARAMS: MultiBitParams<u64> = MultiBitParams {
|
||||
input_lwe_dimension: LweDimension(888),
|
||||
lwe_modular_std_dev: StandardDev(0.0000006125031601933181),
|
||||
decomp_base_log: DecompositionBaseLog(21),
|
||||
decomp_level_count: DecompositionLevelCount(1),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
glwe_modular_std_dev: StandardDev(0.0000000000000003152931493498455),
|
||||
message_modulus_log: CiphertextModulusLog(4),
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
grouping_factor: LweBskGroupingFactor(3),
|
||||
thread_count: ThreadCount(12),
|
||||
};
|
||||
|
||||
#[test]
|
||||
pub fn test_lwe_encrypt_multi_bit_pbs_decrypt_factor_2_thread_5_native_mod() {
|
||||
lwe_encrypt_multi_bit_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(5),
|
||||
..MULTI_BIT_2_2_2_PARAMS
|
||||
});
|
||||
lwe_encrypt_multi_bit_pbs_decrypt_custom_mod::<u64>(MULTI_BIT_2_2_2_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_lwe_encrypt_multi_bit_pbs_decrypt_factor_3_thread_12_native_mod() {
|
||||
lwe_encrypt_multi_bit_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(12),
|
||||
..MULTI_BIT_2_2_3_PARAMS
|
||||
});
|
||||
lwe_encrypt_multi_bit_pbs_decrypt_custom_mod::<u64>(MULTI_BIT_2_2_3_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_lwe_encrypt_multi_bit_pbs_decrypt_factor_2_thread_5_custom_mod() {
|
||||
lwe_encrypt_multi_bit_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(5),
|
||||
message_modulus_log: CiphertextModulusLog(3),
|
||||
ciphertext_modulus: CiphertextModulus::try_new_power_of_2(63).unwrap(),
|
||||
..MULTI_BIT_2_2_2_PARAMS
|
||||
});
|
||||
lwe_encrypt_multi_bit_pbs_decrypt_custom_mod::<u64>(MULTI_BIT_2_2_2_CUSTOM_MOD_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_lwe_encrypt_multi_bit_pbs_decrypt_factor_3_thread_12_custom_mod() {
|
||||
lwe_encrypt_multi_bit_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(12),
|
||||
message_modulus_log: CiphertextModulusLog(3),
|
||||
ciphertext_modulus: CiphertextModulus::try_new_power_of_2(63).unwrap(),
|
||||
..MULTI_BIT_2_2_3_PARAMS
|
||||
});
|
||||
lwe_encrypt_multi_bit_pbs_decrypt_custom_mod::<u64>(MULTI_BIT_2_2_3_CUSTOM_MOD_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_factor_2_thread_5_native_mod() {
|
||||
lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(5),
|
||||
..MULTI_BIT_2_2_2_PARAMS
|
||||
});
|
||||
lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(MULTI_BIT_2_2_2_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_factor_3_thread_12_native_mod() {
|
||||
lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(12),
|
||||
..MULTI_BIT_2_2_3_PARAMS
|
||||
});
|
||||
lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(MULTI_BIT_2_2_3_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_factor_2_thread_5_custom_mod() {
|
||||
lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(5),
|
||||
message_modulus_log: CiphertextModulusLog(3),
|
||||
ciphertext_modulus: CiphertextModulus::try_new_power_of_2(63).unwrap(),
|
||||
..MULTI_BIT_2_2_2_PARAMS
|
||||
});
|
||||
lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(
|
||||
MULTI_BIT_2_2_2_CUSTOM_MOD_PARAMS,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_factor_3_thread_12_custom_mod() {
|
||||
lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(12),
|
||||
message_modulus_log: CiphertextModulusLog(3),
|
||||
ciphertext_modulus: CiphertextModulus::try_new_power_of_2(63).unwrap(),
|
||||
..MULTI_BIT_2_2_3_PARAMS
|
||||
});
|
||||
lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(
|
||||
MULTI_BIT_2_2_3_CUSTOM_MOD_PARAMS,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_lwe_encrypt_std_multi_bit_pbs_decrypt_factor_2_thread_5_native_mod() {
|
||||
lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(5),
|
||||
..MULTI_BIT_2_2_2_PARAMS
|
||||
});
|
||||
lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod::<u64>(MULTI_BIT_2_2_2_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_lwe_encrypt_std_multi_bit_pbs_decrypt_factor_3_thread_12_native_mod() {
|
||||
lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(12),
|
||||
..MULTI_BIT_2_2_3_PARAMS
|
||||
});
|
||||
lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod::<u64>(MULTI_BIT_2_2_3_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_lwe_encrypt_std_multi_bit_pbs_decrypt_factor_2_thread_5_custom_mod() {
|
||||
lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(5),
|
||||
message_modulus_log: CiphertextModulusLog(3),
|
||||
ciphertext_modulus: CiphertextModulus::try_new_power_of_2(63).unwrap(),
|
||||
..MULTI_BIT_2_2_2_PARAMS
|
||||
});
|
||||
lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod::<u64>(MULTI_BIT_2_2_2_CUSTOM_MOD_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_lwe_encrypt_std_multi_bit_pbs_decrypt_factor_3_thread_12_custom_mod() {
|
||||
lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(12),
|
||||
message_modulus_log: CiphertextModulusLog(3),
|
||||
ciphertext_modulus: CiphertextModulus::try_new_power_of_2(63).unwrap(),
|
||||
..MULTI_BIT_2_2_3_PARAMS
|
||||
});
|
||||
lwe_encrypt_std_multi_bit_pbs_decrypt_custom_mod::<u64>(MULTI_BIT_2_2_3_CUSTOM_MOD_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn std_test_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_factor_2_thread_5_native_mod() {
|
||||
std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(5),
|
||||
..MULTI_BIT_2_2_2_PARAMS
|
||||
});
|
||||
std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(MULTI_BIT_2_2_2_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn std_test_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_factor_3_thread_12_native_mod() {
|
||||
std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(12),
|
||||
..MULTI_BIT_2_2_3_PARAMS
|
||||
});
|
||||
std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(MULTI_BIT_2_2_3_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn std_test_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_factor_2_thread_5_custom_mod() {
|
||||
std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(5),
|
||||
message_modulus_log: CiphertextModulusLog(3),
|
||||
ciphertext_modulus: CiphertextModulus::try_new_power_of_2(63).unwrap(),
|
||||
..MULTI_BIT_2_2_2_PARAMS
|
||||
});
|
||||
std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(
|
||||
MULTI_BIT_2_2_2_CUSTOM_MOD_PARAMS,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn std_test_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_factor_3_thread_12_custom_mod() {
|
||||
std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(MultiBitParams {
|
||||
thread_count: ThreadCount(12),
|
||||
message_modulus_log: CiphertextModulusLog(3),
|
||||
ciphertext_modulus: CiphertextModulus::try_new_power_of_2(63).unwrap(),
|
||||
..MULTI_BIT_2_2_3_PARAMS
|
||||
});
|
||||
std_lwe_encrypt_multi_bit_deterministic_pbs_decrypt_custom_mod::<u64>(
|
||||
MULTI_BIT_2_2_3_CUSTOM_MOD_PARAMS,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,64 @@
|
||||
use super::*;
|
||||
use crate::core_crypto::keycache::KeyCacheAccess;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn generate_keys<Scalar: UnsignedTorus + Sync + Send + Serialize + DeserializeOwned>(
|
||||
params: PackingKeySwitchTestParams<Scalar>,
|
||||
rsc: &mut TestResources,
|
||||
) -> PackingKeySwitchKeys<Scalar> {
|
||||
let lwe_sk = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
params.lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
|
||||
let glwe_sk = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
params.glwe_dimension,
|
||||
params.polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
|
||||
let pksk = allocate_and_generate_new_lwe_packing_keyswitch_key(
|
||||
&lwe_sk,
|
||||
&glwe_sk,
|
||||
params.pbs_base_log,
|
||||
params.pbs_level,
|
||||
params.glwe_modular_std_dev,
|
||||
params.ciphertext_modulus,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
assert!(check_encrypted_content_respects_mod(
|
||||
&pksk,
|
||||
params.ciphertext_modulus
|
||||
));
|
||||
|
||||
PackingKeySwitchKeys {
|
||||
lwe_sk,
|
||||
glwe_sk,
|
||||
pksk,
|
||||
}
|
||||
}
|
||||
fn lwe_encrypt_pks_to_glwe_decrypt_custom_mod<Scalar, P>(params: P)
|
||||
where
|
||||
Scalar: UnsignedTorus + Serialize + DeserializeOwned,
|
||||
P: Into<PackingKeySwitchTestParams<Scalar>>,
|
||||
PackingKeySwitchTestParams<Scalar>: KeyCacheAccess<Keys = PackingKeySwitchKeys<Scalar>>,
|
||||
{
|
||||
let params = params.into();
|
||||
|
||||
fn lwe_encrypt_pks_to_glwe_decrypt_custom_mod<Scalar: UnsignedTorus>(params: TestParams<Scalar>) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
let message_modulus_log = params.message_modulus_log;
|
||||
let encoding_with_padding = get_encoding_with_padding(ciphertext_modulus);
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let decomp_base_log = params.pbs_base_log;
|
||||
let decomp_level_count = params.pbs_level;
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
const NB_TESTS: usize = 10;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -22,31 +66,9 @@ fn lwe_encrypt_pks_to_glwe_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Tes
|
||||
while msg != Scalar::ZERO {
|
||||
msg = msg.wrapping_sub(Scalar::ONE);
|
||||
for _ in 0..NB_TESTS {
|
||||
let lwe_sk = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
|
||||
let glwe_sk = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
|
||||
let pksk = allocate_and_generate_new_lwe_packing_keyswitch_key(
|
||||
&lwe_sk,
|
||||
&glwe_sk,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
glwe_modular_std_dev,
|
||||
ciphertext_modulus,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
assert!(check_encrypted_content_respects_mod(
|
||||
&pksk,
|
||||
ciphertext_modulus
|
||||
));
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let (pksk, lwe_sk, glwe_sk) = (keys.pksk, keys.lwe_sk, keys.glwe_sk);
|
||||
|
||||
let plaintext = Plaintext(msg * delta);
|
||||
|
||||
@@ -86,29 +108,31 @@ fn lwe_encrypt_pks_to_glwe_decrypt_custom_mod<Scalar: UnsignedTorus>(params: Tes
|
||||
|
||||
assert_eq!(msg, decoded);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_encrypt_pks_to_glwe_decrypt_custom_mod);
|
||||
|
||||
fn lwe_list_encrypt_pks_to_glwe_decrypt_custom_mod<Scalar: UnsignedTorus + Send + Sync>(
|
||||
params: TestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
fn lwe_list_encrypt_pks_to_glwe_decrypt_custom_mod<Scalar, P>(params: P)
|
||||
where
|
||||
Scalar: UnsignedTorus + Serialize + DeserializeOwned,
|
||||
P: Into<PackingKeySwitchTestParams<Scalar>>,
|
||||
PackingKeySwitchTestParams<Scalar>: KeyCacheAccess<Keys = PackingKeySwitchKeys<Scalar>>,
|
||||
{
|
||||
let params = params.into();
|
||||
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
let message_modulus_log = params.message_modulus_log;
|
||||
let encoding_with_padding = get_encoding_with_padding(ciphertext_modulus);
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let decomp_base_log = params.pbs_base_log;
|
||||
let decomp_level_count = params.pbs_level;
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
// These tests are pretty heavy, cut down a bit
|
||||
const NB_TESTS: usize = 5;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let mut msg = msg_modulus;
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
@@ -116,31 +140,9 @@ fn lwe_list_encrypt_pks_to_glwe_decrypt_custom_mod<Scalar: UnsignedTorus + Send
|
||||
while msg != Scalar::ZERO {
|
||||
msg = msg.wrapping_sub(Scalar::ONE);
|
||||
for _ in 0..NB_TESTS {
|
||||
let lwe_sk = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
|
||||
let glwe_sk = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
|
||||
let pksk = allocate_and_generate_new_lwe_packing_keyswitch_key(
|
||||
&lwe_sk,
|
||||
&glwe_sk,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
glwe_modular_std_dev,
|
||||
ciphertext_modulus,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
assert!(check_encrypted_content_respects_mod(
|
||||
&pksk,
|
||||
ciphertext_modulus
|
||||
));
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let (pksk, lwe_sk, glwe_sk) = (keys.pksk, keys.lwe_sk, keys.glwe_sk);
|
||||
|
||||
let mut input_lwe_list = LweCiphertextList::new(
|
||||
Scalar::ZERO,
|
||||
@@ -212,6 +214,11 @@ fn lwe_list_encrypt_pks_to_glwe_decrypt_custom_mod<Scalar: UnsignedTorus + Send
|
||||
|
||||
assert_eq!(decrypted_plaintext_list, input_plaintext_list);
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,11 @@ use crate::core_crypto::commons::generators::{
|
||||
};
|
||||
use crate::core_crypto::commons::math::random::ActivatedRandomGenerator;
|
||||
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn test_seeded_lwe_pksk_gen_equivalence<Scalar: UnsignedTorus>(
|
||||
ciphertext_modulus: CiphertextModulus<Scalar>,
|
||||
) {
|
||||
@@ -26,9 +31,7 @@ fn test_seeded_lwe_pksk_gen_equivalence<Scalar: UnsignedTorus>(
|
||||
let mut secret_generator =
|
||||
SecretRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed());
|
||||
|
||||
const NB_TEST: usize = 10;
|
||||
|
||||
for _ in 0..NB_TEST {
|
||||
for _ in 0..NB_TESTS {
|
||||
// Create the LweSecretKey
|
||||
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
input_lwe_dimension,
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
use super::*;
|
||||
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
fn test_parallel_pfpks_equivalence<Scalar: UnsignedTorus + Send + Sync>(
|
||||
ciphertext_modulus: CiphertextModulus<Scalar>,
|
||||
) {
|
||||
@@ -26,7 +31,7 @@ fn test_parallel_pfpks_equivalence<Scalar: UnsignedTorus + Send + Sync>(
|
||||
ciphertext_modulus,
|
||||
);
|
||||
|
||||
for _ in 0..10 {
|
||||
for _ in 0..NB_TESTS {
|
||||
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
input_key_lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
@@ -98,7 +103,7 @@ fn test_parallel_pfpks_equivalence<Scalar: UnsignedTorus + Send + Sync>(
|
||||
|
||||
// Small sizes
|
||||
{
|
||||
for _ in 0..10 {
|
||||
for _ in 0..NB_TESTS {
|
||||
let decomp_base_log = DecompositionBaseLog(
|
||||
crate::core_crypto::commons::test_tools::random_usize_between(2..5),
|
||||
);
|
||||
@@ -128,7 +133,7 @@ fn test_parallel_pfpks_equivalence<Scalar: UnsignedTorus + Send + Sync>(
|
||||
ciphertext_modulus,
|
||||
);
|
||||
|
||||
for _ in 0..10 {
|
||||
for _ in 0..NB_TESTS {
|
||||
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
input_key_lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
|
||||
@@ -1,21 +1,90 @@
|
||||
use super::*;
|
||||
use crate::core_crypto::keycache::KeyCacheAccess;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
|
||||
fn lwe_encrypt_pbs_decrypt_custom_mod<
|
||||
Scalar: UnsignedTorus + Sync + Send + CastFrom<usize> + CastInto<usize>,
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
|
||||
pub fn generate_keys<
|
||||
Scalar: UnsignedTorus + Sync + Send + CastFrom<usize> + CastInto<usize> + Serialize + DeserializeOwned,
|
||||
>(
|
||||
params: TestParams<Scalar>,
|
||||
) {
|
||||
let input_lwe_dimension = params.lwe_dimension;
|
||||
params: ClassicTestParams<Scalar>,
|
||||
rsc: &mut TestResources,
|
||||
) -> ClassicBootstrapKeys<Scalar> {
|
||||
// Create the LweSecretKey
|
||||
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
params.lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
params.glwe_dimension,
|
||||
params.polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_lwe_secret_key = output_glwe_secret_key.clone().into_lwe_secret_key();
|
||||
|
||||
let mut bsk = LweBootstrapKey::new(
|
||||
Scalar::ZERO,
|
||||
params.glwe_dimension.to_glwe_size(),
|
||||
params.polynomial_size,
|
||||
params.pbs_base_log,
|
||||
params.pbs_level,
|
||||
params.lwe_dimension,
|
||||
params.ciphertext_modulus,
|
||||
);
|
||||
|
||||
par_generate_lwe_bootstrap_key(
|
||||
&input_lwe_secret_key,
|
||||
&output_glwe_secret_key,
|
||||
&mut bsk,
|
||||
params.glwe_modular_std_dev,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
assert!(check_encrypted_content_respects_mod(
|
||||
&*bsk,
|
||||
params.ciphertext_modulus
|
||||
));
|
||||
|
||||
let mut fbsk = FourierLweBootstrapKey::new(
|
||||
params.lwe_dimension,
|
||||
params.glwe_dimension.to_glwe_size(),
|
||||
params.polynomial_size,
|
||||
params.pbs_base_log,
|
||||
params.pbs_level,
|
||||
);
|
||||
|
||||
par_convert_standard_lwe_bootstrap_key_to_fourier(&bsk, &mut fbsk);
|
||||
|
||||
ClassicBootstrapKeys {
|
||||
small_lwe_sk: input_lwe_secret_key,
|
||||
big_lwe_sk: output_lwe_secret_key,
|
||||
bsk,
|
||||
fbsk,
|
||||
}
|
||||
}
|
||||
|
||||
fn lwe_encrypt_pbs_decrypt_custom_mod<Scalar>(params: ClassicTestParams<Scalar>)
|
||||
where
|
||||
Scalar: UnsignedTorus
|
||||
+ Sync
|
||||
+ Send
|
||||
+ CastFrom<usize>
|
||||
+ CastInto<usize>
|
||||
+ Serialize
|
||||
+ DeserializeOwned,
|
||||
ClassicTestParams<Scalar>: KeyCacheAccess<Keys = ClassicBootstrapKeys<Scalar>>,
|
||||
{
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
let message_modulus_log = params.message_modulus_log;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
let encoding_with_padding = get_encoding_with_padding(ciphertext_modulus);
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let decomp_base_log = params.pbs_base_log;
|
||||
let decomp_level_count = params.pbs_level;
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
@@ -27,7 +96,6 @@ fn lwe_encrypt_pbs_decrypt_custom_mod<
|
||||
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
let mut msg = msg_modulus;
|
||||
const NB_TESTS: usize = 10;
|
||||
|
||||
let accumulator = generate_accumulator(
|
||||
polynomial_size,
|
||||
@@ -45,52 +113,11 @@ fn lwe_encrypt_pbs_decrypt_custom_mod<
|
||||
|
||||
while msg != Scalar::ZERO {
|
||||
msg = msg.wrapping_sub(Scalar::ONE);
|
||||
// Create the LweSecretKey
|
||||
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
input_lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_lwe_secret_key = output_glwe_secret_key.clone().into_lwe_secret_key();
|
||||
|
||||
let mut bsk = LweBootstrapKey::new(
|
||||
Scalar::ZERO,
|
||||
glwe_dimension.to_glwe_size(),
|
||||
polynomial_size,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
input_lwe_dimension,
|
||||
ciphertext_modulus,
|
||||
);
|
||||
|
||||
par_generate_lwe_bootstrap_key(
|
||||
&input_lwe_secret_key,
|
||||
&output_glwe_secret_key,
|
||||
&mut bsk,
|
||||
glwe_modular_std_dev,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
assert!(check_encrypted_content_respects_mod(
|
||||
&*bsk,
|
||||
ciphertext_modulus
|
||||
));
|
||||
|
||||
let mut fbsk = FourierLweBootstrapKey::new(
|
||||
input_lwe_dimension,
|
||||
glwe_dimension.to_glwe_size(),
|
||||
polynomial_size,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
);
|
||||
|
||||
par_convert_standard_lwe_bootstrap_key_to_fourier(&bsk, &mut fbsk);
|
||||
|
||||
drop(bsk);
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let (input_lwe_secret_key, output_lwe_secret_key, fbsk) =
|
||||
(keys.small_lwe_sk, keys.big_lwe_sk, keys.fbsk);
|
||||
|
||||
for _ in 0..NB_TESTS {
|
||||
let plaintext = Plaintext(msg * delta);
|
||||
@@ -132,13 +159,18 @@ fn lwe_encrypt_pbs_decrypt_custom_mod<
|
||||
|
||||
assert_eq!(decoded, f(msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
create_parametrized_test!(lwe_encrypt_pbs_decrypt_custom_mod);
|
||||
|
||||
// DISCLAIMER: all parameters here are not guaranteed to be secure or yield correct computations
|
||||
pub const TEST_PARAMS_4_BITS_NATIVE_U128: TestParams<u128> = TestParams {
|
||||
pub const TEST_PARAMS_4_BITS_NATIVE_U128: ClassicTestParams<u128> = ClassicTestParams {
|
||||
lwe_dimension: LweDimension(742),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
@@ -157,7 +189,7 @@ pub const TEST_PARAMS_4_BITS_NATIVE_U128: TestParams<u128> = TestParams {
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
};
|
||||
|
||||
pub const TEST_PARAMS_3_BITS_127_U128: TestParams<u128> = TestParams {
|
||||
pub const TEST_PARAMS_3_BITS_127_U128: ClassicTestParams<u128> = ClassicTestParams {
|
||||
lwe_dimension: LweDimension(742),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
@@ -176,14 +208,19 @@ pub const TEST_PARAMS_3_BITS_127_U128: TestParams<u128> = TestParams {
|
||||
ciphertext_modulus: CiphertextModulus::new(1 << 127),
|
||||
};
|
||||
|
||||
fn lwe_encrypt_pbs_f128_decrypt_custom_mod<
|
||||
Scalar: UnsignedTorus + Sync + Send + CastFrom<usize> + CastInto<usize>,
|
||||
>(
|
||||
params: TestParams<Scalar>,
|
||||
) {
|
||||
fn lwe_encrypt_pbs_f128_decrypt_custom_mod<Scalar>(params: ClassicTestParams<Scalar>)
|
||||
where
|
||||
Scalar: UnsignedTorus
|
||||
+ Sync
|
||||
+ Send
|
||||
+ CastFrom<usize>
|
||||
+ CastInto<usize>
|
||||
+ Serialize
|
||||
+ DeserializeOwned,
|
||||
ClassicTestParams<Scalar>: KeyCacheAccess<Keys = ClassicBootstrapKeys<Scalar>>,
|
||||
{
|
||||
let input_lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
let message_modulus_log = params.message_modulus_log;
|
||||
let msg_modulus = Scalar::ONE.shl(message_modulus_log.0);
|
||||
@@ -203,7 +240,6 @@ fn lwe_encrypt_pbs_f128_decrypt_custom_mod<
|
||||
|
||||
let delta: Scalar = encoding_with_padding / msg_modulus;
|
||||
let mut msg = msg_modulus;
|
||||
const NB_TESTS: usize = 10;
|
||||
|
||||
let accumulator = generate_accumulator(
|
||||
polynomial_size,
|
||||
@@ -221,40 +257,12 @@ fn lwe_encrypt_pbs_f128_decrypt_custom_mod<
|
||||
|
||||
while msg != Scalar::ZERO {
|
||||
msg = msg.wrapping_sub(Scalar::ONE);
|
||||
// Create the LweSecretKey
|
||||
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
input_lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let output_lwe_secret_key = output_glwe_secret_key.clone().into_lwe_secret_key();
|
||||
|
||||
let mut bsk = LweBootstrapKey::new(
|
||||
Scalar::ZERO,
|
||||
glwe_dimension.to_glwe_size(),
|
||||
polynomial_size,
|
||||
decomp_base_log,
|
||||
decomp_level_count,
|
||||
input_lwe_dimension,
|
||||
ciphertext_modulus,
|
||||
);
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
|
||||
par_generate_lwe_bootstrap_key(
|
||||
&input_lwe_secret_key,
|
||||
&output_glwe_secret_key,
|
||||
&mut bsk,
|
||||
glwe_modular_std_dev,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
assert!(check_encrypted_content_respects_mod(
|
||||
&*bsk,
|
||||
ciphertext_modulus
|
||||
));
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let (input_lwe_secret_key, output_lwe_secret_key, bsk) =
|
||||
(keys.small_lwe_sk, keys.big_lwe_sk, keys.bsk);
|
||||
|
||||
let mut fbsk = Fourier128LweBootstrapKey::new(
|
||||
input_lwe_dimension,
|
||||
@@ -308,6 +316,11 @@ fn lwe_encrypt_pbs_f128_decrypt_custom_mod<
|
||||
|
||||
assert_eq!(decoded, f(msg));
|
||||
}
|
||||
|
||||
// In coverage, we break after one while loop iteration, changing message values does not
|
||||
// yield higher coverage
|
||||
#[cfg(feature = "__coverage")]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
pub mod params;
|
||||
pub(crate) use params::*;
|
||||
|
||||
pub use super::misc::check_encrypted_content_respects_mod;
|
||||
use crate::core_crypto::keycache::KeyCacheAccess;
|
||||
use crate::core_crypto::prelude::*;
|
||||
use paste::paste;
|
||||
use std::fmt::Debug;
|
||||
|
||||
mod ggsw_encryption;
|
||||
mod glwe_encryption;
|
||||
@@ -13,11 +18,11 @@ mod lwe_keyswitch;
|
||||
mod lwe_keyswitch_key_generation;
|
||||
mod lwe_linear_algebra;
|
||||
mod lwe_multi_bit_bootstrap_key_generation;
|
||||
mod lwe_multi_bit_programmable_bootstrapping;
|
||||
pub(crate) mod lwe_multi_bit_programmable_bootstrapping;
|
||||
mod lwe_packing_keyswitch;
|
||||
mod lwe_packing_keyswitch_key_generation;
|
||||
mod lwe_private_functional_packing_keyswitch;
|
||||
mod lwe_programmable_bootstrapping;
|
||||
pub(crate) mod lwe_programmable_bootstrapping;
|
||||
mod noise_distribution;
|
||||
|
||||
pub struct TestResources {
|
||||
@@ -40,28 +45,14 @@ impl TestResources {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct TestParams<Scalar: UnsignedTorus> {
|
||||
pub lwe_dimension: LweDimension,
|
||||
pub glwe_dimension: GlweDimension,
|
||||
pub polynomial_size: PolynomialSize,
|
||||
pub lwe_modular_std_dev: StandardDev,
|
||||
pub glwe_modular_std_dev: StandardDev,
|
||||
pub pbs_base_log: DecompositionBaseLog,
|
||||
pub pbs_level: DecompositionLevelCount,
|
||||
pub ks_base_log: DecompositionBaseLog,
|
||||
pub ks_level: DecompositionLevelCount,
|
||||
pub pfks_level: DecompositionLevelCount,
|
||||
pub pfks_base_log: DecompositionBaseLog,
|
||||
pub pfks_modular_std_dev: StandardDev,
|
||||
pub cbs_level: DecompositionLevelCount,
|
||||
pub cbs_base_log: DecompositionBaseLog,
|
||||
pub message_modulus_log: CiphertextModulusLog,
|
||||
pub ciphertext_modulus: CiphertextModulus<Scalar>,
|
||||
impl Default for TestResources {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
// DISCLAIMER: all parameters here are not guaranteed to be secure or yield correct computations
|
||||
pub const TEST_PARAMS_4_BITS_NATIVE_U64: TestParams<u64> = TestParams {
|
||||
pub const TEST_PARAMS_4_BITS_NATIVE_U64: ClassicTestParams<u64> = ClassicTestParams {
|
||||
lwe_dimension: LweDimension(742),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
@@ -80,7 +71,7 @@ pub const TEST_PARAMS_4_BITS_NATIVE_U64: TestParams<u64> = TestParams {
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
};
|
||||
|
||||
pub const TEST_PARAMS_3_BITS_63_U64: TestParams<u64> = TestParams {
|
||||
pub const TEST_PARAMS_3_BITS_63_U64: ClassicTestParams<u64> = ClassicTestParams {
|
||||
lwe_dimension: LweDimension(742),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
@@ -99,7 +90,26 @@ pub const TEST_PARAMS_3_BITS_63_U64: TestParams<u64> = TestParams {
|
||||
ciphertext_modulus: CiphertextModulus::new(1 << 63),
|
||||
};
|
||||
|
||||
pub const DUMMY_NATIVE_U32: TestParams<u32> = TestParams {
|
||||
pub const TEST_PARAMS_3_BITS_SOLINAS_U64: ClassicTestParams<u64> = ClassicTestParams {
|
||||
lwe_dimension: LweDimension(742),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
lwe_modular_std_dev: StandardDev(0.000007069849454709433),
|
||||
glwe_modular_std_dev: StandardDev(0.00000000000000029403601535432533),
|
||||
pbs_base_log: DecompositionBaseLog(23),
|
||||
pbs_level: DecompositionLevelCount(1),
|
||||
ks_level: DecompositionLevelCount(5),
|
||||
ks_base_log: DecompositionBaseLog(3),
|
||||
pfks_level: DecompositionLevelCount(1),
|
||||
pfks_base_log: DecompositionBaseLog(23),
|
||||
pfks_modular_std_dev: StandardDev(0.00000000000000029403601535432533),
|
||||
cbs_level: DecompositionLevelCount(0),
|
||||
cbs_base_log: DecompositionBaseLog(0),
|
||||
message_modulus_log: CiphertextModulusLog(3),
|
||||
ciphertext_modulus: CiphertextModulus::new((1 << 64) - (1 << 32) + 1),
|
||||
};
|
||||
|
||||
pub const DUMMY_NATIVE_U32: ClassicTestParams<u32> = ClassicTestParams {
|
||||
lwe_dimension: LweDimension(742),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
@@ -118,7 +128,7 @@ pub const DUMMY_NATIVE_U32: TestParams<u32> = TestParams {
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
};
|
||||
|
||||
pub const DUMMY_31_U32: TestParams<u32> = TestParams {
|
||||
pub const DUMMY_31_U32: ClassicTestParams<u32> = ClassicTestParams {
|
||||
lwe_dimension: LweDimension(742),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
@@ -137,23 +147,173 @@ pub const DUMMY_31_U32: TestParams<u32> = TestParams {
|
||||
ciphertext_modulus: CiphertextModulus::new(1 << 31),
|
||||
};
|
||||
|
||||
pub const TEST_PARAMS_3_BITS_SOLINAS_U64: TestParams<u64> = TestParams {
|
||||
pub const MULTI_BIT_2_2_2_PARAMS: MultiBitTestParams<u64> = MultiBitTestParams {
|
||||
input_lwe_dimension: LweDimension(818),
|
||||
lwe_modular_std_dev: StandardDev(0.000002226459789930014),
|
||||
decomp_base_log: DecompositionBaseLog(22),
|
||||
decomp_level_count: DecompositionLevelCount(1),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
glwe_modular_std_dev: StandardDev(0.0000000000000003152931493498455),
|
||||
message_modulus_log: CiphertextModulusLog(4),
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
grouping_factor: LweBskGroupingFactor(2),
|
||||
thread_count: ThreadCount(5),
|
||||
};
|
||||
|
||||
pub const MULTI_BIT_2_2_2_CUSTOM_MOD_PARAMS: MultiBitTestParams<u64> = MultiBitTestParams {
|
||||
input_lwe_dimension: LweDimension(818),
|
||||
lwe_modular_std_dev: StandardDev(0.000002226459789930014),
|
||||
decomp_base_log: DecompositionBaseLog(22),
|
||||
decomp_level_count: DecompositionLevelCount(1),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
glwe_modular_std_dev: StandardDev(0.0000000000000003152931493498455),
|
||||
message_modulus_log: CiphertextModulusLog(3),
|
||||
ciphertext_modulus: CiphertextModulus::new(1 << 63),
|
||||
grouping_factor: LweBskGroupingFactor(2),
|
||||
thread_count: ThreadCount(5),
|
||||
};
|
||||
|
||||
pub const MULTI_BIT_2_2_3_PARAMS: MultiBitTestParams<u64> = MultiBitTestParams {
|
||||
input_lwe_dimension: LweDimension(888),
|
||||
lwe_modular_std_dev: StandardDev(0.0000006125031601933181),
|
||||
decomp_base_log: DecompositionBaseLog(21),
|
||||
decomp_level_count: DecompositionLevelCount(1),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
glwe_modular_std_dev: StandardDev(0.0000000000000003152931493498455),
|
||||
message_modulus_log: CiphertextModulusLog(4),
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
grouping_factor: LweBskGroupingFactor(3),
|
||||
thread_count: ThreadCount(12),
|
||||
};
|
||||
|
||||
pub const MULTI_BIT_2_2_3_CUSTOM_MOD_PARAMS: MultiBitTestParams<u64> = MultiBitTestParams {
|
||||
input_lwe_dimension: LweDimension(888),
|
||||
lwe_modular_std_dev: StandardDev(0.0000006125031601933181),
|
||||
decomp_base_log: DecompositionBaseLog(21),
|
||||
decomp_level_count: DecompositionLevelCount(1),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
glwe_modular_std_dev: StandardDev(0.0000000000000003152931493498455),
|
||||
message_modulus_log: CiphertextModulusLog(3),
|
||||
ciphertext_modulus: CiphertextModulus::new(1 << 63),
|
||||
grouping_factor: LweBskGroupingFactor(3),
|
||||
thread_count: ThreadCount(12),
|
||||
};
|
||||
|
||||
// DISCLAIMER: example parameters tailored for FFT implementation tests. There are not guaranteed
|
||||
// to be secure or yield correct computations.
|
||||
// Define the parameters for a 4 bits message able to hold the doubled 2 bits message.
|
||||
pub const FFT_U32_PARAMS: FftTestParams<u32> = FftTestParams {
|
||||
lwe_dimension: LweDimension(742),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
lwe_modular_std_dev: StandardDev(0.000007069849454709433),
|
||||
glwe_modular_std_dev: StandardDev(0.00000000000000029403601535432533),
|
||||
lwe_modular_std_dev: StandardDev(0.00000000004998277131225527),
|
||||
glwe_modular_std_dev: StandardDev(0.00000000000000000000000000000008645717832544903),
|
||||
pbs_base_log: DecompositionBaseLog(23),
|
||||
pbs_level: DecompositionLevelCount(1),
|
||||
ks_level: DecompositionLevelCount(5),
|
||||
ks_base_log: DecompositionBaseLog(3),
|
||||
pfks_level: DecompositionLevelCount(1),
|
||||
pfks_base_log: DecompositionBaseLog(23),
|
||||
pfks_modular_std_dev: StandardDev(0.00000000000000029403601535432533),
|
||||
cbs_level: DecompositionLevelCount(0),
|
||||
cbs_base_log: DecompositionBaseLog(0),
|
||||
message_modulus_log: CiphertextModulusLog(3),
|
||||
ciphertext_modulus: CiphertextModulus::new((1 << 64) - (1 << 32) + 1),
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
};
|
||||
|
||||
pub const FFT_U64_PARAMS: FftTestParams<u64> = FftTestParams {
|
||||
lwe_dimension: LweDimension(742),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
lwe_modular_std_dev: StandardDev(0.00000000004998277131225527),
|
||||
glwe_modular_std_dev: StandardDev(0.00000000000000000000000000000008645717832544903),
|
||||
pbs_base_log: DecompositionBaseLog(23),
|
||||
pbs_level: DecompositionLevelCount(1),
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
};
|
||||
|
||||
pub const FFT_U128_PARAMS: FftTestParams<u128> = FftTestParams {
|
||||
lwe_dimension: LweDimension(742),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
lwe_modular_std_dev: StandardDev(0.00000000004998277131225527),
|
||||
glwe_modular_std_dev: StandardDev(0.00000000000000000000000000000008645717832544903),
|
||||
pbs_base_log: DecompositionBaseLog(23),
|
||||
pbs_level: DecompositionLevelCount(1),
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
};
|
||||
|
||||
pub const FFT128_U128_PARAMS: FftTestParams<u128> = FftTestParams {
|
||||
lwe_dimension: LweDimension(742),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
lwe_modular_std_dev: StandardDev(0.12345),
|
||||
glwe_modular_std_dev: StandardDev(0.00000000000000000000000000000008645717832544903),
|
||||
pbs_base_log: DecompositionBaseLog(23),
|
||||
pbs_level: DecompositionLevelCount(1),
|
||||
ciphertext_modulus: CiphertextModulus::<u128>::new_native(),
|
||||
};
|
||||
|
||||
pub const FFT_WOPBS_PARAMS: FftWopPbsTestParams<u64> = FftWopPbsTestParams {
|
||||
lwe_dimension: LweDimension(481),
|
||||
glwe_dimension: GlweDimension(1),
|
||||
polynomial_size: PolynomialSize(1024),
|
||||
// Value was 0.000_000_000_000_000_221_486_881_160_055_68_513645324585951
|
||||
// But rust indicates it gets truncated anyways to
|
||||
// 0.000_000_000_000_000_221_486_881_160_055_68
|
||||
lwe_modular_std_dev: StandardDev(0.000_000_000_000_000_221_486_881_160_055_68),
|
||||
// Value was 0.000_061_200_133_780_220_371_345
|
||||
// But rust indicates it gets truncated anyways to
|
||||
// 0.000_061_200_133_780_220_36
|
||||
glwe_modular_std_dev: StandardDev(0.000_061_200_133_780_220_36),
|
||||
pbs_base_log: DecompositionBaseLog(4),
|
||||
pbs_level: DecompositionLevelCount(9),
|
||||
pfks_level: DecompositionLevelCount(9),
|
||||
pfks_base_log: DecompositionBaseLog(4),
|
||||
cbs_level: DecompositionLevelCount(4),
|
||||
cbs_base_log: DecompositionBaseLog(6),
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
};
|
||||
|
||||
pub const FFT_WOPBS_N512_PARAMS: FftWopPbsTestParams<u64> = FftWopPbsTestParams {
|
||||
lwe_dimension: LweDimension(4),
|
||||
glwe_dimension: GlweDimension(2),
|
||||
polynomial_size: PolynomialSize(512),
|
||||
lwe_modular_std_dev: StandardDev(0.000_000_000_000_000_221_486_881_160_055_68),
|
||||
glwe_modular_std_dev: StandardDev(0.000_061_200_133_780_220_36),
|
||||
pbs_base_log: DecompositionBaseLog(9),
|
||||
pbs_level: DecompositionLevelCount(4),
|
||||
pfks_level: DecompositionLevelCount(2),
|
||||
pfks_base_log: DecompositionBaseLog(15),
|
||||
cbs_level: DecompositionLevelCount(4),
|
||||
cbs_base_log: DecompositionBaseLog(6),
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
};
|
||||
|
||||
pub const FFT_WOPBS_N1024_PARAMS: FftWopPbsTestParams<u64> = FftWopPbsTestParams {
|
||||
lwe_dimension: LweDimension(4),
|
||||
glwe_dimension: GlweDimension(2),
|
||||
polynomial_size: PolynomialSize(1024),
|
||||
lwe_modular_std_dev: StandardDev(0.000_000_000_000_000_221_486_881_160_055_68),
|
||||
glwe_modular_std_dev: StandardDev(0.000_061_200_133_780_220_36),
|
||||
pbs_base_log: DecompositionBaseLog(9),
|
||||
pbs_level: DecompositionLevelCount(4),
|
||||
pfks_level: DecompositionLevelCount(2),
|
||||
pfks_base_log: DecompositionBaseLog(15),
|
||||
cbs_level: DecompositionLevelCount(4),
|
||||
cbs_base_log: DecompositionBaseLog(6),
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
};
|
||||
|
||||
pub const FFT_WOPBS_N2048_PARAMS: FftWopPbsTestParams<u64> = FftWopPbsTestParams {
|
||||
lwe_dimension: LweDimension(4),
|
||||
glwe_dimension: GlweDimension(2),
|
||||
polynomial_size: PolynomialSize(2048),
|
||||
lwe_modular_std_dev: StandardDev(0.000_000_000_000_000_221_486_881_160_055_68),
|
||||
glwe_modular_std_dev: StandardDev(0.000_061_200_133_780_220_36),
|
||||
pbs_base_log: DecompositionBaseLog(9),
|
||||
pbs_level: DecompositionLevelCount(4),
|
||||
pfks_level: DecompositionLevelCount(2),
|
||||
pfks_base_log: DecompositionBaseLog(15),
|
||||
cbs_level: DecompositionLevelCount(4),
|
||||
cbs_base_log: DecompositionBaseLog(6),
|
||||
ciphertext_modulus: CiphertextModulus::new_native(),
|
||||
};
|
||||
|
||||
pub fn get_encoding_with_padding<Scalar: UnsignedInteger>(
|
||||
@@ -223,6 +383,23 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn gen_keys_or_get_from_cache_if_enabled<
|
||||
P: Debug + KeyCacheAccess<Keys = K> + serde::Serialize + serde::de::DeserializeOwned,
|
||||
K: serde::de::DeserializeOwned + serde::Serialize + Clone,
|
||||
>(
|
||||
params: P,
|
||||
keygen_func: &mut dyn FnMut(P) -> K,
|
||||
) -> K {
|
||||
#[cfg(feature = "internal-keycache")]
|
||||
{
|
||||
crate::core_crypto::keycache::KEY_CACHE.get_key_with_closure(params, keygen_func)
|
||||
}
|
||||
#[cfg(not(feature = "internal-keycache"))]
|
||||
{
|
||||
keygen_func(params)
|
||||
}
|
||||
}
|
||||
|
||||
// Macro to generate tests for all parameter sets
|
||||
macro_rules! create_parametrized_test{
|
||||
($name:ident { $($param:ident),* }) => {
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::core_crypto::commons::test_tools::{
|
||||
const RELATIVE_TOLERANCE: f64 = 0.0625;
|
||||
|
||||
fn lwe_encrypt_decrypt_noise_distribution_custom_mod<Scalar: UnsignedTorus + CastInto<usize>>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = params.lwe_dimension;
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
@@ -109,7 +109,7 @@ fn test_variance_increase_cpk_formula() {
|
||||
fn lwe_compact_public_encrypt_noise_distribution_custom_mod<
|
||||
Scalar: UnsignedTorus + CastInto<usize>,
|
||||
>(
|
||||
params: TestParams<Scalar>,
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let lwe_dimension = LweDimension(params.polynomial_size.0);
|
||||
let glwe_modular_std_dev = params.glwe_modular_std_dev;
|
||||
@@ -194,7 +194,9 @@ create_parametrized_test!(lwe_compact_public_encrypt_noise_distribution_custom_m
|
||||
TEST_PARAMS_4_BITS_NATIVE_U64
|
||||
});
|
||||
|
||||
fn random_noise_roundtrip<Scalar: UnsignedTorus + CastInto<usize>>(params: TestParams<Scalar>) {
|
||||
fn random_noise_roundtrip<Scalar: UnsignedTorus + CastInto<usize>>(
|
||||
params: ClassicTestParams<Scalar>,
|
||||
) {
|
||||
let mut rsc = TestResources::new();
|
||||
let noise = params.glwe_modular_std_dev;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
|
||||
217
tfhe/src/core_crypto/algorithms/test/params.rs
Normal file
217
tfhe/src/core_crypto/algorithms/test/params.rs
Normal file
@@ -0,0 +1,217 @@
|
||||
use crate::core_crypto::commons::dispersion::*;
|
||||
use crate::core_crypto::commons::parameters::*;
|
||||
use crate::core_crypto::entities::*;
|
||||
use crate::core_crypto::prelude::{CastFrom, CastInto, UnsignedInteger};
|
||||
use crate::keycache::NamedParam;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ClassicBootstrapKeys<Scalar: UnsignedInteger> {
|
||||
pub small_lwe_sk: LweSecretKey<Vec<Scalar>>,
|
||||
pub big_lwe_sk: LweSecretKey<Vec<Scalar>>,
|
||||
pub bsk: LweBootstrapKeyOwned<Scalar>,
|
||||
|
||||
pub fbsk: FourierLweBootstrapKeyOwned,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct MultiBitBootstrapKeys<Scalar: UnsignedInteger> {
|
||||
pub small_lwe_sk: LweSecretKey<Vec<Scalar>>,
|
||||
pub big_lwe_sk: LweSecretKey<Vec<Scalar>>,
|
||||
pub bsk: LweMultiBitBootstrapKeyOwned<Scalar>,
|
||||
pub fbsk: FourierLweMultiBitBootstrapKeyOwned,
|
||||
}
|
||||
|
||||
// Fourier key is generated afterward in order to use generic test function
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct FftBootstrapKeys<Scalar: UnsignedInteger> {
|
||||
pub small_lwe_sk: LweSecretKey<Vec<Scalar>>,
|
||||
pub big_lwe_sk: LweSecretKey<Vec<Scalar>>,
|
||||
pub bsk: LweBootstrapKeyOwned<Scalar>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct FftWopPbsKeys<Scalar: UnsignedInteger> {
|
||||
pub small_lwe_sk: LweSecretKey<Vec<Scalar>>,
|
||||
pub big_lwe_sk: LweSecretKey<Vec<Scalar>>,
|
||||
pub fbsk: FourierLweBootstrapKeyOwned,
|
||||
pub lwe_pfpksk: LwePrivateFunctionalPackingKeyswitchKeyListOwned<Scalar>,
|
||||
}
|
||||
|
||||
// Fourier key is generated afterward in order to use generic test function
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct PackingKeySwitchKeys<Scalar: UnsignedInteger> {
|
||||
pub lwe_sk: LweSecretKey<Vec<Scalar>>,
|
||||
pub glwe_sk: GlweSecretKey<Vec<Scalar>>,
|
||||
pub pksk: LwePackingKeyswitchKeyOwned<Scalar>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ClassicTestParams<Scalar: UnsignedInteger> {
|
||||
pub lwe_dimension: LweDimension,
|
||||
pub glwe_dimension: GlweDimension,
|
||||
pub polynomial_size: PolynomialSize,
|
||||
pub lwe_modular_std_dev: StandardDev,
|
||||
pub glwe_modular_std_dev: StandardDev,
|
||||
pub pbs_base_log: DecompositionBaseLog,
|
||||
pub pbs_level: DecompositionLevelCount,
|
||||
pub ks_base_log: DecompositionBaseLog,
|
||||
pub ks_level: DecompositionLevelCount,
|
||||
pub pfks_level: DecompositionLevelCount,
|
||||
pub pfks_base_log: DecompositionBaseLog,
|
||||
pub pfks_modular_std_dev: StandardDev,
|
||||
pub cbs_level: DecompositionLevelCount,
|
||||
pub cbs_base_log: DecompositionBaseLog,
|
||||
pub message_modulus_log: CiphertextModulusLog,
|
||||
pub ciphertext_modulus: CiphertextModulus<Scalar>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub struct MultiBitTestParams<Scalar: UnsignedInteger> {
|
||||
pub input_lwe_dimension: LweDimension,
|
||||
pub lwe_modular_std_dev: StandardDev,
|
||||
pub decomp_base_log: DecompositionBaseLog,
|
||||
pub decomp_level_count: DecompositionLevelCount,
|
||||
pub glwe_dimension: GlweDimension,
|
||||
pub polynomial_size: PolynomialSize,
|
||||
pub glwe_modular_std_dev: StandardDev,
|
||||
pub message_modulus_log: CiphertextModulusLog,
|
||||
pub ciphertext_modulus: CiphertextModulus<Scalar>,
|
||||
pub grouping_factor: LweBskGroupingFactor,
|
||||
pub thread_count: ThreadCount,
|
||||
}
|
||||
|
||||
// PartialEq is implemented manually because thread_count doesn't affect key generation and we want
|
||||
// to change its value in test without the need of regenerating keys in the key cache.
|
||||
impl<Scalar: UnsignedInteger> PartialEq for MultiBitTestParams<Scalar> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.input_lwe_dimension == other.input_lwe_dimension
|
||||
&& self.lwe_modular_std_dev == other.lwe_modular_std_dev
|
||||
&& self.decomp_base_log == other.decomp_base_log
|
||||
&& self.decomp_level_count == other.decomp_level_count
|
||||
&& self.glwe_dimension == other.glwe_dimension
|
||||
&& self.polynomial_size == other.polynomial_size
|
||||
&& self.glwe_modular_std_dev == other.glwe_modular_std_dev
|
||||
&& self.message_modulus_log == other.message_modulus_log
|
||||
&& self.ciphertext_modulus == other.ciphertext_modulus
|
||||
&& self.grouping_factor == other.grouping_factor
|
||||
}
|
||||
}
|
||||
|
||||
// Parameters to test FFT implementation
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct FftTestParams<Scalar: UnsignedInteger> {
|
||||
pub lwe_dimension: LweDimension,
|
||||
pub glwe_dimension: GlweDimension,
|
||||
pub polynomial_size: PolynomialSize,
|
||||
pub lwe_modular_std_dev: StandardDev,
|
||||
pub glwe_modular_std_dev: StandardDev,
|
||||
pub pbs_base_log: DecompositionBaseLog,
|
||||
pub pbs_level: DecompositionLevelCount,
|
||||
pub ciphertext_modulus: CiphertextModulus<Scalar>,
|
||||
}
|
||||
|
||||
// Parameters to test FFT implementation on wopPBS
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct FftWopPbsTestParams<Scalar: UnsignedInteger> {
|
||||
pub lwe_dimension: LweDimension,
|
||||
pub glwe_dimension: GlweDimension,
|
||||
pub polynomial_size: PolynomialSize,
|
||||
pub lwe_modular_std_dev: StandardDev,
|
||||
pub glwe_modular_std_dev: StandardDev,
|
||||
pub pbs_base_log: DecompositionBaseLog,
|
||||
pub pbs_level: DecompositionLevelCount,
|
||||
pub pfks_level: DecompositionLevelCount,
|
||||
pub pfks_base_log: DecompositionBaseLog,
|
||||
pub cbs_level: DecompositionLevelCount,
|
||||
pub cbs_base_log: DecompositionBaseLog,
|
||||
pub ciphertext_modulus: CiphertextModulus<Scalar>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct PackingKeySwitchTestParams<Scalar: UnsignedInteger> {
|
||||
pub lwe_dimension: LweDimension,
|
||||
pub glwe_dimension: GlweDimension,
|
||||
pub polynomial_size: PolynomialSize,
|
||||
pub lwe_modular_std_dev: StandardDev,
|
||||
pub glwe_modular_std_dev: StandardDev,
|
||||
pub pbs_base_log: DecompositionBaseLog,
|
||||
pub pbs_level: DecompositionLevelCount,
|
||||
pub message_modulus_log: CiphertextModulusLog,
|
||||
pub ciphertext_modulus: CiphertextModulus<Scalar>,
|
||||
}
|
||||
|
||||
impl<Scalar: UnsignedInteger + CastFrom<usize> + CastInto<usize>> From<ClassicTestParams<Scalar>>
|
||||
for PackingKeySwitchTestParams<Scalar>
|
||||
{
|
||||
fn from(params: ClassicTestParams<Scalar>) -> Self {
|
||||
Self {
|
||||
lwe_dimension: params.lwe_dimension,
|
||||
glwe_dimension: params.glwe_dimension,
|
||||
polynomial_size: params.polynomial_size,
|
||||
lwe_modular_std_dev: params.lwe_modular_std_dev,
|
||||
glwe_modular_std_dev: params.glwe_modular_std_dev,
|
||||
pbs_base_log: params.pbs_base_log,
|
||||
pbs_level: params.pbs_level,
|
||||
message_modulus_log: params.message_modulus_log,
|
||||
ciphertext_modulus: params.ciphertext_modulus,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Scalar: UnsignedInteger> NamedParam for ClassicTestParams<Scalar> {
|
||||
fn name(&self) -> String {
|
||||
format!(
|
||||
"PARAM_LWE_BOOTSTRAP_glwe_{}_poly_{}_decomp_base_log_{}_decomp_level_{}_lwe_dim_{}_ct_modulus_{}_msg_modulus_{}",
|
||||
self.glwe_dimension.0, self.polynomial_size.0, self.pbs_base_log.0, self.pbs_level.0,
|
||||
self.lwe_dimension.0, self.ciphertext_modulus, self.message_modulus_log.0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Scalar: UnsignedInteger> NamedParam for MultiBitTestParams<Scalar> {
|
||||
fn name(&self) -> String {
|
||||
format!(
|
||||
"PARAM_LWE_MULTI_BIT_BOOTSTRAP_glwe_{}_poly_{}_decomp_base_log_{}_decomp_level_{}_input_dim_{}_ct_modulus_{}_msg_modulus_log_{}_group_factor_{}",
|
||||
self.glwe_dimension.0, self.polynomial_size.0, self.decomp_base_log.0,
|
||||
self.decomp_level_count.0, self.input_lwe_dimension.0, self.ciphertext_modulus, self.message_modulus_log.0,
|
||||
self.grouping_factor.0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Scalar: UnsignedInteger> NamedParam for FftTestParams<Scalar> {
|
||||
fn name(&self) -> String {
|
||||
format!(
|
||||
"PARAM_FFT_BOOTSTRAP_glwe_{}_poly_{}_decomp_base_log_{}_decomp_level_{}_lwe_dim_{}_ct_modulus_{}_lwe_std_dev_{}_glwe_std_dev_{}",
|
||||
self.glwe_dimension.0, self.polynomial_size.0, self.pbs_base_log.0,
|
||||
self.pbs_level.0,
|
||||
self.lwe_dimension.0, self.ciphertext_modulus, self.lwe_modular_std_dev.0.to_string().replace('.', "-"),
|
||||
self.glwe_modular_std_dev.0.to_string().replace('.', "-"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Scalar: UnsignedInteger> NamedParam for FftWopPbsTestParams<Scalar> {
|
||||
fn name(&self) -> String {
|
||||
format!(
|
||||
"PARAM_FFT_WOPBS_BOOTSTRAP_glwe_{}_poly_{}_decomp_base_log_{}_decomp_level_{}_lwe_dim_{}_ct_modulus_{}_pfks_level_{}_pfks_base_log_{}_cbs_level_{}_cbs_base_log_{}",
|
||||
self.glwe_dimension.0, self.polynomial_size.0, self.pbs_base_log.0,
|
||||
self.pbs_level.0,
|
||||
self.lwe_dimension.0, self.ciphertext_modulus, self.pfks_level.0, self.pfks_base_log.0,
|
||||
self.cbs_level.0, self.cbs_base_log.0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Scalar: UnsignedInteger> NamedParam for PackingKeySwitchTestParams<Scalar> {
|
||||
fn name(&self) -> String {
|
||||
format!(
|
||||
"PARAM_PKS_glwe_{}_poly_{}_decomp_base_log_{}_decomp_level_{}_lwe_dim_{}_ct_modulus_{}_lwe_std_dev_{}_glwe_std_dev_{}",
|
||||
self.glwe_dimension.0, self.polynomial_size.0, self.pbs_base_log.0,
|
||||
self.pbs_level.0,
|
||||
self.lwe_dimension.0, self.ciphertext_modulus, self.lwe_modular_std_dev.0.to_string().replace('.', "-"),
|
||||
self.glwe_modular_std_dev.0.to_string().replace('.', "-"),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -86,70 +86,89 @@ pub trait FourierBootstrapKey<Scalar: UnsignedInteger> {
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
pub(crate) use crate::core_crypto::algorithms::test::gen_keys_or_get_from_cache_if_enabled;
|
||||
|
||||
use crate::core_crypto::algorithms::test::{FftBootstrapKeys, FftTestParams, TestResources};
|
||||
use crate::core_crypto::commons::numeric::Numeric;
|
||||
use crate::core_crypto::fft_impl::common::FourierBootstrapKey;
|
||||
use crate::core_crypto::keycache::KeyCacheAccess;
|
||||
use crate::core_crypto::prelude::*;
|
||||
use dyn_stack::{GlobalPodBuffer, PodStack};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
|
||||
pub fn test_bootstrap_generic<
|
||||
Scalar: Numeric + UnsignedTorus + CastFrom<usize> + CastInto<usize> + Send + Sync,
|
||||
K: FourierBootstrapKey<Scalar>,
|
||||
pub fn generate_keys<
|
||||
Scalar: UnsignedTorus
|
||||
+ Sync
|
||||
+ Send
|
||||
+ CastFrom<usize>
|
||||
+ CastInto<usize>
|
||||
+ Serialize
|
||||
+ DeserializeOwned,
|
||||
>(
|
||||
lwe_modular_std_dev: StandardDev,
|
||||
glwe_modular_std_dev: StandardDev,
|
||||
) {
|
||||
// DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct
|
||||
// computations
|
||||
// Define the parameters for a 4 bits message able to hold the doubled 2 bits message
|
||||
let small_lwe_dimension = LweDimension(742);
|
||||
let glwe_dimension = GlweDimension(1);
|
||||
let polynomial_size = PolynomialSize(2048);
|
||||
let pbs_base_log = DecompositionBaseLog(23);
|
||||
let pbs_level = DecompositionLevelCount(1);
|
||||
let ciphertext_modulus = CiphertextModulus::new_native();
|
||||
|
||||
// Request the best seeder possible, starting with hardware entropy sources and falling back
|
||||
// to /dev/random on Unix systems if enabled via cargo features
|
||||
let mut boxed_seeder = new_seeder();
|
||||
// Get a mutable reference to the seeder as a trait object from the Box returned by
|
||||
// new_seeder
|
||||
let seeder = boxed_seeder.as_mut();
|
||||
|
||||
// Create a generator which uses a CSPRNG to generate secret keys
|
||||
let mut secret_generator =
|
||||
SecretRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed());
|
||||
|
||||
// Create a generator which uses two CSPRNGs to generate public masks and secret encryption
|
||||
// noise
|
||||
let mut encryption_generator =
|
||||
EncryptionRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed(), seeder);
|
||||
|
||||
println!("Generating keys...");
|
||||
|
||||
params: FftTestParams<Scalar>,
|
||||
rsc: &mut TestResources,
|
||||
) -> FftBootstrapKeys<Scalar> {
|
||||
// Generate an LweSecretKey with binary coefficients
|
||||
let small_lwe_sk =
|
||||
LweSecretKey::generate_new_binary(small_lwe_dimension, &mut secret_generator);
|
||||
let small_lwe_sk = LweSecretKey::generate_new_binary(
|
||||
params.lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
|
||||
// Generate a GlweSecretKey with binary coefficients
|
||||
let glwe_sk = GlweSecretKey::generate_new_binary(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut secret_generator,
|
||||
params.glwe_dimension,
|
||||
params.polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
|
||||
// Create a copy of the GlweSecretKey re-interpreted as an LweSecretKey
|
||||
let big_lwe_sk = glwe_sk.clone().into_lwe_secret_key();
|
||||
|
||||
let std_bootstrapping_key = par_allocate_and_generate_new_lwe_bootstrap_key(
|
||||
let bsk = par_allocate_and_generate_new_lwe_bootstrap_key(
|
||||
&small_lwe_sk,
|
||||
&glwe_sk,
|
||||
pbs_base_log,
|
||||
pbs_level,
|
||||
glwe_modular_std_dev,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
params.pbs_base_log,
|
||||
params.pbs_level,
|
||||
params.glwe_modular_std_dev,
|
||||
params.ciphertext_modulus,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
FftBootstrapKeys {
|
||||
small_lwe_sk,
|
||||
big_lwe_sk,
|
||||
bsk,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_bootstrap_generic<Scalar, K>(params: FftTestParams<Scalar>)
|
||||
where
|
||||
Scalar: Numeric
|
||||
+ UnsignedTorus
|
||||
+ CastFrom<usize>
|
||||
+ CastInto<usize>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ Serialize
|
||||
+ DeserializeOwned,
|
||||
K: FourierBootstrapKey<Scalar>,
|
||||
FftTestParams<Scalar>: KeyCacheAccess<Keys = FftBootstrapKeys<Scalar>>,
|
||||
{
|
||||
let lwe_modular_std_dev = params.lwe_modular_std_dev;
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
let fft = K::new_fft(polynomial_size);
|
||||
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let (std_bootstrapping_key, small_lwe_sk, big_lwe_sk) =
|
||||
(keys.bsk, keys.small_lwe_sk, keys.big_lwe_sk);
|
||||
|
||||
// Create the empty bootstrapping key in the Fourier domain
|
||||
let mut fourier_bsk = K::new(
|
||||
std_bootstrapping_key.input_lwe_dimension(),
|
||||
@@ -159,7 +178,6 @@ pub mod tests {
|
||||
std_bootstrapping_key.decomposition_level_count(),
|
||||
);
|
||||
|
||||
let fft = K::new_fft(polynomial_size);
|
||||
fourier_bsk.fill_with_forward_fourier(
|
||||
&std_bootstrapping_key,
|
||||
&fft,
|
||||
@@ -186,7 +204,7 @@ pub mod tests {
|
||||
plaintext,
|
||||
lwe_modular_std_dev,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
// Now we will use a PBS to compute a multiplication by 2, it is NOT the recommended way of
|
||||
|
||||
@@ -1,31 +1,18 @@
|
||||
use crate::core_crypto::fft_impl::common::tests::test_bootstrap_generic;
|
||||
use crate::core_crypto::fft_impl::fft128::crypto::bootstrap::Fourier128LweBootstrapKeyOwned;
|
||||
use crate::core_crypto::prelude::*;
|
||||
|
||||
fn sqr(x: f64) -> f64 {
|
||||
x * x
|
||||
}
|
||||
use crate::core_crypto::prelude::test::{FFT_U128_PARAMS, FFT_U32_PARAMS, FFT_U64_PARAMS};
|
||||
|
||||
#[test]
|
||||
fn test_bootstrap_u128() {
|
||||
test_bootstrap_generic::<u128, Fourier128LweBootstrapKeyOwned>(
|
||||
StandardDev(sqr(0.000007069849454709433)),
|
||||
StandardDev(sqr(0.00000000000000029403601535432533)),
|
||||
);
|
||||
test_bootstrap_generic::<u128, Fourier128LweBootstrapKeyOwned>(FFT_U128_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bootstrap_u64() {
|
||||
test_bootstrap_generic::<u64, Fourier128LweBootstrapKeyOwned>(
|
||||
StandardDev(sqr(0.000007069849454709433)),
|
||||
StandardDev(sqr(0.00000000000000029403601535432533)),
|
||||
);
|
||||
test_bootstrap_generic::<u64, Fourier128LweBootstrapKeyOwned>(FFT_U64_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bootstrap_u32() {
|
||||
test_bootstrap_generic::<u32, Fourier128LweBootstrapKeyOwned>(
|
||||
StandardDev(sqr(0.000007069849454709433)),
|
||||
StandardDev(sqr(0.00000000000000029403601535432533)),
|
||||
);
|
||||
test_bootstrap_generic::<u32, Fourier128LweBootstrapKeyOwned>(FFT_U32_PARAMS);
|
||||
}
|
||||
|
||||
@@ -2,24 +2,24 @@ use dyn_stack::{GlobalPodBuffer, PodStack, ReborrowMut};
|
||||
|
||||
use super::super::super::{fft128, fft128_u128};
|
||||
use super::super::math::fft::{Fft128, Fft128View};
|
||||
use crate::core_crypto::fft_impl::common::tests::{
|
||||
gen_keys_or_get_from_cache_if_enabled, generate_keys,
|
||||
};
|
||||
use crate::core_crypto::prelude::test::{TestResources, FFT128_U128_PARAMS};
|
||||
use crate::core_crypto::prelude::*;
|
||||
use aligned_vec::CACHELINE_ALIGN;
|
||||
|
||||
fn sqr(x: f64) -> f64 {
|
||||
x * x
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_external_product() {
|
||||
let small_lwe_dimension = LweDimension(742);
|
||||
let glwe_dimension = GlweDimension(1);
|
||||
let polynomial_size = PolynomialSize(2048);
|
||||
let pbs_base_log = DecompositionBaseLog(23);
|
||||
let pbs_level = DecompositionLevelCount(1);
|
||||
let glwe_modular_std_dev = StandardDev(sqr(0.00000000000000029403601535432533));
|
||||
let ciphertext_modulus = CiphertextModulus::<u128>::new_native();
|
||||
let params = FFT128_U128_PARAMS;
|
||||
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
let ciphertext_modulus_split = CiphertextModulus::<u64>::new_native();
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
let mut glwe = GlweCiphertext::new(
|
||||
0u128,
|
||||
glwe_dimension.to_glwe_size(),
|
||||
@@ -31,27 +31,9 @@ fn test_split_external_product() {
|
||||
*x = rand::random();
|
||||
}
|
||||
|
||||
let mut boxed_seeder = new_seeder();
|
||||
let seeder = boxed_seeder.as_mut();
|
||||
let mut secret_generator =
|
||||
SecretRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed());
|
||||
let mut encryption_generator =
|
||||
EncryptionRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed(), seeder);
|
||||
|
||||
let small_lwe_sk =
|
||||
LweSecretKey::generate_new_binary(small_lwe_dimension, &mut secret_generator);
|
||||
let glwe_sk =
|
||||
GlweSecretKey::generate_new_binary(glwe_dimension, polynomial_size, &mut secret_generator);
|
||||
|
||||
let std_bootstrapping_key = par_allocate_and_generate_new_lwe_bootstrap_key(
|
||||
&small_lwe_sk,
|
||||
&glwe_sk,
|
||||
pbs_base_log,
|
||||
pbs_level,
|
||||
glwe_modular_std_dev,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
);
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let std_bootstrapping_key = keys.bsk;
|
||||
|
||||
let mut fourier_bsk = Fourier128LweBootstrapKey::new(
|
||||
std_bootstrapping_key.input_lwe_dimension(),
|
||||
@@ -154,35 +136,18 @@ fn test_split_external_product() {
|
||||
|
||||
#[test]
|
||||
fn test_split_pbs() {
|
||||
let small_lwe_dimension = LweDimension(742);
|
||||
let glwe_dimension = GlweDimension(1);
|
||||
let polynomial_size = PolynomialSize(2048);
|
||||
let pbs_base_log = DecompositionBaseLog(23);
|
||||
let pbs_level = DecompositionLevelCount(1);
|
||||
let glwe_modular_std_dev = StandardDev(sqr(0.00000000000000029403601535432533));
|
||||
let ciphertext_modulus = CiphertextModulus::<u128>::new_native();
|
||||
let params = FFT128_U128_PARAMS;
|
||||
|
||||
let mut boxed_seeder = new_seeder();
|
||||
let seeder = boxed_seeder.as_mut();
|
||||
let mut secret_generator =
|
||||
SecretRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed());
|
||||
let mut encryption_generator =
|
||||
EncryptionRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed(), seeder);
|
||||
let small_lwe_dimension = params.lwe_dimension;
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
|
||||
let small_lwe_sk =
|
||||
LweSecretKey::generate_new_binary(small_lwe_dimension, &mut secret_generator);
|
||||
let glwe_sk =
|
||||
GlweSecretKey::generate_new_binary(glwe_dimension, polynomial_size, &mut secret_generator);
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
let std_bootstrapping_key = par_allocate_and_generate_new_lwe_bootstrap_key(
|
||||
&small_lwe_sk,
|
||||
&glwe_sk,
|
||||
pbs_base_log,
|
||||
pbs_level,
|
||||
glwe_modular_std_dev,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
);
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let std_bootstrapping_key = keys.bsk;
|
||||
|
||||
let mut fourier_bsk = Fourier128LweBootstrapKey::new(
|
||||
std_bootstrapping_key.input_lwe_dimension(),
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
use crate::core_crypto::fft_impl::common::tests::test_bootstrap_generic;
|
||||
use crate::core_crypto::fft_impl::fft64::crypto::bootstrap::FourierLweBootstrapKeyOwned;
|
||||
use crate::core_crypto::prelude::*;
|
||||
use crate::core_crypto::prelude::test::{FFT_U32_PARAMS, FFT_U64_PARAMS};
|
||||
|
||||
#[test]
|
||||
fn test_bootstrap_u64() {
|
||||
test_bootstrap_generic::<u64, FourierLweBootstrapKeyOwned>(
|
||||
StandardDev(0.000007069849454709433),
|
||||
StandardDev(0.00000000000000029403601535432533),
|
||||
);
|
||||
test_bootstrap_generic::<u64, FourierLweBootstrapKeyOwned>(FFT_U64_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bootstrap_u32() {
|
||||
test_bootstrap_generic::<u32, FourierLweBootstrapKeyOwned>(
|
||||
StandardDev(0.000007069849454709433),
|
||||
StandardDev(0.00000000000000029403601535432533),
|
||||
);
|
||||
test_bootstrap_generic::<u32, FourierLweBootstrapKeyOwned>(FFT_U32_PARAMS);
|
||||
}
|
||||
|
||||
@@ -892,4 +892,4 @@ pub fn blind_rotate_assign<Scalar: UnsignedTorus + CastInto<usize>>(
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
pub mod tests;
|
||||
|
||||
@@ -1,21 +1,100 @@
|
||||
use super::*;
|
||||
use crate::core_crypto::algorithms::slice_algorithms::*;
|
||||
use crate::core_crypto::commons::dispersion::{LogStandardDev, StandardDev};
|
||||
use crate::core_crypto::commons::generators::{EncryptionRandomGenerator, SecretRandomGenerator};
|
||||
use crate::core_crypto::algorithms::test::{FftWopPbsKeys, FftWopPbsTestParams};
|
||||
use crate::core_crypto::commons::dispersion::LogStandardDev;
|
||||
use crate::core_crypto::commons::math::decomposition::SignedDecomposer;
|
||||
use crate::core_crypto::commons::parameters::{
|
||||
DecompositionBaseLog, DecompositionLevelCount, DeltaLog, ExtractedBitsCount, GlweDimension,
|
||||
LweDimension, PlaintextCount, PolynomialCount, PolynomialSize,
|
||||
};
|
||||
use crate::core_crypto::commons::test_tools;
|
||||
use crate::core_crypto::fft_impl::common::tests::gen_keys_or_get_from_cache_if_enabled;
|
||||
use crate::core_crypto::fft_impl::fft64::crypto::bootstrap::{
|
||||
fill_with_forward_fourier_scratch, FourierLweBootstrapKey,
|
||||
};
|
||||
use crate::core_crypto::fft_impl::fft64::math::fft::Fft;
|
||||
use crate::core_crypto::seeders::new_seeder;
|
||||
use concrete_csprng::generators::SoftwareRandomGenerator;
|
||||
use crate::core_crypto::prelude::test::{
|
||||
TestResources, FFT_WOPBS_N1024_PARAMS, FFT_WOPBS_N2048_PARAMS, FFT_WOPBS_N512_PARAMS,
|
||||
FFT_WOPBS_PARAMS,
|
||||
};
|
||||
use concrete_fft::c64;
|
||||
use dyn_stack::{GlobalPodBuffer, PodStack, ReborrowMut, StackReq};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
// Tests take about 2-3 seconds on a laptop with this number
|
||||
const NB_TESTS: usize = 32;
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const NB_TESTS_LIGHT: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS: usize = 1;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const NB_TESTS_LIGHT: usize = 1;
|
||||
|
||||
pub fn generate_keys<
|
||||
Scalar: UnsignedTorus + Sync + Send + CastFrom<usize> + CastInto<usize> + Serialize + DeserializeOwned,
|
||||
>(
|
||||
params: FftWopPbsTestParams<Scalar>,
|
||||
rsc: &mut TestResources,
|
||||
) -> FftWopPbsKeys<Scalar> {
|
||||
//create GLWE and LWE secret key
|
||||
let glwe_sk = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
params.glwe_dimension,
|
||||
params.polynomial_size,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let small_lwe_sk = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
params.lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
|
||||
let big_lwe_sk = glwe_sk.clone().into_lwe_secret_key();
|
||||
|
||||
// allocation and generation of the key in coef domain:
|
||||
let std_bsk = allocate_and_generate_new_lwe_bootstrap_key(
|
||||
&small_lwe_sk,
|
||||
&glwe_sk,
|
||||
params.pbs_base_log,
|
||||
params.pbs_level,
|
||||
params.lwe_modular_std_dev,
|
||||
params.ciphertext_modulus,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
// allocation for the bootstrapping key
|
||||
let mut fourier_bsk = FourierLweBootstrapKey::new(
|
||||
params.lwe_dimension,
|
||||
params.glwe_dimension.to_glwe_size(),
|
||||
params.polynomial_size,
|
||||
params.pbs_base_log,
|
||||
params.pbs_level,
|
||||
);
|
||||
|
||||
let fft = Fft::new(params.polynomial_size);
|
||||
let fft = fft.as_view();
|
||||
|
||||
fourier_bsk
|
||||
.as_mut_view()
|
||||
.par_fill_with_forward_fourier(std_bsk.as_view(), fft);
|
||||
|
||||
// Creation of all the pfksk for the circuit bootstrapping
|
||||
let vec_pfpksk = par_allocate_and_generate_new_circuit_bootstrap_lwe_pfpksk_list(
|
||||
&big_lwe_sk,
|
||||
&glwe_sk,
|
||||
params.pfks_base_log,
|
||||
params.pfks_level,
|
||||
params.lwe_modular_std_dev,
|
||||
params.ciphertext_modulus,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
FftWopPbsKeys {
|
||||
small_lwe_sk,
|
||||
big_lwe_sk,
|
||||
fbsk: fourier_bsk,
|
||||
lwe_pfpksk: vec_pfpksk,
|
||||
}
|
||||
}
|
||||
|
||||
// Extract all the bits of a LWE
|
||||
#[test]
|
||||
@@ -36,24 +115,19 @@ pub fn test_extract_bits() {
|
||||
let ciphertext_modulus = CiphertextModulus::new_native();
|
||||
|
||||
let number_of_bits_of_message_including_padding = 5_usize;
|
||||
// Tests take about 2-3 seconds on a laptop with this number
|
||||
let number_of_test_runs = 32;
|
||||
|
||||
let mut seeder = new_seeder();
|
||||
let seeder = seeder.as_mut();
|
||||
|
||||
let mut secret_generator = SecretRandomGenerator::<SoftwareRandomGenerator>::new(seeder.seed());
|
||||
let mut encryption_generator =
|
||||
EncryptionRandomGenerator::<SoftwareRandomGenerator>::new(seeder.seed(), seeder);
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
// allocation and generation of the key in coef domain:
|
||||
let glwe_sk: GlweSecretKeyOwned<u64> = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut secret_generator,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let lwe_small_sk: LweSecretKeyOwned<u64> = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
small_lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let lwe_small_sk: LweSecretKeyOwned<u64> =
|
||||
allocate_and_generate_new_binary_lwe_secret_key(small_lwe_dimension, &mut secret_generator);
|
||||
|
||||
let std_bsk: LweBootstrapKeyOwned<u64> = allocate_and_generate_new_lwe_bootstrap_key(
|
||||
&lwe_small_sk,
|
||||
@@ -62,7 +136,7 @@ pub fn test_extract_bits() {
|
||||
level_bsk,
|
||||
std,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
let mut fourier_bsk = FourierLweBootstrapKey::new(
|
||||
@@ -85,7 +159,7 @@ pub fn test_extract_bits() {
|
||||
level_ksk,
|
||||
std,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
let input_lwe_dimension = lwe_big_sk.lwe_dimension();
|
||||
@@ -116,7 +190,7 @@ pub fn test_extract_bits() {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
for _ in 0..number_of_test_runs {
|
||||
for _ in 0..NB_TESTS {
|
||||
// Generate a random plaintext in [0; 2^{number_of_bits_of_message_including_padding}[
|
||||
let val = test_tools::random_uint_between(
|
||||
0..2u64.pow(number_of_bits_of_message_including_padding as u32),
|
||||
@@ -135,7 +209,7 @@ pub fn test_extract_bits() {
|
||||
&mut lwe_in,
|
||||
message,
|
||||
std,
|
||||
&mut encryption_generator,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
// Bit extraction
|
||||
@@ -202,21 +276,18 @@ fn test_circuit_bootstrapping_binary() {
|
||||
|
||||
let ciphertext_modulus = CiphertextModulus::new_native();
|
||||
|
||||
let mut seeder = new_seeder();
|
||||
let seeder = seeder.as_mut();
|
||||
|
||||
let mut secret_generator = SecretRandomGenerator::<SoftwareRandomGenerator>::new(seeder.seed());
|
||||
let mut encryption_generator =
|
||||
EncryptionRandomGenerator::<SoftwareRandomGenerator>::new(seeder.seed(), seeder);
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
// Create GLWE and LWE secret key
|
||||
let glwe_sk: GlweSecretKeyOwned<u64> = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut secret_generator,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let lwe_sk: LweSecretKeyOwned<u64> = allocate_and_generate_new_binary_lwe_secret_key(
|
||||
small_lwe_dimension,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let lwe_sk: LweSecretKeyOwned<u64> =
|
||||
allocate_and_generate_new_binary_lwe_secret_key(small_lwe_dimension, &mut secret_generator);
|
||||
|
||||
// Allocation and generation of the bootstrap key in standard domain:
|
||||
let std_bsk: LweBootstrapKeyOwned<u64> = allocate_and_generate_new_lwe_bootstrap_key(
|
||||
@@ -226,7 +297,7 @@ fn test_circuit_bootstrapping_binary() {
|
||||
level_bsk,
|
||||
std,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
let mut fourier_bsk = FourierLweBootstrapKey::new(
|
||||
@@ -254,14 +325,12 @@ fn test_circuit_bootstrapping_binary() {
|
||||
level_pksk,
|
||||
std,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
let delta_log = DeltaLog(60);
|
||||
|
||||
let number_of_test_runs = 32;
|
||||
|
||||
for _ in 0..number_of_test_runs {
|
||||
for _ in 0..NB_TESTS {
|
||||
// value is 0 or 1 as CBS works on messages expected to contain 1 bit of information
|
||||
let value: u64 = test_tools::random_uint_between(0..2u64);
|
||||
// Encryption of an LWE with the value 'message'
|
||||
@@ -273,7 +342,7 @@ fn test_circuit_bootstrapping_binary() {
|
||||
&mut lwe_in,
|
||||
message,
|
||||
std,
|
||||
&mut encryption_generator,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
let mut cbs_res = GgswCiphertextOwned::new(
|
||||
@@ -386,12 +455,6 @@ fn test_circuit_bootstrapping_binary() {
|
||||
#[test]
|
||||
pub fn test_cmux_tree() {
|
||||
// Define settings for an insecure toy example
|
||||
let mut seeder = new_seeder();
|
||||
let seeder = seeder.as_mut();
|
||||
|
||||
let mut secret_generator = SecretRandomGenerator::<SoftwareRandomGenerator>::new(seeder.seed());
|
||||
let mut encryption_generator =
|
||||
EncryptionRandomGenerator::<SoftwareRandomGenerator>::new(seeder.seed(), seeder);
|
||||
let polynomial_size = PolynomialSize(512);
|
||||
let glwe_dimension = GlweDimension(1);
|
||||
let std = LogStandardDev::from_log_standard_dev(-60.);
|
||||
@@ -403,11 +466,13 @@ pub fn test_cmux_tree() {
|
||||
let nb_ggsw = 10;
|
||||
let delta_log = 60;
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
// Allocation and generation of the key in coef domain:
|
||||
let glwe_sk: GlweSecretKeyOwned<u64> = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut secret_generator,
|
||||
&mut rsc.secret_random_generator,
|
||||
);
|
||||
let glwe_size = glwe_sk.glwe_dimension().to_glwe_size();
|
||||
|
||||
@@ -428,9 +493,7 @@ pub fn test_cmux_tree() {
|
||||
// Decomposer to manage the rounding after decrypting
|
||||
let decomposer = SignedDecomposer::new(DecompositionBaseLog(4), DecompositionLevelCount(1));
|
||||
|
||||
let number_of_test_runs = 32;
|
||||
|
||||
for _ in 0..number_of_test_runs {
|
||||
for _ in 0..NB_TESTS {
|
||||
let mut value =
|
||||
test_tools::random_uint_between(0..2u64.pow(number_of_bits_for_payload as u32));
|
||||
println!("value: {value}");
|
||||
@@ -478,7 +541,7 @@ pub fn test_cmux_tree() {
|
||||
&mut ggsw,
|
||||
single_bit_msg,
|
||||
std,
|
||||
&mut encryption_generator,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
let mut mem = GlobalPodBuffer::new(fill_with_forward_fourier_scratch(fft).unwrap());
|
||||
@@ -517,83 +580,35 @@ pub fn test_cmux_tree() {
|
||||
}
|
||||
}
|
||||
|
||||
// Circuit bootstrap + vecrtical packing applying an identity lut
|
||||
// Circuit bootstrap + vertical packing applying an identity lut
|
||||
#[test]
|
||||
pub fn test_extract_bit_circuit_bootstrapping_vertical_packing() {
|
||||
// define settings
|
||||
let polynomial_size = PolynomialSize(1024);
|
||||
let glwe_dimension = GlweDimension(1);
|
||||
let small_lwe_dimension = LweDimension(481);
|
||||
|
||||
let level_bsk = DecompositionLevelCount(9);
|
||||
let base_log_bsk = DecompositionBaseLog(4);
|
||||
|
||||
let level_pksk = DecompositionLevelCount(9);
|
||||
let base_log_pksk = DecompositionBaseLog(4);
|
||||
let params = FFT_WOPBS_PARAMS;
|
||||
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let glwe_dimension = params.glwe_dimension;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
let level_cbs = params.cbs_level;
|
||||
let base_log_cbs = params.cbs_base_log;
|
||||
let level_ksk = DecompositionLevelCount(9);
|
||||
let base_log_ksk = DecompositionBaseLog(1);
|
||||
let std_big = params.glwe_modular_std_dev;
|
||||
|
||||
let level_cbs = DecompositionLevelCount(4);
|
||||
let base_log_cbs = DecompositionBaseLog(6);
|
||||
|
||||
let ciphertext_modulus = CiphertextModulus::new_native();
|
||||
|
||||
// Value was 0.000_000_000_000_000_221_486_881_160_055_68_513645324585951
|
||||
// But rust indicates it gets truncated anyways to
|
||||
// 0.000_000_000_000_000_221_486_881_160_055_68
|
||||
let std_small = StandardDev::from_standard_dev(0.000_000_000_000_000_221_486_881_160_055_68);
|
||||
// Value was 0.000_061_200_133_780_220_371_345
|
||||
// But rust indicates it gets truncated anyways to
|
||||
// 0.000_061_200_133_780_220_36
|
||||
let std_big = StandardDev::from_standard_dev(0.000_061_200_133_780_220_36);
|
||||
|
||||
let mut seeder = new_seeder();
|
||||
let seeder = seeder.as_mut();
|
||||
|
||||
let mut secret_generator = SecretRandomGenerator::<SoftwareRandomGenerator>::new(seeder.seed());
|
||||
let mut encryption_generator =
|
||||
EncryptionRandomGenerator::<SoftwareRandomGenerator>::new(seeder.seed(), seeder);
|
||||
|
||||
//create GLWE and LWE secret key
|
||||
let glwe_sk: GlweSecretKeyOwned<u64> = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dimension,
|
||||
polynomial_size,
|
||||
&mut secret_generator,
|
||||
);
|
||||
let lwe_small_sk: LweSecretKeyOwned<u64> =
|
||||
allocate_and_generate_new_binary_lwe_secret_key(small_lwe_dimension, &mut secret_generator);
|
||||
|
||||
let lwe_big_sk = glwe_sk.clone().into_lwe_secret_key();
|
||||
|
||||
let input_lwe_dimension = lwe_big_sk.lwe_dimension();
|
||||
|
||||
// allocation and generation of the key in coef domain:
|
||||
let std_bsk: LweBootstrapKeyOwned<u64> = allocate_and_generate_new_lwe_bootstrap_key(
|
||||
&lwe_small_sk,
|
||||
&glwe_sk,
|
||||
base_log_bsk,
|
||||
level_bsk,
|
||||
std_small,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
);
|
||||
|
||||
// allocation for the bootstrapping key
|
||||
let mut fourier_bsk = FourierLweBootstrapKey::new(
|
||||
small_lwe_dimension,
|
||||
glwe_dimension.to_glwe_size(),
|
||||
polynomial_size,
|
||||
base_log_bsk,
|
||||
level_bsk,
|
||||
);
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
let fft = Fft::new(polynomial_size);
|
||||
let fft = fft.as_view();
|
||||
|
||||
fourier_bsk
|
||||
.as_mut_view()
|
||||
.par_fill_with_forward_fourier(std_bsk.as_view(), fft);
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let (fourier_bsk, lwe_small_sk, lwe_big_sk, vec_pfpksk) = (
|
||||
keys.fbsk,
|
||||
keys.small_lwe_sk,
|
||||
keys.big_lwe_sk,
|
||||
keys.lwe_pfpksk,
|
||||
);
|
||||
|
||||
let input_lwe_dimension = lwe_big_sk.lwe_dimension();
|
||||
|
||||
let ksk_lwe_big_to_small: LweKeyswitchKeyOwned<u64> =
|
||||
allocate_and_generate_new_lwe_keyswitch_key(
|
||||
@@ -603,20 +618,9 @@ pub fn test_extract_bit_circuit_bootstrapping_vertical_packing() {
|
||||
level_ksk,
|
||||
std_big,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
// Creation of all the pfksk for the circuit bootstrapping
|
||||
let vec_pfpksk = par_allocate_and_generate_new_circuit_bootstrap_lwe_pfpksk_list(
|
||||
&lwe_big_sk,
|
||||
&glwe_sk,
|
||||
base_log_pksk,
|
||||
level_pksk,
|
||||
std_small,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
);
|
||||
|
||||
let number_of_bits_in_input_lwe = 10;
|
||||
let number_of_values_to_extract = ExtractedBitsCount(number_of_bits_in_input_lwe);
|
||||
|
||||
@@ -627,9 +631,7 @@ pub fn test_extract_bit_circuit_bootstrapping_vertical_packing() {
|
||||
let delta_log = DeltaLog(64 - number_of_values_to_extract.0);
|
||||
let delta_lut = DeltaLog(64 - number_of_values_to_extract.0);
|
||||
|
||||
let number_of_test_runs = 10;
|
||||
|
||||
for run_number in 0..number_of_test_runs {
|
||||
for run_number in 0..NB_TESTS_LIGHT {
|
||||
let cleartext =
|
||||
test_tools::random_uint_between(0..2u64.pow(number_of_bits_in_input_lwe as u32));
|
||||
|
||||
@@ -649,7 +651,7 @@ pub fn test_extract_bit_circuit_bootstrapping_vertical_packing() {
|
||||
&mut lwe_in,
|
||||
message,
|
||||
std_big,
|
||||
&mut encryption_generator,
|
||||
&mut rsc.encryption_random_generator,
|
||||
);
|
||||
|
||||
let mut extracted_bits_lwe_list = LweCiphertextListOwned::new(
|
||||
@@ -762,8 +764,7 @@ pub fn test_extract_bit_circuit_bootstrapping_vertical_packing() {
|
||||
let result_ct = vertical_packing_lwe_list_out.iter().next().unwrap();
|
||||
|
||||
// decrypt result
|
||||
let lwe_sk = glwe_sk.clone().into_lwe_secret_key();
|
||||
let decrypted_message = decrypt_lwe_ciphertext(&lwe_sk, &result_ct);
|
||||
let decrypted_message = decrypt_lwe_ciphertext(&lwe_big_sk, &result_ct);
|
||||
let decoded_message = decomposer.closest_representable(decrypted_message.0) >> delta_log.0;
|
||||
|
||||
// print information if the result is wrong
|
||||
@@ -776,83 +777,42 @@ pub fn test_extract_bit_circuit_bootstrapping_vertical_packing() {
|
||||
}
|
||||
}
|
||||
|
||||
fn test_wop_add_one(polynomial_size: PolynomialSize) {
|
||||
// DISCLAIMER: these are toy parameters and are not guaranteed to be secure
|
||||
let glwe_dim = GlweDimension(1);
|
||||
let small_dim = LweDimension(4);
|
||||
let level_bsk = DecompositionLevelCount(4);
|
||||
let base_log_bsk = DecompositionBaseLog(9);
|
||||
let level_pksk = DecompositionLevelCount(2);
|
||||
let base_log_pksk = DecompositionBaseLog(15);
|
||||
let level_cbs = DecompositionLevelCount(4);
|
||||
let base_log_cbs = DecompositionBaseLog(6);
|
||||
let ciphertext_modulus = CiphertextModulus::new_native();
|
||||
let variance = crate::core_crypto::commons::dispersion::Variance(0.0);
|
||||
fn test_wop_add_one(params: FftWopPbsTestParams<u64>) {
|
||||
let polynomial_size = params.polynomial_size;
|
||||
let small_dim = params.lwe_dimension;
|
||||
let level_cbs = params.cbs_level;
|
||||
let base_log_cbs = params.cbs_base_log;
|
||||
let ciphertext_modulus = params.ciphertext_modulus;
|
||||
let std_small = params.lwe_modular_std_dev;
|
||||
|
||||
let mut seeder = new_seeder();
|
||||
let seeder = seeder.as_mut();
|
||||
|
||||
let mut secret_generator = SecretRandomGenerator::<SoftwareRandomGenerator>::new(seeder.seed());
|
||||
let mut encryption_generator =
|
||||
EncryptionRandomGenerator::<SoftwareRandomGenerator>::new(seeder.seed(), seeder);
|
||||
|
||||
let small_sk =
|
||||
allocate_and_generate_new_binary_lwe_secret_key::<u64, _>(small_dim, &mut secret_generator);
|
||||
|
||||
let big_sk = allocate_and_generate_new_binary_glwe_secret_key(
|
||||
glwe_dim,
|
||||
polynomial_size,
|
||||
&mut secret_generator,
|
||||
);
|
||||
|
||||
let big_lwe_sk = big_sk.clone().into_lwe_secret_key();
|
||||
|
||||
// allocation and generation of the key in coef domain:
|
||||
let std_bsk: LweBootstrapKeyOwned<u64> = allocate_and_generate_new_lwe_bootstrap_key(
|
||||
&small_sk,
|
||||
&big_sk,
|
||||
base_log_bsk,
|
||||
level_bsk,
|
||||
variance,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
);
|
||||
|
||||
// allocation for the bootstrapping key
|
||||
let mut fourier_bsk = FourierLweBootstrapKey::new(
|
||||
small_dim,
|
||||
glwe_dim.to_glwe_size(),
|
||||
polynomial_size,
|
||||
base_log_bsk,
|
||||
level_bsk,
|
||||
);
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
let fft = Fft::new(polynomial_size);
|
||||
let fft = fft.as_view();
|
||||
|
||||
fourier_bsk
|
||||
.as_mut_view()
|
||||
.par_fill_with_forward_fourier(std_bsk.as_view(), fft);
|
||||
|
||||
// Creation of all the pfksk for the circuit bootstrapping
|
||||
let cbs_pfpksk = par_allocate_and_generate_new_circuit_bootstrap_lwe_pfpksk_list(
|
||||
&big_lwe_sk,
|
||||
&big_sk,
|
||||
base_log_pksk,
|
||||
level_pksk,
|
||||
variance,
|
||||
ciphertext_modulus,
|
||||
&mut encryption_generator,
|
||||
let mut keys_gen = |params| generate_keys(params, &mut rsc);
|
||||
let keys = gen_keys_or_get_from_cache_if_enabled(params, &mut keys_gen);
|
||||
let (fourier_bsk, small_sk, big_lwe_sk, cbs_pfpksk) = (
|
||||
keys.fbsk,
|
||||
keys.small_lwe_sk,
|
||||
keys.big_lwe_sk,
|
||||
keys.lwe_pfpksk,
|
||||
);
|
||||
|
||||
// We are going to encrypt 10 bits
|
||||
let number_of_input_bits: usize = 10;
|
||||
|
||||
#[cfg(not(feature = "__coverage"))]
|
||||
const SIZE: usize = 10;
|
||||
#[cfg(feature = "__coverage")]
|
||||
const SIZE: usize = 1;
|
||||
|
||||
// Test on 610, binary representation 10011 00010
|
||||
let mut vals = [0u64; 10];
|
||||
let mut vals = [0u64; SIZE];
|
||||
vals[0] = 610;
|
||||
// Use our generator to have more random values
|
||||
encryption_generator.fill_slice_with_random_mask(&mut vals[1..]);
|
||||
rsc.encryption_random_generator
|
||||
.fill_slice_with_random_mask(&mut vals[1..]);
|
||||
// Apply our modulus to be sure we can represent the test values
|
||||
vals.iter_mut()
|
||||
.for_each(|x| *x %= 1 << number_of_input_bits);
|
||||
@@ -871,8 +831,8 @@ fn test_wop_add_one(polynomial_size: PolynomialSize) {
|
||||
&small_sk,
|
||||
&mut extracted_bits.get_mut(number_of_input_bits - i - 1),
|
||||
Plaintext(((val >> i) & 1) << 63),
|
||||
variance,
|
||||
&mut encryption_generator,
|
||||
std_small,
|
||||
&mut rsc.encryption_random_generator,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -957,17 +917,17 @@ fn test_wop_add_one(polynomial_size: PolynomialSize) {
|
||||
//CMUX tree
|
||||
#[test]
|
||||
fn test_wop_add_one_cmux_tree() {
|
||||
test_wop_add_one(PolynomialSize(512))
|
||||
test_wop_add_one(FFT_WOPBS_N512_PARAMS)
|
||||
}
|
||||
|
||||
//No CMUX tree
|
||||
#[test]
|
||||
fn test_wop_add_one_no_cmux_tree() {
|
||||
test_wop_add_one(PolynomialSize(1024))
|
||||
test_wop_add_one(FFT_WOPBS_N1024_PARAMS)
|
||||
}
|
||||
|
||||
//Expanded lut
|
||||
#[test]
|
||||
fn test_wop_add_one_expanded_lut() {
|
||||
test_wop_add_one(PolynomialSize(2048))
|
||||
test_wop_add_one(FFT_WOPBS_N2048_PARAMS)
|
||||
}
|
||||
|
||||
273
tfhe/src/core_crypto/keycache.rs
Normal file
273
tfhe/src/core_crypto/keycache.rs
Normal file
@@ -0,0 +1,273 @@
|
||||
use crate::core_crypto::algorithms::test::{
|
||||
ClassicBootstrapKeys, ClassicTestParams, FftBootstrapKeys, FftTestParams, FftWopPbsKeys,
|
||||
FftWopPbsTestParams, MultiBitBootstrapKeys, MultiBitTestParams, PackingKeySwitchKeys,
|
||||
PackingKeySwitchTestParams,
|
||||
};
|
||||
use crate::keycache::*;
|
||||
use lazy_static::*;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
#[cfg(feature = "internal-keycache")]
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub struct KeyCacheCoreImpl<P, K>
|
||||
where
|
||||
P: Copy + NamedParam + DeserializeOwned + Serialize + PartialEq,
|
||||
K: DeserializeOwned + Serialize,
|
||||
{
|
||||
inner: ImplKeyCache<P, K, FileStorage>,
|
||||
}
|
||||
|
||||
impl<
|
||||
P: Copy + NamedParam + DeserializeOwned + Serialize + PartialEq,
|
||||
K: DeserializeOwned + Serialize,
|
||||
> Default for KeyCacheCoreImpl<P, K>
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
inner: ImplKeyCache::new(FileStorage::new(
|
||||
"../keys/core_crypto/bootstrap".to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, K> KeyCacheCoreImpl<P, K>
|
||||
where
|
||||
P: Copy + NamedParam + DeserializeOwned + Serialize + PartialEq,
|
||||
K: DeserializeOwned + Serialize + Clone,
|
||||
{
|
||||
pub fn get_key_with_closure<C>(&self, params: P, mut c: C) -> K
|
||||
where
|
||||
C: FnMut(P) -> K,
|
||||
{
|
||||
(*self.inner.get_with_closure(params, &mut c)).clone()
|
||||
}
|
||||
|
||||
pub fn clear_in_memory_cache(&self) {
|
||||
self.inner.clear_in_memory_cache();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct KeyCache {
|
||||
u32_multi_bit_cache: KeyCacheCoreImpl<MultiBitTestParams<u32>, MultiBitBootstrapKeys<u32>>,
|
||||
u64_multi_bit_cache: KeyCacheCoreImpl<MultiBitTestParams<u64>, MultiBitBootstrapKeys<u64>>,
|
||||
u32_classic_cache: KeyCacheCoreImpl<ClassicTestParams<u32>, ClassicBootstrapKeys<u32>>,
|
||||
u64_classic_cache: KeyCacheCoreImpl<ClassicTestParams<u64>, ClassicBootstrapKeys<u64>>,
|
||||
u128_classic_cache: KeyCacheCoreImpl<ClassicTestParams<u128>, ClassicBootstrapKeys<u128>>,
|
||||
u32_fft_cache: KeyCacheCoreImpl<FftTestParams<u32>, FftBootstrapKeys<u32>>,
|
||||
u64_fft_cache: KeyCacheCoreImpl<FftTestParams<u64>, FftBootstrapKeys<u64>>,
|
||||
u128_fft_cache: KeyCacheCoreImpl<FftTestParams<u128>, FftBootstrapKeys<u128>>,
|
||||
u64_fft_wopbs_cache: KeyCacheCoreImpl<FftWopPbsTestParams<u64>, FftWopPbsKeys<u64>>,
|
||||
u32_pksk_cache: KeyCacheCoreImpl<PackingKeySwitchTestParams<u32>, PackingKeySwitchKeys<u32>>,
|
||||
u64_pksk_cache: KeyCacheCoreImpl<PackingKeySwitchTestParams<u64>, PackingKeySwitchKeys<u64>>,
|
||||
}
|
||||
|
||||
impl KeyCache {
|
||||
pub fn get_key_with_closure<C, P, K>(&self, params: P, c: C) -> K
|
||||
where
|
||||
C: FnMut(P) -> K,
|
||||
P: KeyCacheAccess<Keys = K> + Serialize + DeserializeOwned + Copy + PartialEq + NamedParam,
|
||||
K: DeserializeOwned + Serialize + Clone,
|
||||
{
|
||||
P::access(self).get_key_with_closure(params, c)
|
||||
}
|
||||
|
||||
pub fn clear_in_memory_cache<P, K>(&self)
|
||||
where
|
||||
P: KeyCacheAccess<Keys = K> + Serialize + DeserializeOwned + Copy + PartialEq + NamedParam,
|
||||
K: DeserializeOwned + Serialize + Clone,
|
||||
{
|
||||
P::access(self).clear_in_memory_cache();
|
||||
}
|
||||
}
|
||||
|
||||
pub trait KeyCacheAccess: Serialize + DeserializeOwned + Copy + PartialEq + NamedParam {
|
||||
type Keys: DeserializeOwned + Serialize;
|
||||
|
||||
fn access(keycache: &KeyCache) -> &KeyCacheCoreImpl<Self, Self::Keys>;
|
||||
}
|
||||
|
||||
impl KeyCacheAccess for MultiBitTestParams<u32> {
|
||||
type Keys = MultiBitBootstrapKeys<u32>;
|
||||
|
||||
fn access(keycache: &KeyCache) -> &KeyCacheCoreImpl<Self, Self::Keys> {
|
||||
&keycache.u32_multi_bit_cache
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyCacheAccess for MultiBitTestParams<u64> {
|
||||
type Keys = MultiBitBootstrapKeys<u64>;
|
||||
|
||||
fn access(keycache: &KeyCache) -> &KeyCacheCoreImpl<Self, Self::Keys> {
|
||||
&keycache.u64_multi_bit_cache
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyCacheAccess for ClassicTestParams<u32> {
|
||||
type Keys = ClassicBootstrapKeys<u32>;
|
||||
|
||||
fn access(keycache: &KeyCache) -> &KeyCacheCoreImpl<Self, Self::Keys> {
|
||||
&keycache.u32_classic_cache
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyCacheAccess for ClassicTestParams<u64> {
|
||||
type Keys = ClassicBootstrapKeys<u64>;
|
||||
|
||||
fn access(keycache: &KeyCache) -> &KeyCacheCoreImpl<Self, Self::Keys> {
|
||||
&keycache.u64_classic_cache
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyCacheAccess for ClassicTestParams<u128> {
|
||||
type Keys = ClassicBootstrapKeys<u128>;
|
||||
|
||||
fn access(keycache: &KeyCache) -> &KeyCacheCoreImpl<Self, Self::Keys> {
|
||||
&keycache.u128_classic_cache
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyCacheAccess for FftTestParams<u32> {
|
||||
type Keys = FftBootstrapKeys<u32>;
|
||||
|
||||
fn access(keycache: &KeyCache) -> &KeyCacheCoreImpl<Self, Self::Keys> {
|
||||
&keycache.u32_fft_cache
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyCacheAccess for FftTestParams<u64> {
|
||||
type Keys = FftBootstrapKeys<u64>;
|
||||
|
||||
fn access(keycache: &KeyCache) -> &KeyCacheCoreImpl<Self, Self::Keys> {
|
||||
&keycache.u64_fft_cache
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyCacheAccess for FftTestParams<u128> {
|
||||
type Keys = FftBootstrapKeys<u128>;
|
||||
|
||||
fn access(keycache: &KeyCache) -> &KeyCacheCoreImpl<Self, Self::Keys> {
|
||||
&keycache.u128_fft_cache
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyCacheAccess for FftWopPbsTestParams<u64> {
|
||||
type Keys = FftWopPbsKeys<u64>;
|
||||
|
||||
fn access(keycache: &KeyCache) -> &KeyCacheCoreImpl<Self, Self::Keys> {
|
||||
&keycache.u64_fft_wopbs_cache
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyCacheAccess for PackingKeySwitchTestParams<u32> {
|
||||
type Keys = PackingKeySwitchKeys<u32>;
|
||||
|
||||
fn access(keycache: &KeyCache) -> &KeyCacheCoreImpl<Self, Self::Keys> {
|
||||
&keycache.u32_pksk_cache
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyCacheAccess for PackingKeySwitchTestParams<u64> {
|
||||
type Keys = PackingKeySwitchKeys<u64>;
|
||||
|
||||
fn access(keycache: &KeyCache) -> &KeyCacheCoreImpl<Self, Self::Keys> {
|
||||
&keycache.u64_pksk_cache
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref KEY_CACHE: KeyCache = Default::default();
|
||||
}
|
||||
|
||||
#[cfg(feature = "internal-keycache")]
|
||||
#[test]
|
||||
pub fn generate_keys() {
|
||||
use crate::core_crypto::algorithms::test::{
|
||||
lwe_multi_bit_programmable_bootstrapping, lwe_programmable_bootstrapping, TestResources,
|
||||
DUMMY_31_U32, DUMMY_NATIVE_U32, FFT128_U128_PARAMS, FFT_U128_PARAMS, FFT_U32_PARAMS,
|
||||
FFT_U64_PARAMS, FFT_WOPBS_N1024_PARAMS, FFT_WOPBS_N2048_PARAMS, FFT_WOPBS_N512_PARAMS,
|
||||
FFT_WOPBS_PARAMS, MULTI_BIT_2_2_2_CUSTOM_MOD_PARAMS, MULTI_BIT_2_2_2_PARAMS,
|
||||
MULTI_BIT_2_2_3_CUSTOM_MOD_PARAMS, MULTI_BIT_2_2_3_PARAMS, TEST_PARAMS_3_BITS_63_U64,
|
||||
TEST_PARAMS_4_BITS_NATIVE_U64,
|
||||
};
|
||||
use crate::core_crypto::fft_impl;
|
||||
use crate::core_crypto::fft_impl::fft64::crypto::wop_pbs;
|
||||
|
||||
fn generate_and_store<
|
||||
P: Debug + KeyCacheAccess<Keys = K> + serde::Serialize + serde::de::DeserializeOwned,
|
||||
K: serde::de::DeserializeOwned + serde::Serialize + Clone,
|
||||
>(
|
||||
params: P,
|
||||
keygen_func: &mut dyn FnMut(P) -> K,
|
||||
) {
|
||||
println!("Generating : {}", params.name());
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
let _ = KEY_CACHE.get_key_with_closure(params, keygen_func);
|
||||
|
||||
let stop = start.elapsed().as_secs();
|
||||
|
||||
println!("Generation took {stop} seconds");
|
||||
|
||||
// Clear keys as we go to avoid filling the RAM
|
||||
KEY_CACHE.clear_in_memory_cache::<P, K>()
|
||||
}
|
||||
|
||||
let mut rsc = TestResources::new();
|
||||
|
||||
println!("Generating keys for core_crypto");
|
||||
|
||||
let classical_u32_params = vec![DUMMY_31_U32, DUMMY_NATIVE_U32];
|
||||
for param in classical_u32_params.iter().copied() {
|
||||
let mut keys_gen = |_| lwe_programmable_bootstrapping::generate_keys(param, &mut rsc);
|
||||
generate_and_store(param, &mut keys_gen);
|
||||
}
|
||||
|
||||
let multi_bit_params = [
|
||||
MULTI_BIT_2_2_2_PARAMS,
|
||||
MULTI_BIT_2_2_3_PARAMS,
|
||||
MULTI_BIT_2_2_2_CUSTOM_MOD_PARAMS,
|
||||
MULTI_BIT_2_2_3_CUSTOM_MOD_PARAMS,
|
||||
];
|
||||
for param in multi_bit_params.iter().copied() {
|
||||
let mut keys_gen =
|
||||
|_| lwe_multi_bit_programmable_bootstrapping::generate_keys(param, &mut rsc);
|
||||
generate_and_store(param, &mut keys_gen);
|
||||
}
|
||||
|
||||
let classical_u64_params = [TEST_PARAMS_4_BITS_NATIVE_U64, TEST_PARAMS_3_BITS_63_U64];
|
||||
for param in classical_u64_params.iter().copied() {
|
||||
let mut keys_gen = |_| lwe_programmable_bootstrapping::generate_keys(param, &mut rsc);
|
||||
generate_and_store(param, &mut keys_gen);
|
||||
}
|
||||
|
||||
generate_and_store(FFT_U32_PARAMS, &mut |_| {
|
||||
fft_impl::common::tests::generate_keys(FFT_U32_PARAMS, &mut rsc)
|
||||
});
|
||||
generate_and_store(FFT_U64_PARAMS, &mut |_| {
|
||||
fft_impl::common::tests::generate_keys(FFT_U64_PARAMS, &mut rsc)
|
||||
});
|
||||
generate_and_store(FFT_U128_PARAMS, &mut |_| {
|
||||
fft_impl::common::tests::generate_keys(FFT_U128_PARAMS, &mut rsc)
|
||||
});
|
||||
|
||||
generate_and_store(FFT128_U128_PARAMS, &mut |_| {
|
||||
fft_impl::common::tests::generate_keys(FFT128_U128_PARAMS, &mut rsc)
|
||||
});
|
||||
|
||||
generate_and_store(FFT_WOPBS_PARAMS, &mut |_| {
|
||||
wop_pbs::tests::generate_keys(FFT_WOPBS_PARAMS, &mut rsc)
|
||||
});
|
||||
generate_and_store(FFT_WOPBS_N512_PARAMS, &mut |_| {
|
||||
wop_pbs::tests::generate_keys(FFT_WOPBS_N512_PARAMS, &mut rsc)
|
||||
});
|
||||
generate_and_store(FFT_WOPBS_N1024_PARAMS, &mut |_| {
|
||||
wop_pbs::tests::generate_keys(FFT_WOPBS_N1024_PARAMS, &mut rsc)
|
||||
});
|
||||
generate_and_store(FFT_WOPBS_N2048_PARAMS, &mut |_| {
|
||||
wop_pbs::tests::generate_keys(FFT_WOPBS_N2048_PARAMS, &mut rsc)
|
||||
});
|
||||
}
|
||||
@@ -17,3 +17,6 @@ pub mod prelude;
|
||||
pub mod seeders;
|
||||
|
||||
pub mod fft_impl;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod keycache;
|
||||
|
||||
@@ -155,12 +155,26 @@ pub mod utils {
|
||||
K: From<P> + Clone,
|
||||
{
|
||||
pub fn get(&self, param: P) -> SharedKey<K> {
|
||||
self.with_key(param, |k| k.clone())
|
||||
self.get_with_closure(param, &mut K::from)
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, K, S> KeyCache<P, K, S>
|
||||
where
|
||||
P: Copy + PartialEq + NamedParam,
|
||||
S: PersistentStorage<P, K>,
|
||||
{
|
||||
pub fn get_with_closure<C: FnMut(P) -> K>(
|
||||
&self,
|
||||
param: P,
|
||||
key_gen_closure: &mut C,
|
||||
) -> SharedKey<K> {
|
||||
self.with_closure(param, key_gen_closure)
|
||||
}
|
||||
|
||||
pub fn with_key<F, R>(&self, param: P, f: F) -> R
|
||||
pub fn with_closure<C>(&self, param: P, key_gen_closure: &mut C) -> SharedKey<K>
|
||||
where
|
||||
F: FnOnce(&SharedKey<K>) -> R,
|
||||
C: FnMut(P) -> K,
|
||||
{
|
||||
let load_from_persistent_storage = || {
|
||||
// we check if we can load the key from persistent storage
|
||||
@@ -168,7 +182,7 @@ pub mod utils {
|
||||
let maybe_key = persistent_storage.load(param);
|
||||
maybe_key.map_or_else(
|
||||
|| {
|
||||
let key = K::from(param);
|
||||
let key = key_gen_closure(param);
|
||||
persistent_storage.store(param, &key);
|
||||
key
|
||||
},
|
||||
@@ -176,42 +190,40 @@ pub mod utils {
|
||||
)
|
||||
};
|
||||
|
||||
let try_load_from_memory_and_init = || {
|
||||
// we only hold a read lock for a short duration to find the key
|
||||
let maybe_shared_cell = {
|
||||
let memory_storage = self.memory_storage.read().unwrap();
|
||||
memory_storage
|
||||
.iter()
|
||||
.find(|(p, _)| *p == param)
|
||||
.map(|param_key| param_key.1.clone())
|
||||
let try_load_from_memory_and_init = || -> Result<_, ()> {
|
||||
let maybe_shared_key = {
|
||||
let mut res = None;
|
||||
let lock = &*self.memory_storage.read().unwrap();
|
||||
for (p, key) in lock.iter() {
|
||||
if *p == param {
|
||||
res = Some(key.clone());
|
||||
break;
|
||||
}
|
||||
}
|
||||
res
|
||||
};
|
||||
|
||||
if let Some(shared_cell) = maybe_shared_cell {
|
||||
shared_cell.inner.get_or_init(load_from_persistent_storage);
|
||||
Ok(shared_cell)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
maybe_shared_key.map_or_else(
|
||||
|| {
|
||||
let shared_key = SharedKey {
|
||||
inner: Arc::new(OnceLock::new()),
|
||||
};
|
||||
shared_key.inner.get_or_init(load_from_persistent_storage);
|
||||
{
|
||||
// we only hold a write lock for a short duration to push the key
|
||||
// if it doesn't already exists.
|
||||
let mut memory_storage = self.memory_storage.write().unwrap();
|
||||
if memory_storage.iter().all(|(p, _)| *p != param) {
|
||||
memory_storage.push((param, shared_key.clone()));
|
||||
}
|
||||
}
|
||||
Ok(shared_key)
|
||||
},
|
||||
Ok,
|
||||
)
|
||||
};
|
||||
|
||||
if let Ok(result) = try_load_from_memory_and_init() {
|
||||
f(&result)
|
||||
} else {
|
||||
{
|
||||
// we only hold a write lock for a short duration to push the lazily
|
||||
// evaluated key without actually evaluating the key
|
||||
let mut memory_storage = self.memory_storage.write().unwrap();
|
||||
if !memory_storage.iter().any(|(p, _)| *p == param) {
|
||||
memory_storage.push((
|
||||
param,
|
||||
SharedKey {
|
||||
inner: Arc::new(OnceLock::new()),
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
f(&try_load_from_memory_and_init().ok().unwrap())
|
||||
}
|
||||
try_load_from_memory_and_init().ok().unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,15 +392,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WopbsParamPair> for WopbsKey {
|
||||
fn from(params: WopbsParamPair) -> Self {
|
||||
// use with_key to avoid doing a temporary cloning
|
||||
KEY_CACHE.inner.with_key(params.0, |keys| {
|
||||
Self::new_wopbs_key(&keys.0, &keys.1, ¶ms.1)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl NamedParam for WopbsParamPair {
|
||||
fn name(&self) -> String {
|
||||
self.1.name()
|
||||
@@ -427,7 +418,9 @@ impl KeycacheWopbsV0 {
|
||||
pub fn get_from_param<T: Into<WopbsParamPair>>(&self, params: T) -> SharedWopbsKey {
|
||||
let params = params.into();
|
||||
let key = KEY_CACHE.get_from_param(params.0);
|
||||
let wk = self.inner.get(params);
|
||||
let wk = self.inner.get_with_closure(params, &mut |_| {
|
||||
WopbsKey::new_wopbs_key(&key.inner.0, &key.inner.1, ¶ms.1)
|
||||
});
|
||||
SharedWopbsKey {
|
||||
inner: key.inner,
|
||||
wopbs: wk,
|
||||
@@ -455,17 +448,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KeySwitchingKeyParams> for KeySwitchingKey {
|
||||
fn from(params: KeySwitchingKeyParams) -> Self {
|
||||
// use with_key to avoid doing a temporary cloning
|
||||
KEY_CACHE.inner.with_key(params.0, |keys_1| {
|
||||
KEY_CACHE.inner.with_key(params.1, |keys_2| {
|
||||
Self::new((&keys_1.0, &keys_1.1), (&keys_2.0, &keys_2.1), params.2)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl NamedParam for KeySwitchingKeyParams {
|
||||
fn name(&self) -> String {
|
||||
format!("{}__{}__{}", self.0.name(), self.1.name(), self.2.name())
|
||||
@@ -496,7 +478,13 @@ impl KeycacheKeySwitchingKey {
|
||||
let params = params.into();
|
||||
let key_1 = KEY_CACHE.get_from_param(params.0);
|
||||
let key_2 = KEY_CACHE.get_from_param(params.1);
|
||||
let ksk = self.inner.get(params);
|
||||
let ksk = self.inner.get_with_closure(params, &mut |_| {
|
||||
KeySwitchingKey::new(
|
||||
(key_1.client_key(), key_1.server_key()),
|
||||
(key_2.client_key(), key_2.server_key()),
|
||||
params.2,
|
||||
)
|
||||
});
|
||||
SharedKeySwitchingKey {
|
||||
inner_1: key_1.inner,
|
||||
inner_2: key_2.inner,
|
||||
|
||||
@@ -253,6 +253,7 @@ fn test_ct_scalar_op_assign_noise_level_propagation(sk: &ServerKey, ct: &Ciphert
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "__coverage"))] // This test is ignored in coverage, it takes around 4 hours to run otherwise.
|
||||
#[test]
|
||||
fn test_noise_level_propagation_ci_run_filter() {
|
||||
let params = PARAM_MESSAGE_2_CARRY_2_KS_PBS;
|
||||
|
||||
Reference in New Issue
Block a user