From e9125df70d91d99c231d1d9bb5938c2f2afd8d9e Mon Sep 17 00:00:00 2001 From: Sam Tay Date: Sun, 11 Feb 2024 16:03:00 -0500 Subject: [PATCH] Allow insecure params for tests (#344) --- logproof/Cargo.toml | 1 + logproof/src/bfv_statement.rs | 9 +++++---- logproof/src/rings.rs | 22 ++++++++++++++++++++++ seal_fhe/Cargo.toml | 1 + seal_fhe/src/context.rs | 20 ++++++++++++++++++++ sunscreen/Cargo.toml | 1 + sunscreen/tests/linked.rs | 29 +++++++++++++++-------------- sunscreen/tests/sdlp.rs | 19 ++++++++++--------- sunscreen_runtime/Cargo.toml | 1 + sunscreen_runtime/src/builder.rs | 11 +++++------ sunscreen_runtime/src/runtime.rs | 4 ++++ 11 files changed, 85 insertions(+), 33 deletions(-) diff --git a/logproof/Cargo.toml b/logproof/Cargo.toml index 5e3c03dfe..4e3a2637b 100644 --- a/logproof/Cargo.toml +++ b/logproof/Cargo.toml @@ -24,6 +24,7 @@ thiserror = { workspace = true } bincode = { workspace = true } criterion = { workspace = true } once_cell = { workspace = true } +seal_fhe = { workspace = true, features = ["insecure-params"] } [features] default = [] diff --git a/logproof/src/bfv_statement.rs b/logproof/src/bfv_statement.rs index 45ebd5809..76b2a942a 100644 --- a/logproof/src/bfv_statement.rs +++ b/logproof/src/bfv_statement.rs @@ -768,16 +768,16 @@ mod tests { impl BFVTestContext { fn new() -> Self { - let plain_modulus = PlainModulus::raw(1153).unwrap(); + let plain_modulus = PlainModulus::raw(32).unwrap(); let coeff_modulus = CoefficientModulus::bfv_default(1024, SecurityLevel::TC128).unwrap(); let params = BfvEncryptionParametersBuilder::new() - .set_poly_modulus_degree(1024) + .set_poly_modulus_degree(64) .set_coefficient_modulus(coeff_modulus) .set_plain_modulus(plain_modulus) .build() .unwrap(); - let ctx = Context::new(¶ms, false, SecurityLevel::TC128).unwrap(); + let ctx = Context::new_insecure(¶ms, false).unwrap(); let gen = KeyGenerator::new(&ctx).unwrap(); let public_key = gen.create_public_key(); let secret_key = gen.secret_key(); @@ -902,8 +902,9 @@ mod tests { let mut rng = rand::thread_rng(); let mut pt = Plaintext::new().unwrap(); let modulus = self.params.plain_modulus(); + let len = self.params.get_poly_modulus_degree() as usize; - let size = rng.gen_range(0..100); + let size = rng.gen_range(0..len); pt.resize(size); for i in 0..size { diff --git a/logproof/src/rings.rs b/logproof/src/rings.rs index 7d3d862d0..370006e3a 100644 --- a/logproof/src/rings.rs +++ b/logproof/src/rings.rs @@ -47,6 +47,16 @@ pub type ZqRistretto = Zq<4, BarrettBackend<4, RistrettoConfig>>; num_limbs = 3 )] pub struct SealQ128_8192 {} +impl SealQ128_8192 { + /// The SEAL modulus chain + pub const Q: &'static [u64] = &[ + 0x7fffffd8001, + 0x7fffffc8001, + 0xfffffffc001, + 0xffffff6c001, + 0xfffffebc001, + ]; +} /** * The configuration type for q modulus SEAL BFV uses with 128-bit security @@ -65,6 +75,10 @@ pub struct SealQ128_8192 {} #[derive(BarrettConfig)] #[barrett_config(modulus = "4722344527977019809793", num_limbs = 2)] pub struct SealQ128_4096 {} +impl SealQ128_4096 { + /// The SEAL modulus chain + pub const Q: &'static [u64] = &[0xffffee001, 0xffffc4001, 0x1ffffe0001]; +} /** * The configuration type for q modulus SEAL BFV uses with 128-bit security @@ -83,6 +97,10 @@ pub struct SealQ128_4096 {} #[derive(BarrettConfig)] #[barrett_config(modulus = "18014398492704769", num_limbs = 1)] pub struct SealQ128_2048 {} +impl SealQ128_2048 { + /// The SEAL modulus chain + pub const Q: &'static [u64] = &[0x3fffffff000001]; +} /** * The configuration type for q modulus SEAL BFV uses with 128-bit security @@ -101,6 +119,10 @@ pub struct SealQ128_2048 {} #[derive(BarrettConfig)] #[barrett_config(modulus = "132120577", num_limbs = 1)] pub struct SealQ128_1024 {} +impl SealQ128_1024 { + /// The SEAL modulus chain + pub const Q: &'static [u64] = &[0x7e00001]; +} #[allow(unused)] /** diff --git a/seal_fhe/Cargo.toml b/seal_fhe/Cargo.toml index a710d0ace..843bf4e40 100644 --- a/seal_fhe/Cargo.toml +++ b/seal_fhe/Cargo.toml @@ -37,3 +37,4 @@ serde_json = { workspace = true } hexl = [] transparent-ciphertexts = [] deterministic = [] +insecure-params = [] diff --git a/seal_fhe/src/context.rs b/seal_fhe/src/context.rs index 32c150171..a32ab1725 100644 --- a/seal_fhe/src/context.rs +++ b/seal_fhe/src/context.rs @@ -79,6 +79,26 @@ impl Context { Ok(Context { handle }) } + /** + * Creates an instance of SEALContext and performs several pre-computations + * on the given EncryptionParameters. This function explicitly allows insecure parameters, + * and is only for testing! + * + * * `params` - The encryption parameters. + * * `expand_mod_chain` - Determines whether the modulus switching chain + * should be created. + */ + #[cfg(feature = "insecure-params")] + pub fn new_insecure(params: &EncryptionParameters, expand_mod_chain: bool) -> Result { + let mut handle: *mut c_void = null_mut(); + + convert_seal_error(unsafe { + bindgen::SEALContext_Create(params.get_handle(), expand_mod_chain, 0, &mut handle) + })?; + + Ok(Context { handle }) + } + /** * Returns handle to the underlying SEAL object. */ diff --git a/sunscreen/Cargo.toml b/sunscreen/Cargo.toml index 2c830a687..e1b620a74 100644 --- a/sunscreen/Cargo.toml +++ b/sunscreen/Cargo.toml @@ -58,6 +58,7 @@ proptest = { workspace = true } rand = { workspace = true } sunscreen_zkp_backend = { workspace = true, features = ["bulletproofs"] } sunscreen_compiler_common = { workspace = true } +sunscreen_runtime = { workspace = true, features = ["insecure-params"] } serde_json = { workspace = true } [features] diff --git a/sunscreen/tests/linked.rs b/sunscreen/tests/linked.rs index 017257934..77131b072 100644 --- a/sunscreen/tests/linked.rs +++ b/sunscreen/tests/linked.rs @@ -1,6 +1,7 @@ #[cfg(feature = "linkedproofs")] mod linked_tests { use lazy_static::lazy_static; + use logproof::rings::SealQ128_1024; use num::Rational64; use sunscreen::types::bfv::{Rational, Signed, Unsigned64}; use sunscreen::types::zkp::{AsFieldElement, BfvRational, BfvSigned, BulletproofsField}; @@ -15,10 +16,10 @@ mod linked_tests { use sunscreen_zkp_backend::bulletproofs::BulletproofsBackend; lazy_static! { - static ref SMALL_PARAMS: Params = Params { - lattice_dimension: 1024, - coeff_modulus: vec![0x7e00001], - plain_modulus: 4_096, + static ref TEST_PARAMS: Params = Params { + lattice_dimension: 128, + coeff_modulus: SealQ128_1024::Q.to_vec(), + plain_modulus: 32, scheme_type: SchemeType::Bfv, security_level: sunscreen::SecurityLevel::TC128, }; @@ -45,7 +46,7 @@ mod linked_tests { fn test_valid_transaction_example() { let app = Compiler::new() .fhe_program(doggie) - .with_params(&SMALL_PARAMS) + .with_params(&TEST_PARAMS) .zkp_backend::() .zkp_program(valid_transaction) .compile() @@ -90,7 +91,7 @@ mod linked_tests { fn test_invalid_transaction_example() { let app = Compiler::new() .fhe_program(doggie) - .with_params(&SMALL_PARAMS) + .with_params(&TEST_PARAMS) .zkp_backend::() .zkp_program(valid_transaction) .compile() @@ -127,7 +128,7 @@ mod linked_tests { fn test_signed_encoding() { let app = Compiler::new() .fhe_program(doggie) - .with_params(&SMALL_PARAMS) + .with_params(&TEST_PARAMS) .zkp_backend::() .zkp_program(is_eq_signed) .compile() @@ -178,7 +179,7 @@ mod linked_tests { fn test_rational_encoding() { let app = Compiler::new() .fhe_program(doggie) - .with_params(&SMALL_PARAMS) + .with_params(&TEST_PARAMS) .zkp_backend::() .zkp_program(is_eq_rational) .compile() @@ -221,7 +222,7 @@ mod linked_tests { fn can_compare_signed() { let app = Compiler::new() .fhe_program(doggie) - .with_params(&SMALL_PARAMS) + .with_params(&TEST_PARAMS) .zkp_backend::() .zkp_program(compare_signed) .compile() @@ -270,7 +271,7 @@ mod linked_tests { fn can_compare_rationals() { let app = Compiler::new() .fhe_program(doggie) - .with_params(&SMALL_PARAMS) + .with_params(&TEST_PARAMS) .zkp_backend::() .zkp_program(compare_rational) .compile() @@ -326,7 +327,7 @@ mod linked_tests { // proves equivalence of pt x, pt y, and field elem z within ZKP let app = Compiler::new() .fhe_program(doggie) - .with_params(&SMALL_PARAMS) + .with_params(&TEST_PARAMS) .zkp_backend::() .zkp_program(is_eq_3) .compile() @@ -385,7 +386,7 @@ mod linked_tests { let is_eq_zkp = app.get_zkp_program(is_eq_signed).unwrap(); // but use runtime with modulus 4096 - let rt = FheZkpRuntime::new(&SMALL_PARAMS, &BulletproofsBackend::new()).unwrap(); + let rt = FheZkpRuntime::new(&TEST_PARAMS, &BulletproofsBackend::new()).unwrap(); let mut proof_builder = LogProofBuilder::new(&rt); let res = proof_builder.zkp_program(is_eq_zkp); @@ -400,7 +401,7 @@ mod linked_tests { fn test_case(num_linked_inputs: usize, num_private_inputs: usize) { let app = Compiler::new() .fhe_program(doggie) - .with_params(&SMALL_PARAMS) + .with_params(&TEST_PARAMS) .zkp_backend::() .zkp_program(is_eq_3) .compile() @@ -436,7 +437,7 @@ mod linked_tests { fn throws_linked_arg_type_mismatch() { let app = Compiler::new() .fhe_program(doggie) - .with_params(&SMALL_PARAMS) + .with_params(&TEST_PARAMS) .zkp_backend::() .zkp_program(compare_signed) .compile() diff --git a/sunscreen/tests/sdlp.rs b/sunscreen/tests/sdlp.rs index 375acc587..388f06535 100644 --- a/sunscreen/tests/sdlp.rs +++ b/sunscreen/tests/sdlp.rs @@ -1,16 +1,17 @@ #[cfg(feature = "linkedproofs")] mod sdlp_tests { use lazy_static::lazy_static; - use sunscreen::types::bfv::Signed; + use logproof::rings::SealQ128_1024; + use sunscreen::types::bfv::{Signed, Unsigned64}; use sunscreen_fhe_program::SchemeType; use sunscreen_runtime::{FheRuntime, LogProofBuilder, Params}; lazy_static! { - static ref SMALL_PARAMS: Params = Params { - lattice_dimension: 1024, - coeff_modulus: vec![0x7e00001], - plain_modulus: 4_096, + static ref TEST_PARAMS: Params = Params { + lattice_dimension: 128, + coeff_modulus: SealQ128_1024::Q.to_vec(), + plain_modulus: 32, scheme_type: SchemeType::Bfv, security_level: sunscreen::SecurityLevel::TC128, }; @@ -18,7 +19,7 @@ mod sdlp_tests { #[test] fn prove_one_asymmetric_statement() { - let rt = FheRuntime::new(&SMALL_PARAMS).unwrap(); + let rt = FheRuntime::new(&TEST_PARAMS).unwrap(); let (public_key, _secret_key) = rt.generate_keys().unwrap(); let mut logproof_builder = LogProofBuilder::new(&rt); @@ -32,12 +33,12 @@ mod sdlp_tests { #[test] fn prove_one_symmetric_statement() { - let rt = FheRuntime::new(&SMALL_PARAMS).unwrap(); + let rt = FheRuntime::new(&TEST_PARAMS).unwrap(); let (_public_key, private_key) = rt.generate_keys().unwrap(); let mut logproof_builder = LogProofBuilder::new(&rt); let _ct = logproof_builder - .encrypt_symmetric(&Signed::from(3), &private_key) + .encrypt_symmetric(&Unsigned64::from(3), &private_key) .unwrap(); let sdlp = logproof_builder.build_logproof().unwrap(); @@ -46,7 +47,7 @@ mod sdlp_tests { #[test] fn prove_linked_statements() { - let rt = FheRuntime::new(&SMALL_PARAMS).unwrap(); + let rt = FheRuntime::new(&TEST_PARAMS).unwrap(); let (public_key, private_key) = rt.generate_keys().unwrap(); let mut logproof_builder = LogProofBuilder::new(&rt); diff --git a/sunscreen_runtime/Cargo.toml b/sunscreen_runtime/Cargo.toml index dd32c8dd4..c47b8bf9a 100644 --- a/sunscreen_runtime/Cargo.toml +++ b/sunscreen_runtime/Cargo.toml @@ -52,3 +52,4 @@ linkedproofs = [ "dep:paste", ] deterministic = ["seal_fhe/deterministic"] +insecure-params = ["seal_fhe/insecure-params"] diff --git a/sunscreen_runtime/src/builder.rs b/sunscreen_runtime/src/builder.rs index 90e9425da..f1ac8719b 100644 --- a/sunscreen_runtime/src/builder.rs +++ b/sunscreen_runtime/src/builder.rs @@ -219,7 +219,6 @@ mod linked { rings::{SealQ128_1024, SealQ128_2048, SealQ128_4096, SealQ128_8192}, Bounds, LogProofProverKnowledge, }; - use seal_fhe::SecurityLevel; use sunscreen_compiler_common::{Type, TypeName}; use sunscreen_math::ring::{BarrettBackend, BarrettConfig, Zq}; use sunscreen_zkp_backend::{ @@ -594,17 +593,17 @@ mod linked { fn build_sdlp_pk(&self) -> Result { let params = self.runtime.params(); - match (params.lattice_dimension, params.security_level) { - (1024, SecurityLevel::TC128) => Ok(SealSdlpProverKnowledge::from( + match ¶ms.coeff_modulus[..] { + SealQ128_1024::Q => Ok(SealSdlpProverKnowledge::from( self.build_sdlp_pk_generic::<1, SealQ128_1024>()?, )), - (2048, SecurityLevel::TC128) => Ok(SealSdlpProverKnowledge::from( + SealQ128_2048::Q => Ok(SealSdlpProverKnowledge::from( self.build_sdlp_pk_generic::<1, SealQ128_2048>()?, )), - (4096, SecurityLevel::TC128) => Ok(SealSdlpProverKnowledge::from( + SealQ128_4096::Q => Ok(SealSdlpProverKnowledge::from( self.build_sdlp_pk_generic::<2, SealQ128_4096>()?, )), - (8192, SecurityLevel::TC128) => Ok(SealSdlpProverKnowledge::from( + SealQ128_8192::Q => Ok(SealSdlpProverKnowledge::from( self.build_sdlp_pk_generic::<3, SealQ128_8192>()?, )), _ => Err(BuilderError::UnsupportedParameters(Box::new(params.clone())).into()), diff --git a/sunscreen_runtime/src/runtime.rs b/sunscreen_runtime/src/runtime.rs index 00ce10350..2e7158839 100644 --- a/sunscreen_runtime/src/runtime.rs +++ b/sunscreen_runtime/src/runtime.rs @@ -840,6 +840,10 @@ impl GenericRuntime<(), ()> { ) .build()?; + #[cfg(feature = "insecure-params")] + let context = SealContext::new_insecure(&bfv_params, true)?; + + #[cfg(not(feature = "insecure-params"))] let context = SealContext::new(&bfv_params, true, params.security_level)?; Ok(FheRuntimeData {