From 7735fbe85cc7cc77551565411c5b3108b0210be9 Mon Sep 17 00:00:00 2001 From: "Mayeul@Zama" Date: Thu, 8 Dec 2022 10:37:42 +0100 Subject: [PATCH] add rust crate to expose security weights --- .gitignore | 2 + rust-security-curves/Cargo.toml | 8 +++ rust-security-curves/src/lib.rs | 67 ++++++++++++++++++++++++ rust-security-curves/verified_curves.txt | 9 ++++ 4 files changed, 86 insertions(+) create mode 100644 .gitignore create mode 100644 rust-security-curves/Cargo.toml create mode 100644 rust-security-curves/src/lib.rs create mode 100644 rust-security-curves/verified_curves.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..ba51dfb7f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +rust-security-curves/target/ +rust-security-curves/Cargo.lock diff --git a/rust-security-curves/Cargo.toml b/rust-security-curves/Cargo.toml new file mode 100644 index 000000000..facecdebe --- /dev/null +++ b/rust-security-curves/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust-security-curves" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rust-security-curves/src/lib.rs b/rust-security-curves/src/lib.rs new file mode 100644 index 000000000..c59091925 --- /dev/null +++ b/rust-security-curves/src/lib.rs @@ -0,0 +1,67 @@ +const SECURITY_WEIGHTS_ARRAY: [(f64, f64, u64, &str, u64); 9] = include!("../verified_curves.txt"); + +#[derive(Clone, Copy)] +pub struct SecurityWeights { + slope: f64, + bias: f64, + minimal_lwe_dimension: u64, +} + +impl SecurityWeights { + pub fn secure_log2_std(&self, lwe_dimension: u64, ciphertext_modulus_log: f64) -> f64 { + // ensure to have a minimal on std deviation covering the 2 lowest bits on modular scale + let epsilon_log2_std_modular = 2.0; + let epsilon_log2_std = epsilon_log2_std_modular - (ciphertext_modulus_log); + // ensure the requested lwe_dimension is bigger than the minimal lwe dimension + if self.minimal_lwe_dimension <= lwe_dimension { + f64::max( + self.slope * lwe_dimension as f64 + self.bias, + epsilon_log2_std, + ) + } else { + ciphertext_modulus_log + } + } +} + +pub fn supported_security_levels() -> impl std::iter::Iterator { + SECURITY_WEIGHTS_ARRAY + .iter() + .filter(|(_, _, _, status, _)| *status == "PASS") + .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, _, _)| { + *security_level + }) + .ok()?; + + let (slope, bias, _security_level, status, minimal_lwe_dimension) = + SECURITY_WEIGHTS_ARRAY[index]; + + if status == "PASS" { + Some(SecurityWeights { + slope, + bias, + minimal_lwe_dimension, + }) + } else { + None + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let weight = security_weight(128).unwrap(); + + let secure_log_2_std = weight.secure_log2_std(512, 64.); + + assert!((-12.0..-10.0).contains(&secure_log_2_std)); + } +} diff --git a/rust-security-curves/verified_curves.txt b/rust-security-curves/verified_curves.txt new file mode 100644 index 000000000..f1ed1aed1 --- /dev/null +++ b/rust-security-curves/verified_curves.txt @@ -0,0 +1,9 @@ +[(-0.04042633119364589, 1.6609788641436722, 80, "PASS", 450), + (-0.03414780360867051, 2.017310258660345, 96, "PASS", 450), + (-0.029670137081135885, 2.162463714083856, 112, "PASS", 450), + (-0.02640502876522622, 2.4826422691043177, 128, "PASS", 450), + (-0.023821437305989134, 2.7177789440636673, 144, "PASS", 450), + (-0.02174358218716036, 2.938810548493322, 160, "PASS", 498), + (-0.019904056582117684, 2.8161252801542247, 176, "PASS", 551), + (-0.018610403247590085, 3.2996236848399008, 192, "PASS", 606), + (-0.014606812351714953, 3.8493629234693003, 256, "PASS", 826)]