diff --git a/concrete-optimizer/Cargo.toml b/concrete-optimizer/Cargo.toml index f7aacca2e..6e6b7dc0e 100644 --- a/concrete-optimizer/Cargo.toml +++ b/concrete-optimizer/Cargo.toml @@ -9,7 +9,6 @@ edition = "2021" concrete-commons = { git = "ssh://git@github.com/zama-ai/concrete-core.git", rev = "715d4a18a59d13a5a51fee14bc1f6578de665c20" } concrete-npe = { git = "ssh://git@github.com/zama-ai/concrete-core.git", rev = "715d4a18a59d13a5a51fee14bc1f6578de665c20" } file-lock = "2.1.6" -static_init = "1.0.3" serde = { version = "1.0", features = ["derive"] } bincode = "1.3" puruspe = "0.2.0" diff --git a/concrete-optimizer/src/security/glwe.rs b/concrete-optimizer/src/security/glwe.rs index 95d44d48b..fae3fa799 100644 --- a/concrete-optimizer/src/security/glwe.rs +++ b/concrete-optimizer/src/security/glwe.rs @@ -1,5 +1,5 @@ +use super::security_weights::security_weight; use crate::parameters::GlweParameters; -use crate::security::security_weights::SECURITY_WEIGHTS_TABLE; use concrete_commons::dispersion::Variance; /// Noise ensuring security @@ -9,9 +9,9 @@ pub fn minimal_variance( security_level: u64, ) -> Variance { let equiv_lwe_dimension = glwe_params.glwe_dimension * glwe_params.polynomial_size(); - let security_weights = SECURITY_WEIGHTS_TABLE - .get(&security_level) + let security_weights = security_weight(security_level) .unwrap_or_else(|| panic!("{security_level} bits of security is not supported")); + let secure_log2_std = security_weights.secure_log2_std(equiv_lwe_dimension, ciphertext_modulus_log as f64); let log2_var = 2.0 * secure_log2_std; diff --git a/concrete-optimizer/src/security/security_weights.rs b/concrete-optimizer/src/security/security_weights.rs index 0a36da213..74c1a294a 100644 --- a/concrete-optimizer/src/security/security_weights.rs +++ b/concrete-optimizer/src/security/security_weights.rs @@ -1,7 +1,4 @@ -use std::collections::HashMap; - -use static_init::dynamic; - +#[derive(Clone, Copy)] pub struct SecurityWeights { slope: f64, bias: f64, @@ -102,6 +99,18 @@ const SECURITY_WEIGHTS_ARRAY: [(u64, SecurityWeights); 9] = [ ), ]; -#[dynamic(lazy)] -pub static SECURITY_WEIGHTS_TABLE: HashMap = - HashMap::from(SECURITY_WEIGHTS_ARRAY); +pub fn supported_security_levels() -> impl std::iter::Iterator { + SECURITY_WEIGHTS_ARRAY + .iter() + .map(|(security_level, _)| *security_level) +} + +pub fn security_weight(security_level: u64) -> Option { + let index = SECURITY_WEIGHTS_ARRAY + .binary_search_by_key(&security_level, |(security_level, _weights)| { + *security_level + }) + .ok()?; + + Some(SECURITY_WEIGHTS_ARRAY[index].1) +} diff --git a/v0-parameters/src/bin/v0-parameters-by-level.rs b/v0-parameters/src/bin/v0-parameters-by-level.rs index 609e389b5..145938206 100644 --- a/v0-parameters/src/bin/v0-parameters-by-level.rs +++ b/v0-parameters/src/bin/v0-parameters-by-level.rs @@ -4,7 +4,7 @@ use chrono::{Datelike, Utc}; use clap::Parser; -use concrete_optimizer::security::security_weights::SECURITY_WEIGHTS_TABLE; +use concrete_optimizer::security::security_weights::supported_security_levels; use std::fs::File; use v0_parameters::{compute_print_results, Args}; @@ -26,7 +26,7 @@ fn main() { args.max_precision = 9; } - for &security_level in SECURITY_WEIGHTS_TABLE.keys() { + for security_level in supported_security_levels() { let filename_date = if args.wop_pbs { format!("ref/wop_pbs_{year}-{month}-{day}_{security_level}") } else { diff --git a/v0-parameters/src/lib.rs b/v0-parameters/src/lib.rs index e90b1f313..dfe301c23 100644 --- a/v0-parameters/src/lib.rs +++ b/v0-parameters/src/lib.rs @@ -235,27 +235,27 @@ pub fn compute_print_results(mut writer: impl Write, args: &Args) -> Result<(), #[cfg(test)] mod tests { - use super::*; - use concrete_optimizer::security::security_weights::SECURITY_WEIGHTS_TABLE; + use concrete_optimizer::security::security_weights::supported_security_levels; - fn security_levels_to_test() -> Vec { - SECURITY_WEIGHTS_TABLE.keys().copied().collect() - } + use super::*; #[test] fn test_reference_output() { - check_reference_output_on_levels(&security_levels_to_test(), false); + check_reference_output_on_levels(supported_security_levels(), false); } #[test] fn test_reference_output_dag() { - check_reference_output_on_levels(&security_levels_to_test(), true); + check_reference_output_on_levels(supported_security_levels(), true); } - fn check_reference_output_on_levels(security_levels: &[u64], simulate_dag: bool) { + fn check_reference_output_on_levels( + security_levels: impl std::iter::Iterator, + simulate_dag: bool, + ) { const CMP_LINES: &str = "\n"; const EXACT_EQUALITY: i32 = 0; - for &security_level in security_levels { + for security_level in security_levels { let ref_file: &str = &format!("ref/v0_last_{security_level}"); let args: Args = Args { min_precision: 1, @@ -289,13 +289,13 @@ mod tests { #[test] fn test_reference_wop_output() { - check_reference_wop_output_on_levels(&security_levels_to_test()); + check_reference_wop_output_on_levels(supported_security_levels()); } - fn check_reference_wop_output_on_levels(security_levels: &[u64]) { + fn check_reference_wop_output_on_levels(security_levels: impl std::iter::Iterator) { const CMP_LINES: &str = "\n"; const EXACT_EQUALITY: i32 = 0; - for &security_level in security_levels { + for security_level in security_levels { let ref_file: &str = &format!("ref/wop_pbs_last_{security_level}"); let args = Args {