From 4589a341b4307c91087c10be6fa717c493992513 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Thu, 22 Jan 2026 20:22:10 +0100 Subject: [PATCH 01/19] bootstrap e3-fhe-params crate --- Cargo.lock | 15 +- Cargo.toml | 2 + crates/bfv-helpers/Cargo.toml | 3 +- crates/bfv-helpers/src/client.rs | 18 +- crates/bfv-helpers/src/lib.rs | 684 +----------------- crates/bfv-helpers/src/utils/greco.rs | 8 +- .../src/merkle_tree_builder.rs | 2 +- crates/fhe-params/Cargo.toml | 19 + crates/fhe-params/src/builder.rs | 262 +++++++ crates/fhe-params/src/constants.rs | 81 +++ crates/fhe-params/src/encoding.rs | 294 ++++++++ crates/fhe-params/src/lib.rs | 15 + crates/fhe-params/src/presets.rs | 390 ++++++++++ crates/fhe/src/fhe.rs | 2 +- crates/indexer/tests/integration.rs | 4 +- crates/support/host/src/bin/profile_risc0.rs | 6 +- crates/test-helpers/src/bin/fake_encrypt.rs | 10 +- crates/test-helpers/src/lib.rs | 4 +- crates/trbfv/src/helpers.rs | 4 +- crates/trbfv/src/trbfv_config.rs | 2 +- crates/wasm/src/lib.rs | 15 +- examples/CRISP/Cargo.lock | 15 +- .../CRISP/crates/crisp-constants/src/lib.rs | 4 +- packages/enclave-react/src/useEnclaveSDK.ts | 6 +- packages/enclave-sdk/src/enclave-sdk.ts | 20 +- packages/enclave-sdk/src/index.ts | 3 +- packages/enclave-sdk/src/types.ts | 66 +- packages/enclave-sdk/src/utils.ts | 40 +- packages/enclave-sdk/tests/sdk.test.ts | 4 +- .../src/pages/steps/RequestComputation.tsx | 3 +- .../default/client/src/utils/sdk-config.ts | 4 +- templates/default/program/src/lib.rs | 5 +- templates/default/server/index.ts | 4 +- templates/default/tests/integration.spec.ts | 4 +- 34 files changed, 1205 insertions(+), 813 deletions(-) create mode 100644 crates/fhe-params/Cargo.toml create mode 100644 crates/fhe-params/src/builder.rs create mode 100644 crates/fhe-params/src/constants.rs create mode 100644 crates/fhe-params/src/encoding.rs create mode 100644 crates/fhe-params/src/lib.rs create mode 100644 crates/fhe-params/src/presets.rs diff --git a/Cargo.lock b/Cargo.lock index 7937229399..e3df0e8236 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2760,9 +2760,8 @@ dependencies = [ name = "e3-bfv-helpers" version = "0.1.7" dependencies = [ - "alloy-dyn-abi", - "alloy-primitives", "anyhow", + "e3-fhe-params", "fhe", "fhe-math", "fhe-traits", @@ -3056,6 +3055,18 @@ dependencies = [ "tracing", ] +[[package]] +name = "e3-fhe-params" +version = "0.1.7" +dependencies = [ + "alloy-dyn-abi", + "alloy-primitives", + "fhe", + "num-bigint", + "thiserror 1.0.69", + "zkfhe-shared", +] + [[package]] name = "e3-fs" version = "0.1.7" diff --git a/Cargo.toml b/Cargo.toml index 4bb2a832ba..15d0db39fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ members = [ "crates/evm", "crates/evm-helpers", "crates/fhe", + "crates/fhe-params", "crates/fs", "crates/indexer", "crates/init", @@ -78,6 +79,7 @@ e3-events = { version = "0.1.7", path = "./crates/events" } e3-evm = { version = "0.1.7", path = "./crates/evm" } e3-evm-helpers = { version = "0.1.7", path = "./crates/evm-helpers" } e3-fhe = { version = "0.1.7", path = "./crates/fhe" } +e3-fhe-params = { version = "0.1.7", path = "./crates/fhe-params" } e3-fs = { version = "0.1.7", path = "./crates/fs" } e3-indexer = { version = "0.1.7", path = "./crates/indexer" } e3-multithread = { version = "0.1.7", path = "./crates/multithread" } diff --git a/crates/bfv-helpers/Cargo.toml b/crates/bfv-helpers/Cargo.toml index 9f3113408d..ae6ba4f0e4 100644 --- a/crates/bfv-helpers/Cargo.toml +++ b/crates/bfv-helpers/Cargo.toml @@ -7,9 +7,8 @@ description = "E3 - Enclave BFV Helpers" repository = "https://github.com/gnosisguild/enclave/crates/bfv-helpers" [dependencies] -alloy-dyn-abi = { workspace = true } -alloy-primitives = { workspace = true } anyhow.workspace = true +e3-fhe-params = { workspace = true, features = ["abi-encoding"] } fhe-math = { git = "https://github.com/gnosisguild/fhe.rs" } fhe-traits.workspace = true fhe-util = { git = "https://github.com/gnosisguild/fhe.rs" } diff --git a/crates/bfv-helpers/src/client.rs b/crates/bfv-helpers/src/client.rs index d740fd4c0d..f76df5bad6 100644 --- a/crates/bfv-helpers/src/client.rs +++ b/crates/bfv-helpers/src/client.rs @@ -209,7 +209,7 @@ pub fn compute_ct_commitment( #[cfg(test)] mod tests { - use crate::BfvParamSets; + use crate::{BfvParamSet, BfvPreset}; use super::*; @@ -219,11 +219,11 @@ mod tests { use fhe::bfv::{Ciphertext, PublicKey, SecretKey}; use fhe_traits::{DeserializeParametrized, FheDecrypter, Serialize}; - let param_set = BfvParamSets::InsecureSet2048_1032193_1.into(); + let param_set: BfvParamSet = BfvPreset::InsecureThresholdBfv512.into(); let params = build_bfv_params_from_set_arc(param_set); let degree = param_set.degree; let plaintext_modulus = param_set.plaintext_modulus; - let moduli = [param_set.moduli[0]]; + let moduli = param_set.moduli; let mut rng = thread_rng(); let sk = SecretKey::random(¶ms, &mut rng); let pk = PublicKey::new(&sk, &mut rng); @@ -244,11 +244,11 @@ mod tests { use fhe::bfv::{Ciphertext, PublicKey, SecretKey}; use fhe_traits::{DeserializeParametrized, FheDecrypter, Serialize}; - let param_set = BfvParamSets::InsecureSet2048_1032193_1.into(); + let param_set: BfvParamSet = BfvPreset::InsecureThresholdBfv512.into(); let params = build_bfv_params_from_set_arc(param_set); let degree = param_set.degree; let plaintext_modulus = param_set.plaintext_modulus; - let moduli = [param_set.moduli[0]]; + let moduli = param_set.moduli; let mut rng = thread_rng(); let sk = SecretKey::random(¶ms, &mut rng); let pk = PublicKey::new(&sk, &mut rng); @@ -276,11 +276,11 @@ mod tests { use fhe::bfv::{Ciphertext, PublicKey, SecretKey}; use fhe_traits::{DeserializeParametrized, FheDecrypter, Serialize}; - let param_set = BfvParamSets::InsecureSet2048_1032193_1.into(); + let param_set: BfvParamSet = BfvPreset::InsecureThresholdBfv512.into(); let params = build_bfv_params_from_set_arc(param_set); let degree = param_set.degree; let plaintext_modulus = param_set.plaintext_modulus; - let moduli = [param_set.moduli[0]]; + let moduli = param_set.moduli; let mut rng = thread_rng(); let sk = SecretKey::random(¶ms, &mut rng); let pk = PublicKey::new(&sk, &mut rng); @@ -307,11 +307,11 @@ mod tests { use fhe::bfv::{Ciphertext, PublicKey, SecretKey}; use fhe_traits::{DeserializeParametrized, FheDecrypter, Serialize}; - let param_set = BfvParamSets::InsecureSet2048_1032193_1.into(); + let param_set: BfvParamSet = BfvPreset::InsecureThresholdBfv512.into(); let params = build_bfv_params_from_set_arc(param_set); let degree = param_set.degree; let plaintext_modulus = param_set.plaintext_modulus; - let moduli = [param_set.moduli[0]]; + let moduli = param_set.moduli; let mut rng = thread_rng(); let sk = SecretKey::random(¶ms, &mut rng); let pk = PublicKey::new(&sk, &mut rng); diff --git a/crates/bfv-helpers/src/lib.rs b/crates/bfv-helpers/src/lib.rs index 92c0fbcb1d..8cdd84e720 100644 --- a/crates/bfv-helpers/src/lib.rs +++ b/crates/bfv-helpers/src/lib.rs @@ -7,452 +7,30 @@ pub mod client; pub mod utils; -use alloy_dyn_abi::{DynSolType, DynSolValue}; -use alloy_primitives::U256; -use fhe::bfv::{BfvParameters, BfvParametersBuilder, Encoding, Plaintext}; +use fhe::bfv::{Encoding, Plaintext}; use fhe_traits::FheDecoder; -use std::sync::Arc; -use strum::{EnumIter, EnumString, IntoEnumIterator, IntoStaticStr}; use thiserror::Error as ThisError; +pub use e3_fhe_params::{ + build_bfv_params, build_bfv_params_arc, build_bfv_params_from_set, + build_bfv_params_from_set_arc, BfvParamSet, BfvPreset, PresetError, PresetMetadata, + PresetSearchDefaults, +}; +pub use e3_fhe_params::{ + decode_bfv_params, decode_bfv_params_arc, encode_bfv_params, EncodingError, +}; + #[derive(ThisError, Debug)] pub enum Error { #[error("Plaintext decoding failed")] PlaintextDecodeFailed, - // TODO: add errors from client.rs #[error("Input was not encoded correctly")] BadEncoding, - #[error("Unknown parameter set: {0}")] - UnknownParamSet(String), } /// Result that returns a type T or a BfvHelpersError type Result = std::result::Result; -#[derive(Debug, Clone, Copy, EnumString, IntoStaticStr, EnumIter)] -#[strum(serialize_all = "SCREAMING_SNAKE_CASE")] -/// Predefined BFV parameters for common use cases -/// Note that 10 is the default value for both error1 and error2 variance -/// for both BFV and TRBFV (if not explicitly set). -pub enum BfvParamSets { - // List parameter strings and variants here - // - /// Standard BFV development parameters set (DO NOT USE IN PRODUCTION). - /// - Degree: 2048 (polynomial ring size) - /// - Plaintext modulus: 1032193 - /// - Moduli: [0x3FFFFFFF000001] (provides good security level) - #[strum(serialize = "INSECURE_SET_2048_1032193_1")] - InsecureSet2048_1032193_1, - - /// Testing TrBFV development parameters set (DO NOT USE IN PRODUCTION). - /// - Degree: 512 - /// - Moduli: [0xffffee001, 0xffffc4001] - /// - Plaintext modulus: 10 - /// - Error2 Variance: 3 - #[strum(serialize = "INSECURE_SET_512_10_1")] - InsecureSet512_10_1, - - /// Testing BFV development parameters for share encryption (DO NOT USE IN PRODUCTION). - /// - Degree: 512 - /// - Moduli: [0x7fffffffe0001] - /// - Plaintext modulus: 0xffffee001 - /// - Error2 Variance: 3 - #[strum(serialize = "INSECURE_SET_512_0XFFFFEE001_1")] - InsecureSet512_0xffffee001_1, - - /// 128bits security TRBFV parameters set (PRODUCTION READY). - /// - Degree: 8192 - /// - Plaintext modulus: 1000 - /// - Moduli: [0x00800000022a0001, 0x00800000021a0001, 0x0080000002120001, 0x0080000001f60001] - /// - Error2 Variance: 52309181128222339698631578526730685514457152477762943514050560000 - #[strum(serialize = "SET_8192_1000_4")] - Set8192_1000_4, - - /// 128bits security BFV parameters set (PRODUCTION READY). - /// - Degree: 8192 - /// - Plaintext modulus: 100 - /// - Moduli: [0x0008000000820001, 0x0010000000060001, 0x00100000003e0001, 0x00100000006e0001] - /// - Error2 Variance: 1004336277661868922213726307713258317841382576849282939643494400 - #[strum(serialize = "SET_8192_100_4")] - Set8192_100_4, - - /// 128bits security BFV parameters set (PRODUCTION READY). - /// - Degree: 8192 - /// - Plaintext modulus: 144115188075855872 - /// - Moduli: [288230376173076481, 288230376167047169] - #[strum(serialize = "SET_8192_144115188075855872_2")] - Set8192_144115188075855872_2, -} - -// Map for getters -impl BfvParamSets { - /// Return the given param set based on the input key &str. - pub fn get_params_by_str(key: &str) -> Result { - key.parse::() - .map(|k| k.into()) - .map_err(|_| Error::UnknownParamSet(key.to_string())) - } - - /// List all the available parameter keys - pub fn get_params_list() -> Vec { - BfvParamSets::iter() - .map(|key| { - let s: &'static str = key.into(); - s.to_string() - }) - .collect() - } -} - -impl From for BfvParamSet { - fn from(value: BfvParamSets) -> Self { - use BfvParamSets as B; - match value { - // List each new parameter set here - B::InsecureSet2048_1032193_1 => BfvParamSet { - degree: 2048, - plaintext_modulus: 1032193, - moduli: &[0x3FFFFFFF000001], - error1_variance: None, - }, - B::InsecureSet512_10_1 => BfvParamSet { - degree: 512, - moduli: &[0xffffee001, 0xffffc4001], - plaintext_modulus: 10, - error1_variance: Some("3"), - }, - B::InsecureSet512_0xffffee001_1 => BfvParamSet { - degree: 512, - moduli: &[0x7fffffffe0001], - plaintext_modulus: 0xffffee001, - error1_variance: None, - }, - B::Set8192_1000_4 => BfvParamSet { - degree: 8192, - plaintext_modulus: 1000, - moduli: &[ - 0x00800000022a0001, - 0x00800000021a0001, - 0x0080000002120001, - 0x0080000001f60001, - ], - error1_variance: Some( - "52309181128222339698631578526730685514457152477762943514050560000", - ), - }, - B::Set8192_100_4 => BfvParamSet { - degree: 8192, - plaintext_modulus: 100, - moduli: &[ - 0x0008000000820001, - 0x0010000000060001, - 0x00100000003e0001, - 0x00100000006e0001, - ], - error1_variance: Some( - "1004336277661868922213726307713258317841382576849282939643494400", - ), - }, - B::Set8192_144115188075855872_2 => BfvParamSet { - degree: 8192, - plaintext_modulus: 144115188075855872, - moduli: &[288230376173076481, 288230376167047169], - error1_variance: None, - }, - } - } -} - -/// A consistent type representing a BFV parameter set. -/// -/// This struct provides a uniform way to represent BFV parameter sets, -/// making it easy to consume them with functions like `build_bfv_params_from_set`. -#[derive(Debug, Clone, Copy)] -pub struct BfvParamSet { - /// The degree of the polynomial ring, must be a power of 2 - pub degree: usize, - /// The modulus for the plaintext space - pub plaintext_modulus: u64, - /// The moduli for the ciphertext space - pub moduli: &'static [u64], - /// Optional error2 variance (as decimal string). If None, defaults to "10" - pub error1_variance: Option<&'static str>, -} - -impl BfvParamSet { - /// Build the BfvParamSet into an fhe.rs BfvParameters struct - pub fn build(self) -> BfvParameters { - build_bfv_params_from_set(self) - } - - /// Build the BfvParamSet into an fhe.rs Arc struct - pub fn build_arc(self) -> Arc { - Arc::new(self.build()) - } -} - -/// Builds BFV parameters from a `BfvParamSet`. -/// -/// This is a convenience function that consumes a `BfvParamSet` struct -/// and builds the corresponding `BfvParameters` instance. -/// -/// # Arguments -/// -/// * `param_set` - A `BfvParamSet` containing the degree, plaintext modulus, moduli, and optional error2 variance -/// -/// # Returns -/// -/// Returns a `BfvParameters` instance configured with the specified parameters. -pub fn build_bfv_params_from_set(param_set: BfvParamSet) -> BfvParameters { - build_bfv_params( - param_set.degree, - param_set.plaintext_modulus, - param_set.moduli, - param_set.error1_variance, - ) -} - -/// Builds BFV parameters from a `BfvParamSet` wrapped in an `Arc`. -/// -/// This is a convenience function that consumes a `BfvParamSet` struct -/// and builds the corresponding `Arc` instance for thread-safe shared ownership. -/// -/// # Arguments -/// -/// * `param_set` - A `BfvParamSet` containing the degree, plaintext modulus, moduli, and optional error2 variance -/// -/// # Returns -/// -/// Returns an `Arc` instance configured with the specified parameters. -pub fn build_bfv_params_from_set_arc(param_set: BfvParamSet) -> Arc { - build_bfv_params_arc( - param_set.degree, - param_set.plaintext_modulus, - param_set.moduli, - param_set.error1_variance, - ) -} - -/// Builds BFV (Brakerski-Fan-Vercauteren) encryption parameters. -/// -/// This function supports both standard BFV and threshold BFV (trBFV) parameters. -/// If `error1_variance` is not provided (None), it defaults to "10", which matches -/// the default variance value for standard BFV. -/// -/// # Arguments -/// -/// * `degree` - The degree of the polynomial ring, must be a power of 2 -/// * `plaintext_modulus` - The modulus for the plaintext space -/// * `moduli` - The moduli for the ciphertext space -/// * `error1_variance` - Optional error2 variance (as decimal string). Defaults to "10" if None. -/// -/// # Returns -/// -/// Returns a `BfvParameters` instance configured with the specified parameters. -/// -/// # Panics -/// -/// Panics if the parameters cannot be built (e.g., invalid degree or moduli). -pub fn build_bfv_params( - degree: usize, - plaintext_modulus: u64, - moduli: &[u64], - error1_variance: Option<&str>, -) -> BfvParameters { - let mut builder = BfvParametersBuilder::new(); - builder - .set_degree(degree) - .set_plaintext_modulus(plaintext_modulus) - .set_moduli(moduli); - - if let Some(error1) = error1_variance { - builder - .set_error1_variance_str(error1) - .unwrap_or_else(|e| panic!("Failed to set error1_variance: {}", e)); - } - // If error1_variance is None, the builder defaults to 10 - - builder - .build() - .unwrap_or_else(|e| panic!("Failed to build BFV Parameters: {}", e)) -} - -/// Builds BFV encryption parameters wrapped in an `Arc` for shared ownership. -/// -/// This function is similar to `build_bfv_params` but returns the parameters -/// wrapped in an `Arc` for thread-safe shared ownership. -/// -/// # Arguments -/// -/// * `degree` - The degree of the polynomial ring, must be a power of 2 -/// * `plaintext_modulus` - The modulus for the plaintext space -/// * `moduli` - The moduli for the ciphertext space -/// * `error1_variance` - Optional error2 variance (as decimal string). Defaults to "10" if None. -/// -/// # Returns -/// -/// Returns an `Arc` instance configured with the specified parameters. -/// -/// # Panics -/// -/// Panics if the parameters cannot be built (e.g., invalid degree or moduli). -pub fn build_bfv_params_arc( - degree: usize, - plaintext_modulus: u64, - moduli: &[u64], - error1_variance: Option<&str>, -) -> Arc { - let mut builder = BfvParametersBuilder::new(); - builder - .set_degree(degree) - .set_plaintext_modulus(plaintext_modulus) - .set_moduli(moduli); - - if let Some(error1) = error1_variance { - builder - .set_error1_variance_str(error1) - .unwrap_or_else(|e| panic!("Failed to set error1_variance: {}", e)); - } - // If error1_variance is None, the builder defaults to 10 - - builder - .build_arc() - .unwrap_or_else(|e| panic!("Failed to build BFV Parameters wrapped in Arc: {}", e)) -} - -/// Encodes BFV parameters into ABI-encoded bytes. -/// -/// This function converts BFV parameters into a tuple structure of (degree, plaintext_modulus, moduli[], error1_variance) -/// and then ABI-encodes the tuple using Solidity ABI format. The resulting bytes can be used -/// in smart contracts or for cross-platform serialization. -/// # Arguments -/// -/// * `params` - The BFV parameters to encode -/// -/// # Returns -/// -/// Returns a `Vec` containing the ABI-encoded parameters as a tuple (uint256, uint256, uint256[], string). -pub fn encode_bfv_params(params: &BfvParameters) -> Vec { - let value = DynSolValue::Tuple(vec![ - DynSolValue::Uint(U256::from(params.degree()), 256), - DynSolValue::Uint(U256::from(params.plaintext()), 256), - DynSolValue::Array( - params - .moduli() - .iter() - .map(|val| DynSolValue::Uint(U256::from(*val), 256)) - .collect(), - ), - DynSolValue::String(params.get_error1_variance().to_string()), - ]); - value.abi_encode() -} - -/// Decodes BFV parameters from ABI-encoded bytes. -/// -/// This function converts ABI-encoded bytes back into BFV parameters. -/// The bytes should represent a tuple (uint256, uint256, uint256[], string) containing -/// (degree, plaintext_modulus, moduli[], error1_variance) as produced by `encode_bfv_params`. -/// -/// # Arguments -/// -/// * `bytes` - The ABI-encoded bytes containing the encoded parameters -/// -/// # Returns -/// -/// Returns a `BfvParameters` instance decoded from the bytes. -/// -/// # Panics -/// -/// Panics if the decoding fails due to invalid format or parameter values. -pub fn decode_bfv_params(bytes: &[u8]) -> BfvParameters { - // Define the expected tuple type: (uint256, uint256, uint256[], string) - let tuple_type = DynSolType::Tuple(vec![ - DynSolType::Uint(256), // degree - DynSolType::Uint(256), // plaintext_modulus - DynSolType::Array(Box::new(DynSolType::Uint(256))), // moduli array - DynSolType::String, // error1_variance (as decimal string) - ]); - - let decoded = tuple_type - .abi_decode(bytes) - .expect("Failed to ABI decode bytes"); - - match decoded { - DynSolValue::Tuple(inner_values) => { - // Extract degree (first element) - let degree: u64 = match &inner_values[0] { - DynSolValue::Uint(val, _) => { - (*val).try_into().expect("Failed to convert degree to u64") - } - _ => panic!("Expected uint256 for degree"), - }; - - // Extract plaintext modulus (second element) - let plaintext: u64 = match &inner_values[1] { - DynSolValue::Uint(val, _) => (*val) - .try_into() - .expect("Failed to convert plaintext to u64"), - _ => panic!("Expected uint256 for plaintext modulus"), - }; - - // Extract moduli array (third element) - let moduli: Vec = match &inner_values[2] { - DynSolValue::Array(moduli_array) => moduli_array - .iter() - .map(|val| match val { - DynSolValue::Uint(modulus, _) => (*modulus) - .try_into() - .expect("Failed to convert modulus to u64"), - _ => panic!("Expected uint256 for modulus value"), - }) - .collect::>(), - _ => panic!("Expected array for moduli"), - }; - - // Extract error1_variance (fourth element) - let error1_variance: String = match &inner_values[3] { - DynSolValue::String(val) => val.clone(), - _ => panic!("Expected string for error1_variance"), - }; - - let params = BfvParametersBuilder::new() - .set_degree(degree as usize) - .set_plaintext_modulus(plaintext) - .set_moduli(&moduli) - .set_error1_variance_str(&error1_variance) - .unwrap_or_else(|e| panic!("Failed to set error1_variance: {}", e)) - .build() - .unwrap_or_else(|e| panic!("Failed to build BFV Parameters: {}", e)); - - params - } - _ => panic!("Expected tuple value in ABI encoding"), - } -} - -/// Decodes BFV parameters from ABI-encoded bytes and wraps them in an `Arc`. -/// -/// This is a convenience function that combines `decode_bfv_params` with `Arc::new` -/// to provide thread-safe shared ownership of the decoded parameters. -/// The input bytes should represent a tuple (uint256, uint256, uint256[], string) containing -/// (degree, plaintext_modulus, moduli[], error1_variance) in ABI-encoded format. -/// -/// # Arguments -/// -/// * `bytes` - The ABI-encoded bytes containing the encoded parameters -/// -/// # Returns -/// -/// Returns an `Arc` instance decoded from the bytes. -/// -/// # Panics -/// -/// Panics if the decoding fails (see `decode_bfv_params`). -pub fn decode_bfv_params_arc(bytes: &[u8]) -> Arc { - Arc::new(decode_bfv_params(bytes)) -} - /// Decode Plaintext to a Vec pub fn decode_plaintext_to_vec_u64(value: &Plaintext) -> Result> { let decoded = Vec::::try_decode(&value, Encoding::poly()) @@ -481,245 +59,3 @@ pub fn decode_bytes_to_vec_u64(bytes: &[u8]) -> Result> { .map(|chunk| u64::from_le_bytes(chunk.try_into().unwrap())) .collect()) } - -#[cfg(test)] -mod tests { - use super::*; - use num_bigint::BigUint; - use std::str::FromStr; - - #[test] - fn test_build_bfv_params() { - let degree = 2048; - let plaintext_modulus = 1032193; - let moduli = [0x3FFFFFFF000001]; - - let params = build_bfv_params(degree, plaintext_modulus, &moduli, None); - assert_eq!(params.degree(), degree); - assert_eq!(params.plaintext(), plaintext_modulus); - assert_eq!(params.moduli(), moduli); - assert_eq!(params.variance(), 10); - assert_eq!(params.get_error1_variance(), &BigUint::from(10u32)); - } - - #[test] - fn test_build_bfv_params_arc() { - let degree = 2048; - let plaintext_modulus = 1032193; - let moduli = [0x3FFFFFFF000001]; - - let params = build_bfv_params_arc(degree, plaintext_modulus, &moduli, None); - assert_eq!(params.degree(), degree); - assert_eq!(params.plaintext(), plaintext_modulus); - assert_eq!(params.moduli(), moduli); - assert_eq!(params.variance(), 10); - assert_eq!(params.get_error1_variance(), &BigUint::from(10u32)); - } - - #[test] - fn test_build_trbfv_params() { - let degree = 8192; - let plaintext_modulus = 1000; - let moduli = [ - 0x00800000022a0001, - 0x00800000021a0001, - 0x0080000002120001, - 0x0080000001f60001, - ]; - let error1_variance = "52309181128222339698631578526730685514457152477762943514050560000"; - - let params = build_bfv_params(degree, plaintext_modulus, &moduli, Some(error1_variance)); - assert_eq!(params.degree(), degree); - assert_eq!(params.plaintext(), plaintext_modulus); - assert_eq!(params.moduli(), moduli); - assert_eq!(params.variance(), 10); - assert_eq!( - params.get_error1_variance(), - &BigUint::from_str(error1_variance).unwrap() - ); - } - - #[test] - fn test_build_trbfv_params_arc() { - let degree = 8192; - let plaintext_modulus = 1000; - let moduli = [ - 0x00800000022a0001, - 0x00800000021a0001, - 0x0080000002120001, - 0x0080000001f60001, - ]; - let error1_variance = "52309181128222339698631578526730685514457152477762943514050560000"; - - let params = - build_bfv_params_arc(degree, plaintext_modulus, &moduli, Some(error1_variance)); - assert_eq!(params.degree(), degree); - assert_eq!(params.plaintext(), plaintext_modulus); - assert_eq!(params.moduli(), moduli); - assert_eq!(params.variance(), 10); - assert_eq!( - params.get_error1_variance(), - &BigUint::from_str(error1_variance).unwrap() - ); - } - - #[test] - fn test_encoding_roundtrip() { - let degree = 2048; - let plaintext_modulus = 1032193; - let moduli = vec![0x3FFFFFFF000001]; - - let params = build_bfv_params(degree, plaintext_modulus, &moduli, None); - let encoded = encode_bfv_params(¶ms); - let decoded = decode_bfv_params(&encoded); - - assert_eq!(decoded.degree(), degree); - assert_eq!(decoded.plaintext(), plaintext_modulus); - assert_eq!(decoded.moduli(), moduli.as_slice()); - // Verify error1_variance is preserved (defaults to 10 for standard BFV) - assert_eq!(decoded.get_error1_variance(), params.get_error1_variance()); - } - - #[test] - fn test_encoding_deterministic() { - let degree = 2048; - let plaintext_modulus = 1032193; - let moduli = vec![0x3FFFFFFF000001]; - - let params = build_bfv_params(degree, plaintext_modulus, &moduli, None); - - // Verify the encoding result is deterministic - let encoded1 = encode_bfv_params(¶ms); - let encoded2 = encode_bfv_params(¶ms); - assert_eq!(encoded1, encoded2, "ABI encoding should be deterministic"); - } - - #[test] - fn test_encoding_roundtrip_arc() { - let degree = 2048; - let plaintext_modulus = 1032193; - let moduli = vec![0x3FFFFFFF000001]; - - let params = build_bfv_params(degree, plaintext_modulus, &moduli, None); - let encoded = encode_bfv_params(¶ms); - - // Verify we can decode back to the original parameters with Arc - let decoded = decode_bfv_params_arc(&encoded); - assert_eq!(decoded.degree(), degree); - assert_eq!(decoded.plaintext(), plaintext_modulus); - assert_eq!(decoded.moduli(), moduli.as_slice()); - // Verify error1_variance is preserved - assert_eq!(decoded.get_error1_variance(), params.get_error1_variance()); - } - - #[test] - fn test_encoding_roundtrip_trbfv() { - let degree = 8192; - let plaintext_modulus = 1000; - let moduli = [ - 0x00800000022a0001, - 0x00800000021a0001, - 0x0080000002120001, - 0x0080000001f60001, - ]; - let error1_variance = "52309181128222339698631578526730685514457152477762943514050560000"; - - let params = build_bfv_params(degree, plaintext_modulus, &moduli, Some(error1_variance)); - let encoded = encode_bfv_params(¶ms); - let decoded = decode_bfv_params(&encoded); - - assert_eq!(decoded.degree(), degree); - assert_eq!(decoded.plaintext(), plaintext_modulus); - assert_eq!(decoded.moduli(), moduli); - // Verify error1_variance is preserved for trBFV - assert_eq!( - decoded.get_error1_variance(), - &BigUint::from_str(error1_variance).unwrap() - ); - } - - #[test] - #[should_panic(expected = "Failed to ABI decode bytes")] - fn test_decode_bfv_params_error() { - let invalid_bytes = vec![0u8; 10]; - let _ = decode_bfv_params(&invalid_bytes); - } - - #[cfg(test)] - mod params_tests { - use super::*; - - #[test] - fn test_params_constant() { - let param_set: BfvParamSet = BfvParamSets::InsecureSet2048_1032193_1.into(); - assert_eq!(param_set.degree, 2048); - assert_eq!(param_set.plaintext_modulus, 1032193); - assert_eq!(param_set.moduli, &[0x3FFFFFFF000001]); - } - - #[test] - fn test_params_function() { - let param_set = BfvParamSets::InsecureSet2048_1032193_1.into(); - let params = build_bfv_params_from_set(param_set); - - assert_eq!(params.degree(), param_set.degree); - assert_eq!(params.plaintext(), param_set.plaintext_modulus); - assert_eq!(params.moduli(), param_set.moduli); - } - - #[test] - fn test_params_arc_function() { - let param_set = BfvParamSets::InsecureSet2048_1032193_1.into(); - let params = build_bfv_params_from_set_arc(param_set); - - assert_eq!(params.degree(), param_set.degree); - assert_eq!(params.plaintext(), param_set.plaintext_modulus); - assert_eq!(params.moduli(), param_set.moduli); - } - - #[test] - fn test_params_encoding_roundtrip() { - let param_set = BfvParamSets::InsecureSet2048_1032193_1.into(); - let params = build_bfv_params_from_set(param_set); - let encoded = encode_bfv_params(¶ms); - let decoded = decode_bfv_params(&encoded); - - assert_eq!(decoded.degree(), param_set.degree); - assert_eq!(decoded.plaintext(), param_set.plaintext_modulus); - assert_eq!(decoded.moduli(), param_set.moduli); - // Verify error1_variance is preserved - assert_eq!(decoded.get_error1_variance(), params.get_error1_variance()); - } - - #[test] - fn test_params_arc_encoding_roundtrip() { - let param_set = BfvParamSets::InsecureSet2048_1032193_1.into(); - let params = build_bfv_params_from_set_arc(param_set); - let encoded = encode_bfv_params(¶ms); - let decoded = decode_bfv_params_arc(&encoded); - - assert_eq!(decoded.degree(), param_set.degree); - assert_eq!(decoded.plaintext(), param_set.plaintext_modulus); - assert_eq!(decoded.moduli(), param_set.moduli); - // Verify error1_variance is preserved - assert_eq!(decoded.get_error1_variance(), params.get_error1_variance()); - } - - #[test] - fn test_params_trbfv_encoding_roundtrip() { - let param_set = BfvParamSets::Set8192_1000_4.into(); - let params = build_bfv_params_from_set(param_set); - let encoded = encode_bfv_params(¶ms); - let decoded = decode_bfv_params(&encoded); - - assert_eq!(decoded.degree(), param_set.degree); - assert_eq!(decoded.plaintext(), param_set.plaintext_modulus); - assert_eq!(decoded.moduli(), param_set.moduli); - // Verify error1_variance is preserved for trBFV - assert_eq!( - decoded.get_error1_variance(), - &BigUint::from_str(param_set.error1_variance.unwrap()).unwrap() - ); - } - } -} diff --git a/crates/bfv-helpers/src/utils/greco.rs b/crates/bfv-helpers/src/utils/greco.rs index 247e535de2..82d8683db6 100644 --- a/crates/bfv-helpers/src/utils/greco.rs +++ b/crates/bfv-helpers/src/utils/greco.rs @@ -178,8 +178,8 @@ mod tests { #[test] fn test_bfv_public_key_to_greco() { - use crate::{BfvParamSet, BfvParamSets}; - let params = BfvParamSet::from(BfvParamSets::InsecureSet512_10_1).build_arc(); + use crate::{BfvParamSet, BfvPreset}; + let params = BfvParamSet::from(BfvPreset::InsecureThresholdBfv512).build_arc(); let mut rng = thread_rng(); let sk = SecretKey::random(¶ms, &mut rng); @@ -267,8 +267,8 @@ mod tests { #[test] fn test_bfv_ciphertext_to_greco() { - use crate::{BfvParamSet, BfvParamSets}; - let params = BfvParamSet::from(BfvParamSets::InsecureSet512_10_1).build_arc(); + use crate::{BfvParamSet, BfvPreset}; + let params = BfvParamSet::from(BfvPreset::InsecureThresholdBfv512).build_arc(); let mut rng = thread_rng(); let sk = SecretKey::random(¶ms, &mut rng); diff --git a/crates/compute-provider/src/merkle_tree_builder.rs b/crates/compute-provider/src/merkle_tree_builder.rs index a5914801b5..9384948181 100644 --- a/crates/compute-provider/src/merkle_tree_builder.rs +++ b/crates/compute-provider/src/merkle_tree_builder.rs @@ -36,7 +36,7 @@ impl MerkleTreeBuilder { } pub fn compute_leaf_hashes(&mut self, data: &[(Vec, u64)], params_bytes: &[u8]) { - let params = decode_bfv_params(params_bytes); + let params = decode_bfv_params(params_bytes).expect("Failed to decode BFV params"); let degree = params.degree(); let plaintext_modulus = params.plaintext(); let moduli = params.moduli().to_vec(); diff --git a/crates/fhe-params/Cargo.toml b/crates/fhe-params/Cargo.toml new file mode 100644 index 0000000000..e36478a590 --- /dev/null +++ b/crates/fhe-params/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "e3-fhe-params" +version.workspace = true +edition.workspace = true +license.workspace = true +description = "E3 - Enclave FHE Params" +repository = "https://github.com/gnosisguild/enclave/crates/fhe-params" + +[dependencies] +fhe = { workspace = true } +num-bigint = { workspace = true } +thiserror = { workspace = true } +shared = { package = "zkfhe-shared", git = "https://github.com/gnosisguild/zkfhe-generator" } +alloy-dyn-abi = { workspace = true, optional = true } +alloy-primitives = { workspace = true, optional = true } + +[features] +default = [] +abi-encoding = ["dep:alloy-dyn-abi", "dep:alloy-primitives"] diff --git a/crates/fhe-params/src/builder.rs b/crates/fhe-params/src/builder.rs new file mode 100644 index 0000000000..1308762255 --- /dev/null +++ b/crates/fhe-params/src/builder.rs @@ -0,0 +1,262 @@ +use crate::constants::{insecure_512, secure_8192}; +use crate::presets::{BfvParamSet, BfvPreset, PresetError}; +use fhe::bfv::{BfvParameters, BfvParametersBuilder}; +use num_bigint::BigUint; +use std::sync::Arc; + +pub fn build_pair_for_preset( + preset: BfvPreset, +) -> Result<(Arc, Arc), PresetError> { + match preset { + BfvPreset::InsecureThresholdBfv512 => { + let params_trbfv = BfvParametersBuilder::new() + .set_degree(insecure_512::DEGREE) + .set_plaintext_modulus(insecure_512::threshold::PLAINTEXT_MODULUS) + .set_moduli(insecure_512::threshold::MODULI) + .set_error1_variance(BigUint::from( + insecure_512::threshold::ERROR1_VARIANCE_BIGUINT, + )) + .build_arc() + .unwrap(); + + let params_bfv = BfvParametersBuilder::new() + .set_degree(insecure_512::DEGREE) + .set_plaintext_modulus(insecure_512::dkg::PLAINTEXT_MODULUS) + .set_moduli(insecure_512::dkg::MODULI) + .set_variance(insecure_512::dkg::VARIANCE as usize) + .build_arc() + .unwrap(); + + Ok((params_trbfv, params_bfv)) + } + BfvPreset::SecureThresholdBfv8192 => { + let params_trbfv = BfvParametersBuilder::new() + .set_degree(secure_8192::DEGREE) + .set_plaintext_modulus(secure_8192::threshold::PLAINTEXT_MODULUS) + .set_moduli(secure_8192::threshold::MODULI) + .set_error1_variance_str(secure_8192::threshold::ERROR1_VARIANCE) + .unwrap() + .build_arc() + .unwrap(); + + let params_bfv = BfvParametersBuilder::new() + .set_degree(secure_8192::DEGREE) + .set_plaintext_modulus(secure_8192::dkg::BFV_PLAINTEXT_MODULUS) + .set_moduli(secure_8192::dkg::BFV_MODULI) + .build_arc() + .unwrap(); + + Ok((params_trbfv, params_bfv)) + } + other => Err(PresetError::MissingPair(other.name())), + } +} + +pub fn build_bfv_params_from_set(param_set: BfvParamSet) -> BfvParameters { + build_bfv_params( + param_set.degree, + param_set.plaintext_modulus, + param_set.moduli, + param_set.error1_variance, + ) +} + +pub fn build_bfv_params_from_set_arc(param_set: BfvParamSet) -> Arc { + build_bfv_params_arc( + param_set.degree, + param_set.plaintext_modulus, + param_set.moduli, + param_set.error1_variance, + ) +} + +pub fn build_bfv_params( + degree: usize, + plaintext_modulus: u64, + moduli: &[u64], + error1_variance: Option<&str>, +) -> BfvParameters { + let mut builder = BfvParametersBuilder::new(); + builder + .set_degree(degree) + .set_plaintext_modulus(plaintext_modulus) + .set_moduli(moduli); + + if let Some(error1) = error1_variance { + builder + .set_error1_variance_str(error1) + .unwrap_or_else(|e| panic!("Failed to set error1_variance: {}", e)); + } + + builder + .build() + .unwrap_or_else(|e| panic!("Failed to build BFV Parameters: {}", e)) +} + +pub fn build_bfv_params_arc( + degree: usize, + plaintext_modulus: u64, + moduli: &[u64], + error1_variance: Option<&str>, +) -> Arc { + let mut builder = BfvParametersBuilder::new(); + builder + .set_degree(degree) + .set_plaintext_modulus(plaintext_modulus) + .set_moduli(moduli); + + if let Some(error1) = error1_variance { + builder + .set_error1_variance_str(error1) + .unwrap_or_else(|e| panic!("Failed to set error1_variance: {}", e)); + } + + builder + .build_arc() + .unwrap_or_else(|e| panic!("Failed to build BFV Parameters wrapped in Arc: {}", e)) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::constants::{defaults, insecure_512, secure_8192}; + use crate::presets::BfvPreset; + use num_bigint::BigUint; + use std::str::FromStr; + + #[test] + fn test_build_bfv_params_insecure_dkg() { + // Test building BFV params using insecure DKG preset constants + let degree = insecure_512::DEGREE; + let plaintext_modulus = insecure_512::dkg::PLAINTEXT_MODULUS; + let moduli = insecure_512::dkg::MODULI; + + let params = build_bfv_params(degree, plaintext_modulus, moduli, None); + assert_eq!(params.degree(), degree); + assert_eq!(params.plaintext(), plaintext_modulus); + assert_eq!(params.moduli(), moduli); + assert_eq!(params.variance(), defaults::VARIANCE); + assert_eq!( + params.get_error1_variance(), + &BigUint::from(defaults::ERROR1_VARIANCE) + ); + } + + #[test] + fn test_build_bfv_params_arc_insecure_dkg() { + // Test building Arc using insecure DKG preset constants + let degree = insecure_512::DEGREE; + let plaintext_modulus = insecure_512::dkg::PLAINTEXT_MODULUS; + let moduli = insecure_512::dkg::MODULI; + + let params = build_bfv_params_arc(degree, plaintext_modulus, moduli, None); + assert_eq!(params.degree(), degree); + assert_eq!(params.plaintext(), plaintext_modulus); + assert_eq!(params.moduli(), moduli); + assert_eq!(params.variance(), defaults::VARIANCE); + assert_eq!( + params.get_error1_variance(), + &BigUint::from(defaults::ERROR1_VARIANCE) + ); + } + + #[test] + fn test_build_trbfv_params_secure_threshold() { + // Test building TRBFV params using secure threshold preset constants + let degree = secure_8192::DEGREE; + let plaintext_modulus = secure_8192::threshold::PLAINTEXT_MODULUS; + let moduli = secure_8192::threshold::MODULI; + let error1_variance = secure_8192::threshold::ERROR1_VARIANCE; + + let params = build_bfv_params(degree, plaintext_modulus, moduli, Some(error1_variance)); + assert_eq!(params.degree(), degree); + assert_eq!(params.plaintext(), plaintext_modulus); + assert_eq!(params.moduli(), moduli); + assert_eq!(params.variance(), defaults::VARIANCE); + assert_eq!( + params.get_error1_variance(), + &BigUint::from_str(error1_variance).unwrap() + ); + } + + #[test] + fn test_build_trbfv_params_arc_secure_threshold() { + // Test building Arc using secure threshold preset constants + let degree = secure_8192::DEGREE; + let plaintext_modulus = secure_8192::threshold::PLAINTEXT_MODULUS; + let moduli = secure_8192::threshold::MODULI; + let error1_variance = secure_8192::threshold::ERROR1_VARIANCE; + + let params = build_bfv_params_arc(degree, plaintext_modulus, moduli, Some(error1_variance)); + assert_eq!(params.degree(), degree); + assert_eq!(params.plaintext(), plaintext_modulus); + assert_eq!(params.moduli(), moduli); + assert_eq!(params.variance(), defaults::VARIANCE); + assert_eq!( + params.get_error1_variance(), + &BigUint::from_str(error1_variance).unwrap() + ); + } + + #[test] + fn test_build_bfv_params_from_set_insecure_dkg() { + // Test building from BfvParamSet using insecure DKG preset + let preset = BfvPreset::InsecureDkg512; + let param_set = preset.into(); + let params = build_bfv_params_from_set(param_set); + + assert_eq!(params.degree(), insecure_512::DEGREE); + assert_eq!(params.plaintext(), insecure_512::dkg::PLAINTEXT_MODULUS); + assert_eq!(params.moduli(), insecure_512::dkg::MODULI); + } + + #[test] + fn test_build_bfv_params_from_set_arc_insecure_dkg() { + // Test building Arc from BfvParamSet using insecure DKG preset + let preset = BfvPreset::InsecureDkg512; + let param_set = preset.into(); + let params = build_bfv_params_from_set_arc(param_set); + + assert_eq!(params.degree(), insecure_512::DEGREE); + assert_eq!(params.plaintext(), insecure_512::dkg::PLAINTEXT_MODULUS); + assert_eq!(params.moduli(), insecure_512::dkg::MODULI); + } + + #[test] + fn test_build_bfv_params_from_set_secure_threshold() { + // Test building from BfvParamSet using secure threshold preset + let preset = BfvPreset::SecureThresholdBfv8192; + let param_set = preset.into(); + let params = build_bfv_params_from_set(param_set); + + assert_eq!(params.degree(), secure_8192::DEGREE); + assert_eq!( + params.plaintext(), + secure_8192::threshold::PLAINTEXT_MODULUS + ); + assert_eq!(params.moduli(), secure_8192::threshold::MODULI); + assert_eq!( + params.get_error1_variance(), + &BigUint::from_str(secure_8192::threshold::ERROR1_VARIANCE).unwrap() + ); + } + + #[test] + fn test_build_bfv_params_from_set_arc_secure_threshold() { + // Test building Arc from BfvParamSet using secure threshold preset + let preset = BfvPreset::SecureThresholdBfv8192; + let param_set = preset.into(); + let params = build_bfv_params_from_set_arc(param_set); + + assert_eq!(params.degree(), secure_8192::DEGREE); + assert_eq!( + params.plaintext(), + secure_8192::threshold::PLAINTEXT_MODULUS + ); + assert_eq!(params.moduli(), secure_8192::threshold::MODULI); + assert_eq!( + params.get_error1_variance(), + &BigUint::from_str(secure_8192::threshold::ERROR1_VARIANCE).unwrap() + ); + } +} diff --git a/crates/fhe-params/src/constants.rs b/crates/fhe-params/src/constants.rs new file mode 100644 index 0000000000..bab8940af9 --- /dev/null +++ b/crates/fhe-params/src/constants.rs @@ -0,0 +1,81 @@ +//! Constants for BFV presets +//! +//! This module contains all hardcoded values used in preset definitions. +//! Centralizing these values makes it easier to maintain and update presets. + +/// Insecure preset constants (degree 512) - DO NOT USE IN PRODUCTION +pub mod insecure_512 { + pub const DEGREE: usize = 512; + pub const NUM_PARTIES: u128 = 5; + + /// Threshold BFV (TRBFV) parameters + pub mod threshold { + pub const PLAINTEXT_MODULUS: u64 = 10; + pub const MODULI: &[u64] = &[0xffffee001, 0xffffc4001]; + pub const ERROR1_VARIANCE: &str = "3"; + pub const ERROR1_VARIANCE_BIGUINT: u32 = 3; + + /// Search defaults for insecure threshold BFV + pub const SEARCH_N: u128 = 5; + pub const SEARCH_K: u128 = 1000; + pub const SEARCH_Z: u128 = 1000; + } + + /// DKG parameters + pub mod dkg { + pub const PLAINTEXT_MODULUS: u64 = 0xffffee001; + pub const MODULI: &[u64] = &[0x7fffffffe0001]; + pub const ERROR1_VARIANCE: Option<&str> = None; + pub const VARIANCE: u32 = 3; + } +} + +/// Secure preset constants (degree 8192) - PRODUCTION READY +pub mod secure_8192 { + pub const DEGREE: usize = 8192; + pub const NUM_PARTIES: u128 = 100; + + /// Threshold BFV (TRBFV) parameters + pub mod threshold { + pub const PLAINTEXT_MODULUS: u64 = 100; + pub const MODULI: &[u64] = &[ + 0x0008000000820001, + 0x0010000000060001, + 0x00100000003e0001, + 0x00100000006e0001, + ]; + pub const ERROR1_VARIANCE: &str = + "1004336277661868922213726307713258317841382576849282939643494400"; + + /// Search defaults for secure threshold BFV + pub const SEARCH_N: u128 = 100; + pub const SEARCH_K: u128 = 100; + pub const SEARCH_Z: u128 = 100; + } + + /// DKG parameters + pub mod dkg { + pub const PLAINTEXT_MODULUS: u64 = 144115188075855872; + pub const MODULI: &[u64] = &[288230376173076481, 288230376167047169]; + pub const ERROR1_VARIANCE: Option<&str> = None; + + /// BFV plaintext modulus for pair building + pub const BFV_PLAINTEXT_MODULUS: u64 = 18014398509481984; + pub const BFV_MODULI: &[u64] = &[0x0100000002a20001, 0x0100000001760001]; + } +} + +/// Common search defaults shared across presets +pub mod search_defaults { + pub const B: u128 = 20; + pub const B_CHI: u128 = 1; +} + +/// Default values for BFV parameters +pub mod defaults { + /// Default variance for BFV parameters when not explicitly set + /// This is the standard default variance (and error1_variance) used in BFV + /// when variance is not specified. Both variance() and error1_variance default to this value. + pub const VARIANCE: usize = 10; + pub const ERROR1_VARIANCE: u32 = 10; +} diff --git a/crates/fhe-params/src/encoding.rs b/crates/fhe-params/src/encoding.rs new file mode 100644 index 0000000000..2150227c63 --- /dev/null +++ b/crates/fhe-params/src/encoding.rs @@ -0,0 +1,294 @@ +//! BFV Parameter Encoding/Decoding +//! +//! This module provides functions for encoding and decoding BFV parameters +//! using Solidity ABI format. This enables serialization for smart contracts +//! and cross-platform parameter exchange. + +use fhe::bfv::{BfvParameters, BfvParametersBuilder}; +use std::sync::Arc; +use thiserror::Error as ThisError; + +#[cfg(feature = "abi-encoding")] +use alloy_dyn_abi::{DynSolType, DynSolValue}; +#[cfg(feature = "abi-encoding")] +use alloy_primitives::U256; + +#[derive(ThisError, Debug)] +pub enum EncodingError { + #[error("Failed to ABI decode bytes: {0}")] + AbiDecodeFailed(String), + #[error("Invalid ABI structure: expected tuple")] + InvalidAbiStructure, + #[error("Invalid degree value: {0}")] + InvalidDegree(String), + #[error("Invalid plaintext modulus value: {0}")] + InvalidPlaintextModulus(String), + #[error("Invalid modulus value: {0}")] + InvalidModulus(String), + #[error("Invalid error1_variance: {0}")] + InvalidError1Variance(String), + #[error("Failed to build BFV parameters: {0}")] + BuildFailed(String), +} + +/// Encodes BFV parameters into ABI-encoded bytes. +/// +/// This function converts BFV parameters into a tuple structure of +/// `(degree, plaintext_modulus, moduli[], error1_variance)` and then +/// ABI-encodes the tuple using Solidity ABI format. The resulting bytes +/// can be used in smart contracts or for cross-platform serialization. +#[cfg(feature = "abi-encoding")] +pub fn encode_bfv_params(params: &BfvParameters) -> Vec { + let value = DynSolValue::Tuple(vec![ + DynSolValue::Uint(U256::from(params.degree()), 256), + DynSolValue::Uint(U256::from(params.plaintext()), 256), + DynSolValue::Array( + params + .moduli() + .iter() + .map(|val| DynSolValue::Uint(U256::from(*val), 256)) + .collect(), + ), + DynSolValue::String(params.get_error1_variance().to_string()), + ]); + value.abi_encode() +} + +/// Decodes BFV parameters from ABI-encoded bytes. +/// +/// This function converts ABI-encoded bytes back into BFV parameters. +/// The bytes should represent a tuple `(uint256, uint256, uint256[], string)` +/// containing `(degree, plaintext_modulus, moduli[], error1_variance)` as +/// produced by `encode_bfv_params`. +#[cfg(feature = "abi-encoding")] +pub fn decode_bfv_params(bytes: &[u8]) -> Result { + // Define the expected tuple type: (uint256, uint256, uint256[], string) + let tuple_type = DynSolType::Tuple(vec![ + DynSolType::Uint(256), // degree + DynSolType::Uint(256), // plaintext_modulus + DynSolType::Array(Box::new(DynSolType::Uint(256))), // moduli array + DynSolType::String, // error1_variance (as decimal string) + ]); + + let decoded = tuple_type.abi_decode(bytes).map_err(|e| { + EncodingError::AbiDecodeFailed(format!("Failed to ABI decode bytes: {}", e)) + })?; + + match decoded { + DynSolValue::Tuple(inner_values) => { + // Extract degree (first element) + let degree: u64 = match &inner_values[0] { + DynSolValue::Uint(val, _) => (*val).try_into().map_err(|e| { + EncodingError::InvalidDegree(format!("Failed to convert degree to u64: {}", e)) + })?, + _ => return Err(EncodingError::InvalidAbiStructure), + }; + + // Extract plaintext modulus (second element) + let plaintext: u64 = match &inner_values[1] { + DynSolValue::Uint(val, _) => (*val).try_into().map_err(|e| { + EncodingError::InvalidPlaintextModulus(format!( + "Failed to convert plaintext to u64: {}", + e + )) + })?, + _ => return Err(EncodingError::InvalidAbiStructure), + }; + + // Extract moduli array (third element) + let moduli: Vec = match &inner_values[2] { + DynSolValue::Array(moduli_array) => moduli_array + .iter() + .map(|val| match val { + DynSolValue::Uint(modulus, _) => (*modulus).try_into().map_err(|e| { + EncodingError::InvalidModulus(format!( + "Failed to convert modulus to u64: {}", + e + )) + }), + _ => Err(EncodingError::InvalidAbiStructure), + }) + .collect::, _>>()?, + _ => return Err(EncodingError::InvalidAbiStructure), + }; + + // Extract error1_variance (fourth element) + let error1_variance: String = match &inner_values[3] { + DynSolValue::String(val) => val.clone(), + _ => return Err(EncodingError::InvalidAbiStructure), + }; + + let params = BfvParametersBuilder::new() + .set_degree(degree as usize) + .set_plaintext_modulus(plaintext) + .set_moduli(&moduli) + .set_error1_variance_str(&error1_variance) + .map_err(|e| { + EncodingError::InvalidError1Variance(format!( + "Failed to set error1_variance: {}", + e + )) + })? + .build() + .map_err(|e| { + EncodingError::BuildFailed(format!("Failed to build BFV Parameters: {}", e)) + })?; + + Ok(params) + } + _ => Err(EncodingError::InvalidAbiStructure), + } +} + +/// Decodes BFV parameters from ABI-encoded bytes and wraps them in an `Arc`. +/// +/// This is a convenience function that combines `decode_bfv_params` with `Arc::new` +/// to provide thread-safe shared ownership of the decoded parameters. +#[cfg(feature = "abi-encoding")] +pub fn decode_bfv_params_arc(bytes: &[u8]) -> Result, EncodingError> { + Ok(Arc::new(decode_bfv_params(bytes)?)) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::constants::{defaults, insecure_512, secure_8192}; + use crate::presets::BfvPreset; + + #[cfg(feature = "abi-encoding")] + #[test] + fn test_encode_decode_roundtrip_preset() { + use crate::presets::BfvParamSet; + + let preset = BfvPreset::SecureThresholdBfv8192; + let param_set: BfvParamSet = preset.into(); + let params = param_set.build(); + + let encoded = encode_bfv_params(¶ms); + let decoded = decode_bfv_params(&encoded).expect("should decode successfully"); + + assert_eq!(decoded.degree(), params.degree()); + assert_eq!(decoded.plaintext(), params.plaintext()); + assert_eq!(decoded.moduli(), params.moduli()); + assert_eq!(decoded.get_error1_variance(), params.get_error1_variance()); + } + + #[cfg(feature = "abi-encoding")] + #[test] + fn test_encode_decode_roundtrip_arbitrary() { + use crate::builder::build_bfv_params; + + // Use insecure DKG preset constants for testing arbitrary parameter encoding + let degree = insecure_512::DEGREE; + let plaintext_modulus = insecure_512::dkg::PLAINTEXT_MODULUS; + let moduli = insecure_512::dkg::MODULI; + + let params = build_bfv_params(degree, plaintext_modulus, moduli, None); + let encoded = encode_bfv_params(¶ms); + let decoded = decode_bfv_params(&encoded).expect("should decode successfully"); + + assert_eq!(decoded.degree(), degree); + assert_eq!(decoded.plaintext(), plaintext_modulus); + assert_eq!(decoded.moduli(), moduli); + // Verify error1_variance is preserved (defaults to 10 for standard BFV) + assert_eq!( + decoded.get_error1_variance(), + &num_bigint::BigUint::from(defaults::ERROR1_VARIANCE) + ); + assert_eq!(decoded.get_error1_variance(), params.get_error1_variance()); + } + + #[cfg(feature = "abi-encoding")] + #[test] + fn test_encode_decode_roundtrip_trbfv() { + use crate::builder::build_bfv_params; + use num_bigint::BigUint; + use std::str::FromStr; + + // Use secure threshold preset constants for testing TRBFV parameter encoding + let degree = secure_8192::DEGREE; + let plaintext_modulus = secure_8192::threshold::PLAINTEXT_MODULUS; + let moduli = secure_8192::threshold::MODULI; + let error1_variance = secure_8192::threshold::ERROR1_VARIANCE; + + let params = build_bfv_params(degree, plaintext_modulus, moduli, Some(error1_variance)); + let encoded = encode_bfv_params(¶ms); + let decoded = decode_bfv_params(&encoded).expect("should decode successfully"); + + assert_eq!(decoded.degree(), degree); + assert_eq!(decoded.plaintext(), plaintext_modulus); + assert_eq!(decoded.moduli(), moduli); + // Verify error1_variance is preserved for trBFV + assert_eq!( + decoded.get_error1_variance(), + &BigUint::from_str(error1_variance).unwrap() + ); + } + + #[cfg(feature = "abi-encoding")] + #[test] + fn test_encode_decode_arc_roundtrip() { + use crate::presets::BfvParamSet; + + let preset = BfvPreset::InsecureThresholdBfv512; + let param_set: BfvParamSet = preset.into(); + let params = param_set.build_arc(); + + let encoded = encode_bfv_params(¶ms); + let decoded = decode_bfv_params_arc(&encoded).expect("should decode successfully"); + + assert_eq!(decoded.degree(), params.degree()); + assert_eq!(decoded.plaintext(), params.plaintext()); + assert_eq!(decoded.moduli(), params.moduli()); + assert_eq!(decoded.get_error1_variance(), params.get_error1_variance()); + } + + #[cfg(feature = "abi-encoding")] + #[test] + fn test_encode_decode_arc_roundtrip_arbitrary() { + use crate::builder::build_bfv_params_arc; + + // Use insecure DKG preset constants for testing arbitrary parameter encoding with Arc + let degree = insecure_512::DEGREE; + let plaintext_modulus = insecure_512::dkg::PLAINTEXT_MODULUS; + let moduli = insecure_512::dkg::MODULI; + + let params = build_bfv_params_arc(degree, plaintext_modulus, moduli, None); + let encoded = encode_bfv_params(¶ms); + + // Verify we can decode back to the original parameters with Arc + let decoded = decode_bfv_params_arc(&encoded).expect("should decode successfully"); + assert_eq!(decoded.degree(), degree); + assert_eq!(decoded.plaintext(), plaintext_modulus); + assert_eq!(decoded.moduli(), moduli); + // Verify error1_variance is preserved (defaults to 10 for standard BFV) + assert_eq!( + decoded.get_error1_variance(), + &num_bigint::BigUint::from(defaults::ERROR1_VARIANCE) + ); + assert_eq!(decoded.get_error1_variance(), params.get_error1_variance()); + } + + #[cfg(feature = "abi-encoding")] + #[test] + fn test_encode_deterministic() { + use crate::presets::BfvParamSet; + + let preset = BfvPreset::SecureThresholdBfv8192; + let param_set: BfvParamSet = preset.into(); + let params = param_set.build(); + + let encoded1 = encode_bfv_params(¶ms); + let encoded2 = encode_bfv_params(¶ms); + + assert_eq!(encoded1, encoded2, "ABI encoding should be deterministic"); + } + + #[cfg(feature = "abi-encoding")] + #[test] + fn test_decode_invalid_bytes() { + let invalid_bytes = vec![0u8; 10]; + let result = decode_bfv_params(&invalid_bytes); + assert!(result.is_err()); + } +} diff --git a/crates/fhe-params/src/lib.rs b/crates/fhe-params/src/lib.rs new file mode 100644 index 0000000000..e5d15b7e24 --- /dev/null +++ b/crates/fhe-params/src/lib.rs @@ -0,0 +1,15 @@ +//! Preset definitions and builders for zkFHE parameters. + +pub mod builder; +pub mod constants; +#[cfg(feature = "abi-encoding")] +pub mod encoding; +pub mod presets; + +pub use builder::{ + build_bfv_params, build_bfv_params_arc, build_bfv_params_from_set, + build_bfv_params_from_set_arc, +}; +#[cfg(feature = "abi-encoding")] +pub use encoding::{decode_bfv_params, decode_bfv_params_arc, encode_bfv_params, EncodingError}; +pub use presets::{BfvParamSet, BfvPreset, PresetError, PresetMetadata, PresetSearchDefaults}; diff --git a/crates/fhe-params/src/presets.rs b/crates/fhe-params/src/presets.rs new file mode 100644 index 0000000000..131e82da1c --- /dev/null +++ b/crates/fhe-params/src/presets.rs @@ -0,0 +1,390 @@ +use crate::builder::build_pair_for_preset; +use crate::builder::{build_bfv_params_from_set, build_bfv_params_from_set_arc}; +use crate::constants::{ + insecure_512, + search_defaults::{B, B_CHI}, + secure_8192, +}; +use shared::{SecurityLevel, DEFAULT_INSECURE_LAMBDA, DEFAULT_SECURE_LAMBDA}; +use std::sync::Arc; +use thiserror::Error as ThisError; + +use fhe::bfv::BfvParameters; + +/// BFV preset configurations for PVSS (Public Verifiable Secret Sharing) +/// +/// In the PVSS protocol, two types of BFV parameters are needed: +/// +/// **Threshold BFV Parameters**: Used for the main threshold encryption/decryption operations +/// (Phases 2-3-4). These are the parameters for the threshold public key that users encrypt with, +/// and for threshold decryption where T+1 parties collaborate to decrypt. +/// +/// **DKG Parameters**: Used during Distributed Key Generation (Phases 0-1). Each ciphernode +/// generates a standard (non-threshold) BFV key-pair using these parameters. These keys are +/// used exclusively for encrypting secret shares during DKG, since the threshold public key +/// doesn't exist yet. After DKG completes, these keys are no longer needed. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] +pub enum BfvPreset { + /// Insecure threshold BFV parameters (degree 512) - DO NOT USE IN PRODUCTION + /// + /// Used for threshold encryption (GRECO) and threshold decryption operations. + /// These parameters define the threshold public key that data providers use to encrypt inputs. + InsecureThresholdBfv512, + /// Insecure DKG parameters (degree 512) - DO NOT USE IN PRODUCTION + /// + /// Used during Phase 0-1 (BFV Key Setup and DKG) where each ciphernode generates + /// a standard BFV key-pair to encrypt secret shares. These are temporary keys used + /// only during the key generation process. + InsecureDkg512, + /// Secure threshold BFV parameters (degree 8192) - PRODUCTION READY + /// + /// Used for threshold encryption (GRECO) and threshold decryption operations. + /// These parameters define the threshold public key that data providers use to encrypt inputs. + #[default] + SecureThresholdBfv8192, + /// Secure DKG parameters (degree 8192) - PRODUCTION READY + /// + /// Used during Phase 0-1 (BFV Key Setup and DKG) where each ciphernode generates + /// a standard BFV key-pair to encrypt secret shares. These are temporary keys used + /// only during the key generation process. + SecureDkg8192, +} + +/// Metadata describing a BFV preset configuration +/// +/// This struct contains high-level information about a preset, including +/// its security properties and basic parameter dimensions. +#[derive(Debug, Clone, Copy)] +pub struct PresetMetadata { + /// The canonical name of the preset (e.g., "INSECURE_THRESHOLD_BFV_512") + pub name: &'static str, + /// Security level classification (Secure if λ ≥ 80, Insecure otherwise) + pub security_level: SecurityLevel, + /// LWE dimension (d) - the degree of the polynomial ring, must be a power of 2 + /// + /// This determines the size of the polynomial ring R_q = Z_q[X]/(X^d + 1). + /// Common values are 512, 1024, 2048, 4096, 8192, etc. + pub degree: usize, + /// Number of parties (n) - the number of ciphernodes in the system supported by + /// the preset. + /// + /// This affects the security analysis and noise bounds. + pub num_parties: u128, + /// Statistical security parameter λ (negl(λ) = 2^{-λ}) + /// + /// Higher values provide stronger security guarantees but may require + /// larger parameters. Typically 80 for secure presets, 2 for insecure. + pub lambda: usize, +} + +/// Default search parameters for BFV parameter generation +/// +/// These values are used when searching for optimal BFV parameters using +/// the crypto_params search algorithm. They define the constraints and +/// requirements for parameter selection. +/// +/// See `crypto_params::bfv::BfvSearchConfig` for more details. +#[derive(Debug, Clone, Copy)] +pub struct PresetSearchDefaults { + /// Number of parties (n) - the number of ciphernodes in the system supported by + /// the preset. + /// + /// This parameter affects the security analysis and noise bounds. + pub n: u128, + /// Number of fresh ciphertext additions z + /// + /// Note that the BFV plaintext modulus k will be defined as k = z. + /// This is also equal to k_plain_eff in the search result. + pub z: u128, + /// Plaintext modulus k (plaintext space) + /// + /// The modulus for the plaintext space. Typically set equal to z. + pub k: u128, + /// Statistical Security parameter λ (negl(λ) = 2^{-λ}) + /// + /// Higher values provide stronger security guarantees but may require + /// larger parameters. Typically 80 for secure presets, 2 for insecure. + pub lambda: u32, + /// Bound B on the error distribution ψ + /// + /// Used to generate e1 when encrypting (e.g., 20 for CBD with σ≈3.2). + /// This bound is used in security analysis equations. + pub b: u128, + /// Bound B_χ on the distribution χ + /// + /// Used to generate the secret key sk_i of each party i. + /// This bound is used in security analysis equations. + pub b_chi: u128, +} + +#[derive(ThisError, Debug)] +pub enum PresetError { + #[error("Unknown preset: {0}")] + UnknownPreset(String), + #[error("Preset does not define a TRBFV/BFV pair: {0}")] + MissingPair(&'static str), +} + +/// A complete BFV parameter set definition +/// +/// This struct contains all the values needed to construct a `BfvParameters` +/// instance. It represents a concrete set of cryptographic parameters for +/// building a BFV (Brakerski-Fan-Vercauteren) homomorphic encryption. +#[derive(Debug, Clone, Copy)] +pub struct BfvParamSet { + /// LWE dimension (d) - the degree of the polynomial ring, must be a power of 2 + /// + /// This determines the size of the polynomial ring R_q = Z_q[X]/(X^d + 1). + /// Common values are 512, 1024, 2048, 4096, 8192, etc. + pub degree: usize, + /// Plaintext modulus (k) - the modulus for the plaintext space + /// + /// This defines the range of values that can be encrypted as plaintexts. + /// Plaintexts are elements of the ring Z_k. + pub plaintext_modulus: u64, + /// Ciphertext moduli (q_i) - array of NTT-friendly primes for the ciphertext space + /// + /// These are the moduli used in the Chinese Remainder Theorem (CRT) representation + /// of the ciphertext space. The product q = ∏q_i is the ciphertext modulus. + /// Each prime must be NTT-friendly (typically 40-63 bits) for efficient operations. + pub moduli: &'static [u64], + /// Error1 variance (as decimal string) - variance of the encryption error distribution + /// + /// This is the variance of the error term e0 in the encryption process. + /// If None, defaults to "10" (the standard default for BFV parameters). + /// This value is used in noise analysis and security proofs. + pub error1_variance: Option<&'static str>, +} + +impl BfvParamSet { + pub fn build(self) -> BfvParameters { + build_bfv_params_from_set(self) + } + + pub fn build_arc(self) -> Arc { + build_bfv_params_from_set_arc(self) + } +} + +impl BfvPreset { + pub const ALL: [BfvPreset; 4] = [ + BfvPreset::InsecureThresholdBfv512, + BfvPreset::InsecureDkg512, + BfvPreset::SecureThresholdBfv8192, + BfvPreset::SecureDkg8192, + ]; + + pub const PAIR_PRESETS: [BfvPreset; 2] = [ + BfvPreset::InsecureThresholdBfv512, + BfvPreset::SecureThresholdBfv8192, + ]; + + pub fn from_name(name: &str) -> Result { + let normalized = name.trim().to_ascii_uppercase(); + match normalized.as_str() { + "INSECURE_THRESHOLD_BFV_512" => Ok(Self::InsecureThresholdBfv512), + "INSECURE_DKG_512" => Ok(Self::InsecureDkg512), + "SECURE_THRESHOLD_BFV_8192" => Ok(Self::SecureThresholdBfv8192), + "SECURE_DKG_8192" => Ok(Self::SecureDkg8192), + _ => Err(PresetError::UnknownPreset(name.to_string())), + } + } + + pub fn name(&self) -> &'static str { + match self { + BfvPreset::InsecureThresholdBfv512 => "INSECURE_THRESHOLD_BFV_512", + BfvPreset::InsecureDkg512 => "INSECURE_DKG_512", + BfvPreset::SecureThresholdBfv8192 => "SECURE_THRESHOLD_BFV_8192", + BfvPreset::SecureDkg8192 => "SECURE_DKG_8192", + } + } + + pub fn list() -> Vec<&'static str> { + Self::ALL.iter().map(BfvPreset::name).collect() + } + + pub fn list_pairs() -> Vec<&'static str> { + Self::PAIR_PRESETS.iter().map(BfvPreset::name).collect() + } + + pub fn supports_pair(&self) -> bool { + Self::PAIR_PRESETS.contains(self) + } + + pub fn metadata(&self) -> PresetMetadata { + match self { + BfvPreset::InsecureThresholdBfv512 | BfvPreset::InsecureDkg512 => PresetMetadata { + name: self.name(), + security_level: SecurityLevel::from_lambda(DEFAULT_INSECURE_LAMBDA), + degree: insecure_512::DEGREE, + num_parties: insecure_512::NUM_PARTIES, + lambda: DEFAULT_INSECURE_LAMBDA, + }, + BfvPreset::SecureThresholdBfv8192 | BfvPreset::SecureDkg8192 => PresetMetadata { + name: self.name(), + security_level: SecurityLevel::from_lambda(DEFAULT_SECURE_LAMBDA), + degree: secure_8192::DEGREE, + num_parties: secure_8192::NUM_PARTIES, + lambda: DEFAULT_SECURE_LAMBDA, + }, + } + } + + pub fn search_defaults(&self) -> Option { + match self { + BfvPreset::InsecureThresholdBfv512 => Some(PresetSearchDefaults { + n: insecure_512::threshold::SEARCH_N, + k: insecure_512::threshold::SEARCH_K, + z: insecure_512::threshold::SEARCH_Z, + lambda: DEFAULT_INSECURE_LAMBDA as u32, + b: B, + b_chi: B_CHI, + }), + BfvPreset::SecureThresholdBfv8192 => Some(PresetSearchDefaults { + n: secure_8192::threshold::SEARCH_N, + k: secure_8192::threshold::SEARCH_K, + z: secure_8192::threshold::SEARCH_Z, + lambda: DEFAULT_SECURE_LAMBDA as u32, + b: B, + b_chi: B_CHI, + }), + _ => None, + } + } + + pub fn build_pair(&self) -> Result<(Arc, Arc), PresetError> { + build_pair_for_preset(*self) + } +} + +impl From for BfvParamSet { + fn from(value: BfvPreset) -> Self { + match value { + BfvPreset::InsecureThresholdBfv512 => BfvParamSet { + degree: insecure_512::DEGREE, + moduli: insecure_512::threshold::MODULI, + plaintext_modulus: insecure_512::threshold::PLAINTEXT_MODULUS, + error1_variance: Some(insecure_512::threshold::ERROR1_VARIANCE), + }, + BfvPreset::InsecureDkg512 => BfvParamSet { + degree: insecure_512::DEGREE, + moduli: insecure_512::dkg::MODULI, + plaintext_modulus: insecure_512::dkg::PLAINTEXT_MODULUS, + error1_variance: insecure_512::dkg::ERROR1_VARIANCE, + }, + BfvPreset::SecureThresholdBfv8192 => BfvParamSet { + degree: secure_8192::DEGREE, + plaintext_modulus: secure_8192::threshold::PLAINTEXT_MODULUS, + moduli: secure_8192::threshold::MODULI, + error1_variance: Some(secure_8192::threshold::ERROR1_VARIANCE), + }, + BfvPreset::SecureDkg8192 => BfvParamSet { + degree: secure_8192::DEGREE, + plaintext_modulus: secure_8192::dkg::PLAINTEXT_MODULUS, + moduli: secure_8192::dkg::MODULI, + error1_variance: secure_8192::dkg::ERROR1_VARIANCE, + }, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::constants::{insecure_512, secure_8192}; + + #[test] + fn from_name_accepts_all_presets() { + for preset in BfvPreset::ALL { + let parsed = BfvPreset::from_name(preset.name()).expect("preset should parse"); + assert_eq!(parsed, preset); + } + } + + #[test] + fn build_pair_matches_expected_params() { + let (trbfv, bfv) = BfvPreset::InsecureThresholdBfv512.build_pair().unwrap(); + assert_eq!(trbfv.degree(), insecure_512::DEGREE); + assert_eq!( + trbfv.plaintext(), + insecure_512::threshold::PLAINTEXT_MODULUS + ); + assert_eq!(trbfv.moduli(), insecure_512::threshold::MODULI); + assert_eq!(bfv.degree(), insecure_512::DEGREE); + assert_eq!(bfv.plaintext(), insecure_512::dkg::PLAINTEXT_MODULUS); + assert_eq!(bfv.moduli(), insecure_512::dkg::MODULI); + + let (trbfv, bfv) = BfvPreset::SecureThresholdBfv8192.build_pair().unwrap(); + assert_eq!(trbfv.degree(), secure_8192::DEGREE); + assert_eq!(trbfv.plaintext(), secure_8192::threshold::PLAINTEXT_MODULUS); + assert_eq!(trbfv.moduli(), secure_8192::threshold::MODULI); + assert_eq!(bfv.degree(), secure_8192::DEGREE); + assert_eq!(bfv.plaintext(), secure_8192::dkg::BFV_PLAINTEXT_MODULUS); + assert_eq!(bfv.moduli(), secure_8192::dkg::BFV_MODULI); + } + + #[test] + fn test_param_set_build() { + let preset = BfvPreset::InsecureDkg512; + let param_set: BfvParamSet = preset.into(); + + assert_eq!(param_set.degree, insecure_512::DEGREE); + assert_eq!( + param_set.plaintext_modulus, + insecure_512::dkg::PLAINTEXT_MODULUS + ); + assert_eq!(param_set.moduli, insecure_512::dkg::MODULI); + + let params = param_set.build(); + assert_eq!(params.degree(), param_set.degree); + assert_eq!(params.plaintext(), param_set.plaintext_modulus); + assert_eq!(params.moduli(), param_set.moduli); + } + + #[test] + fn test_param_set_build_arc() { + let preset = BfvPreset::SecureDkg8192; + let param_set: BfvParamSet = preset.into(); + + let params = param_set.build_arc(); + assert_eq!(params.degree(), param_set.degree); + assert_eq!(params.plaintext(), param_set.plaintext_modulus); + assert_eq!(params.moduli(), param_set.moduli); + } + + #[test] + fn test_metadata_values() { + let insecure = BfvPreset::InsecureThresholdBfv512; + let metadata = insecure.metadata(); + assert_eq!(metadata.degree, insecure_512::DEGREE); + assert_eq!(metadata.num_parties, insecure_512::NUM_PARTIES); + assert_eq!(metadata.lambda, shared::DEFAULT_INSECURE_LAMBDA); + + let secure = BfvPreset::SecureThresholdBfv8192; + let metadata = secure.metadata(); + assert_eq!(metadata.degree, secure_8192::DEGREE); + assert_eq!(metadata.num_parties, secure_8192::NUM_PARTIES); + assert_eq!(metadata.lambda, shared::DEFAULT_SECURE_LAMBDA); + } + + #[test] + fn test_search_defaults() { + let preset = BfvPreset::InsecureThresholdBfv512; + let defaults = preset.search_defaults().unwrap(); + assert_eq!(defaults.n, insecure_512::threshold::SEARCH_N); + assert_eq!(defaults.k, insecure_512::threshold::SEARCH_K); + assert_eq!(defaults.z, insecure_512::threshold::SEARCH_Z); + assert_eq!(defaults.lambda, shared::DEFAULT_INSECURE_LAMBDA as u32); + + let preset = BfvPreset::SecureThresholdBfv8192; + let defaults = preset.search_defaults().unwrap(); + assert_eq!(defaults.n, secure_8192::threshold::SEARCH_N); + assert_eq!(defaults.k, secure_8192::threshold::SEARCH_K); + assert_eq!(defaults.z, secure_8192::threshold::SEARCH_Z); + assert_eq!(defaults.lambda, shared::DEFAULT_SECURE_LAMBDA as u32); + + // DKG presets don't have search defaults + assert!(BfvPreset::InsecureDkg512.search_defaults().is_none()); + assert!(BfvPreset::SecureDkg8192.search_defaults().is_none()); + } +} diff --git a/crates/fhe/src/fhe.rs b/crates/fhe/src/fhe.rs index cd2b3507c2..4c4629c32e 100644 --- a/crates/fhe/src/fhe.rs +++ b/crates/fhe/src/fhe.rs @@ -51,7 +51,7 @@ impl Fhe { } pub fn from_encoded(bytes: &[u8], seed: Seed, rng: SharedRng) -> Result { - let params = decode_bfv_params_arc(bytes); + let params = decode_bfv_params_arc(bytes).expect("Failed to decode BFV params"); let crp = create_crp( params.clone(), Arc::new(Mutex::new(ChaCha20Rng::from_seed(seed.into()))), diff --git a/crates/indexer/tests/integration.rs b/crates/indexer/tests/integration.rs index 63f02523fb..7dfa3c7712 100644 --- a/crates/indexer/tests/integration.rs +++ b/crates/indexer/tests/integration.rs @@ -9,7 +9,7 @@ use alloy::{ primitives::{Bytes, FixedBytes, Uint}, sol, }; -use e3_bfv_helpers::{build_bfv_params_from_set_arc, client::compute_pk_commitment, BfvParamSets}; +use e3_bfv_helpers::{build_bfv_params_from_set_arc, client::compute_pk_commitment, BfvPreset}; use e3_evm_helpers::contracts::ReadOnly; use e3_indexer::{DataStore, EnclaveIndexer, InMemoryStore}; use eyre::Result; @@ -43,7 +43,7 @@ async fn test_indexer() -> Result<()> { const THRESHOLD: u64 = 10; const INDEXER_DELAY_MS: u64 = 10; - let param_set = BfvParamSets::InsecureSet2048_1032193_1.into(); + let param_set = BfvPreset::InsecureThresholdBfv512.into(); let params = build_bfv_params_from_set_arc(param_set); let ( diff --git a/crates/support/host/src/bin/profile_risc0.rs b/crates/support/host/src/bin/profile_risc0.rs index bc664f4c1c..fe371340eb 100644 --- a/crates/support/host/src/bin/profile_risc0.rs +++ b/crates/support/host/src/bin/profile_risc0.rs @@ -4,7 +4,7 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use e3_bfv_helpers::{build_bfv_params_from_set_arc, encode_bfv_params, BfvParamSets}; +use e3_bfv_helpers::{build_bfv_params_from_set_arc, encode_bfv_params, BfvPreset}; use e3_compute_provider::FHEInputs; use e3_support_host::run_risc0_compute; use fhe::bfv::{Encoding, Plaintext, PublicKey, SecretKey}; @@ -14,8 +14,8 @@ use rand::thread_rng; fn main() { println!("Starting RISC0 profiling with mock ciphertexts..."); - // Use InsecureSet512_10_1 parameter set - let param_set = BfvParamSets::InsecureSet512_10_1.into(); + // Use InsecureThresholdBfv512 parameter set + let param_set = BfvPreset::InsecureThresholdBfv512.into(); let params = build_bfv_params_from_set_arc(param_set); println!( diff --git a/crates/test-helpers/src/bin/fake_encrypt.rs b/crates/test-helpers/src/bin/fake_encrypt.rs index 517d6340b9..bd302023e6 100644 --- a/crates/test-helpers/src/bin/fake_encrypt.rs +++ b/crates/test-helpers/src/bin/fake_encrypt.rs @@ -6,14 +6,12 @@ // This is a test script designed to encrypt some fixed data to a fhe public key use clap::Parser; -use e3_sdk::bfv_helpers::build_bfv_params_from_set_arc; -use e3_sdk::bfv_helpers::decode_bfv_params; -use e3_sdk::bfv_helpers::BfvParamSets; +use e3_sdk::bfv_helpers::{build_bfv_params_from_set_arc, decode_bfv_params_arc, BfvPreset}; use fhe::bfv::{Encoding, Plaintext, PublicKey}; use fhe_traits::{DeserializeParametrized, FheEncoder, FheEncrypter, Serialize}; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; -use std::{fs, sync::Arc}; +use std::fs; #[derive(Debug, Clone)] struct HexBytes(pub Vec); @@ -53,9 +51,9 @@ fn main() -> Result<(), Box> { println!("Loading public key from {}", args.input); let bytes = fs::read(&args.input)?; let params = if let Some(params_bytes) = args.params { - Arc::new(decode_bfv_params(¶ms_bytes.0)) + decode_bfv_params_arc(¶ms_bytes.0).expect("Failed to decode BFV params") } else { - build_bfv_params_from_set_arc(BfvParamSets::InsecureSet2048_1032193_1.into()) + build_bfv_params_from_set_arc(BfvPreset::InsecureThresholdBfv512.into()) }; let pubkey = PublicKey::from_bytes(&bytes, ¶ms)?; let raw_plaintext = args.plaintext; diff --git a/crates/test-helpers/src/lib.rs b/crates/test-helpers/src/lib.rs index 8f7540e14c..fe3eb1fa64 100644 --- a/crates/test-helpers/src/lib.rs +++ b/crates/test-helpers/src/lib.rs @@ -20,7 +20,7 @@ use e3_events::{ }; use e3_fhe::{create_crp, setup_crp_params, ParamsWithCrp}; use e3_net::{DocumentPublisher, NetEventTranslator}; -use e3_sdk::bfv_helpers::{BfvParamSet, BfvParamSets}; +use e3_sdk::bfv_helpers::{BfvParamSet, BfvPreset}; use e3_utils::SharedRng; use fhe::bfv::{BfvParameters, Ciphertext, Encoding, Plaintext, PublicKey}; use fhe::mbfv::CommonRandomPoly; @@ -88,7 +88,7 @@ pub fn get_common_setup( let rng = create_shared_rng_from_u64(42); let seed = create_seed_from_u64(123); - let param_set = param_set.unwrap_or(BfvParamSets::InsecureSet2048_1032193_1.into()); + let param_set = param_set.unwrap_or(BfvPreset::InsecureThresholdBfv512.into()); let degree = param_set.degree; let plaintext_modulus = param_set.plaintext_modulus; let moduli = param_set.moduli; diff --git a/crates/trbfv/src/helpers.rs b/crates/trbfv/src/helpers.rs index 484d5264cd..d878bc5b79 100644 --- a/crates/trbfv/src/helpers.rs +++ b/crates/trbfv/src/helpers.rs @@ -6,7 +6,7 @@ use crate::shares::ShamirShare; use anyhow::Result; -use e3_bfv_helpers::BfvParamSets; +use e3_bfv_helpers::{BfvParamSet, BfvPreset}; use e3_crypto::{Cipher, SensitiveBytes}; use fhe::mbfv::PublicKeyShare; use fhe::{ @@ -45,7 +45,7 @@ pub fn deserialize_secret_key(bytes: &[u8], params: &Arc) -> Resu /// TODO: Make this modular pub fn get_share_encryption_params() -> Arc { - let param_set: e3_bfv_helpers::BfvParamSet = BfvParamSets::Set8192_144115188075855872_2.into(); + let param_set: BfvParamSet = BfvPreset::SecureThresholdBfv8192.into(); param_set.build_arc() } diff --git a/crates/trbfv/src/trbfv_config.rs b/crates/trbfv/src/trbfv_config.rs index 8c574153ee..203b1174ae 100644 --- a/crates/trbfv/src/trbfv_config.rs +++ b/crates/trbfv/src/trbfv_config.rs @@ -32,7 +32,7 @@ impl TrBFVConfig { } pub fn params(&self) -> Arc { - decode_bfv_params_arc(&self.params) + decode_bfv_params_arc(&self.params).expect("Failed to decode BFV params") } pub fn num_parties(&self) -> u64 { diff --git a/crates/wasm/src/lib.rs b/crates/wasm/src/lib.rs index 2de2751d95..9d71fbe096 100644 --- a/crates/wasm/src/lib.rs +++ b/crates/wasm/src/lib.rs @@ -8,7 +8,7 @@ use e3_bfv_helpers::{ client::{ bfv_encrypt, bfv_verifiable_encrypt, compute_pk_commitment as _compute_pk_commitment, }, - BfvParamSet, BfvParamSets, + BfvParamSet, BfvPreset, }; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; @@ -173,7 +173,7 @@ pub fn bfv_verifiable_encrypt_vector( /// Retrieves a BFV parameter set by name. /// /// # Parameters -/// * `name` - Parameter set identifier (e.g., "SET_8192_1000_4") +/// * `name` - Parameter set identifier (e.g., "SECURE_THRESHOLD_BFV_8192") /// /// # Returns /// A JavaScript object with the following structure: @@ -189,8 +189,8 @@ pub fn bfv_verifiable_encrypt_vector( /// # Errors /// Returns error if the parameter set name is invalid or serialization fails. pub fn get_bfv_params(name: &str) -> Result { - let params = - BfvParamSets::get_params_by_str(name).map_err(|e| JsValue::from_str(&e.to_string()))?; + let preset = BfvPreset::from_name(name).map_err(|e| JsValue::from_str(&e.to_string()))?; + let params: BfvParamSet = preset.into(); let js_params = BfvParamSetJs::from(¶ms); let serializer = serde_wasm_bindgen::Serializer::new().serialize_large_number_types_as_bigints(true); @@ -204,10 +204,13 @@ pub fn get_bfv_params(name: &str) -> Result { /// /// # Returns /// Array of parameter set names that can be passed to `get_bfv_params()`. -/// Includes both production-ready sets (e.g., "SET_8192_1000_4") and +/// Includes both production-ready sets (e.g., "SECURE_THRESHOLD_BFV_8192") and /// insecure sets for testing (prefixed with "INSECURE_"). pub fn get_bfv_params_list() -> Vec { - BfvParamSets::get_params_list() + BfvPreset::list() + .into_iter() + .map(|name| name.to_string()) + .collect() } #[derive(Serialize, Deserialize)] diff --git a/examples/CRISP/Cargo.lock b/examples/CRISP/Cargo.lock index b545a2ae44..300005775f 100644 --- a/examples/CRISP/Cargo.lock +++ b/examples/CRISP/Cargo.lock @@ -2385,9 +2385,8 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" name = "e3-bfv-helpers" version = "0.1.7" dependencies = [ - "alloy-dyn-abi", - "alloy-primitives", "anyhow", + "e3-fhe-params", "fhe", "fhe-math", "fhe-traits", @@ -2437,6 +2436,18 @@ dependencies = [ "tracing", ] +[[package]] +name = "e3-fhe-params" +version = "0.1.7" +dependencies = [ + "alloy-dyn-abi", + "alloy-primitives", + "fhe", + "num-bigint", + "thiserror 1.0.69", + "zkfhe-shared", +] + [[package]] name = "e3-indexer" version = "0.1.7" diff --git a/examples/CRISP/crates/crisp-constants/src/lib.rs b/examples/CRISP/crates/crisp-constants/src/lib.rs index bf31a6cb0c..b26aa859df 100644 --- a/examples/CRISP/crates/crisp-constants/src/lib.rs +++ b/examples/CRISP/crates/crisp-constants/src/lib.rs @@ -4,10 +4,10 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use e3_sdk::bfv_helpers::{BfvParamSet, BfvParamSets}; +use e3_sdk::bfv_helpers::{BfvParamSet, BfvPreset}; // This could eventually be set here with an environment var once we allow for dynamic circuit selection. pub fn get_default_paramset() -> BfvParamSet { // NOTE: parameters are insecure. These parameters are mainly for testing and demonstration - BfvParamSets::InsecureSet512_10_1.into() + BfvPreset::InsecureThresholdBfv512.into() } diff --git a/packages/enclave-react/src/useEnclaveSDK.ts b/packages/enclave-react/src/useEnclaveSDK.ts index 13dcea9332..77e8936cb2 100644 --- a/packages/enclave-react/src/useEnclaveSDK.ts +++ b/packages/enclave-react/src/useEnclaveSDK.ts @@ -11,7 +11,7 @@ import { type SDKConfig, type AllEventTypes, type EventCallback, - type FheProtocol, + BfvParamSetType, type ProtocolParams, EnclaveEventType, RegistryEventType, @@ -26,7 +26,7 @@ export interface UseEnclaveSDKConfig { } chainId?: number autoConnect?: boolean - protocol: FheProtocol + protocol: BfvParamSetType protocolParams?: ProtocolParams } @@ -69,7 +69,7 @@ export interface UseEnclaveSDKReturn { * enclave: '0x...', * ciphernodeRegistry: '0x...' * }, - * protocol: EFheProtocol.BFV, + * protocol: BfvParamSetType.DKG, * protocolParams: { * degree: 2048, * plaintextModulus: 1032193n, diff --git a/packages/enclave-sdk/src/enclave-sdk.ts b/packages/enclave-sdk/src/enclave-sdk.ts index a19e98c545..7a1b653b36 100644 --- a/packages/enclave-sdk/src/enclave-sdk.ts +++ b/packages/enclave-sdk/src/enclave-sdk.ts @@ -12,7 +12,7 @@ import initializeWasm from '@enclave-e3/wasm/init' import { CiphernodeRegistryOwnable__factory, Enclave__factory } from '@enclave-e3/contracts/types' import { ContractClient } from './contract-client' import { EventListener } from './event-listener' -import { FheProtocol, EnclaveEventType } from './types' +import { BfvParamSetType, EnclaveEventType } from './types' import { SDKError, isValidAddress } from './utils' import type { @@ -47,7 +47,7 @@ export class EnclaveSDK { private eventListener: EventListener private contractClient: ContractClient private initialized = false - private protocol: FheProtocol + private protocol: BfvParamSetType private protocolParams?: ProtocolParams private publicClient: PublicClient @@ -72,8 +72,8 @@ export class EnclaveSDK { this.eventListener = new EventListener(config.publicClient) this.contractClient = new ContractClient(config.publicClient, config.walletClient, config.contracts) - if (!Object.values(FheProtocol).includes(config.protocol)) { - throw new SDKError(`Invalid protocol: ${config.protocol}`, 'INVALID_PROTOCOL') + if (!Object.values(BfvParamSetType).includes(config.protocol)) { + throw new SDKError(`Invalid BFV parameter set type: ${config.protocol}`, 'INVALID_PARAM_SET_TYPE') } this.protocol = config.protocol @@ -126,10 +126,10 @@ export class EnclaveSDK { } switch (this.protocol) { - case FheProtocol.BFV: - return await this.getBfvParamsSet('INSECURE_SET_2048_1032193_1') - case FheProtocol.TRBFV: - return await this.getBfvParamsSet('INSECURE_SET_512_10_1') + case BfvParamSetType.DKG: + return await this.getBfvParamsSet('INSECURE_DKG_512') + case BfvParamSetType.THRESHOLD: + return await this.getBfvParamsSet('INSECURE_THRESHOLD_BFV_512') } } @@ -513,7 +513,7 @@ export class EnclaveSDK { } privateKey?: `0x${string}` chainId: keyof typeof EnclaveSDK.chains - protocol: FheProtocol + protocol: BfvParamSetType protocolParams?: ProtocolParams }): EnclaveSDK { const chain = EnclaveSDK.chains[options.chainId] @@ -548,4 +548,4 @@ export class EnclaveSDK { protocolParams: options.protocolParams, }) } -} +} \ No newline at end of file diff --git a/packages/enclave-sdk/src/index.ts b/packages/enclave-sdk/src/index.ts index 5f353d3253..3b470965b1 100644 --- a/packages/enclave-sdk/src/index.ts +++ b/packages/enclave-sdk/src/index.ts @@ -40,7 +40,7 @@ export type { } from './types' // enums and constants -export { EnclaveEventType, RegistryEventType, FheProtocol, BfvProtocolParams } from './types' +export { EnclaveEventType, RegistryEventType, BfvParamSetType, BfvProtocolParams } from './types' // Export utilities export { @@ -55,7 +55,6 @@ export { sleep, getCurrentTimestamp, // BFV and E3 utilities - BFV_PARAMS_SET, DEFAULT_COMPUTE_PROVIDER_PARAMS, DEFAULT_E3_CONFIG, encodeBfvParams, diff --git a/packages/enclave-sdk/src/types.ts b/packages/enclave-sdk/src/types.ts index a6979d21ee..35a9bdc8d6 100644 --- a/packages/enclave-sdk/src/types.ts +++ b/packages/enclave-sdk/src/types.ts @@ -50,9 +50,11 @@ export interface SDKConfig { chainId?: number /** - * The protocol to use for the Enclave requests + * The BFV parameter set type to use for FHE operations. + * DKG: Parameters for Distributed Key Generation (PVSS phase) + * THRESHOLD: Parameters for threshold encryption/decryption operations */ - protocol: FheProtocol + protocol: BfvParamSetType /** * The protocol parameters to use for the Enclave requests @@ -262,17 +264,24 @@ export interface VerifiableEncryptionResult { } /** - * The protocol to use for the Enclave requests + * BFV parameter set type for FHE operations. + * + * The protocol is always FHE BFV, but different parameter sets are needed: + * - DKG: Used during Distributed Key Generation (PVSS phase 0-1) where each + * ciphernode generates a standard BFV key-pair to encrypt secret shares. + * - THRESHOLD: Used for threshold encryption/decryption operations (PVSS phase 2-4) + * where the threshold public key is used for encryption and T+1 parties + * collaborate for decryption. */ -export enum FheProtocol { +export enum BfvParamSetType { /** - * The BFV protocol + * DKG parameter set - for Distributed Key Generation phase */ - BFV = 'BFV', + DKG = 'DKG', /** - * The TrBFV protocol + * Threshold parameter set - for threshold encryption/decryption operations */ - TRBFV = 'TRBFV', + THRESHOLD = 'THRESHOLD', } /** @@ -302,42 +311,19 @@ export interface ProtocolParams { } export type ProtocolParamsName = - | 'INSECURE_SET_2048_1032193_1' - | 'INSECURE_SET_512_10_1' - | 'INSECURE_SET_512_0XFFFFEE001_1' - | 'SET_8192_1000_4' - | 'SET_8192_144115188075855872_2' + | 'INSECURE_THRESHOLD_BFV_512' + | 'INSECURE_DKG_512' + | 'SECURE_THRESHOLD_BFV_8192' + | 'SECURE_DKG_8192' /** - * Parameters for the BFV protocol + * Preset identifiers for BFV/TRBFV parameter selection. + * Use these with `EnclaveSDK.getBfvParamsSet()` to fetch the actual parameters. */ export const BfvProtocolParams = { - /** - * Recommended parameters for BFV protocol - * - Degree: 2048 - * - Plaintext modulus: 1032193 - * - Moduli:0x3FFFFFFF000001 - */ - BFV_NORMAL: { - degree: 2048, - plaintextModulus: 1032193n, - moduli: [0x3fffffff000001n], - error1Variance: '10', - } as const satisfies ProtocolParams, - - /** - * Recommended parameters for TrBFV protocol - * - Degree: 8192 - * - Plaintext modulus: 1000 - * - Moduli: [0x00800000022a0001, 0x00800000021a0001, 0x0080000002120001, 0x0080000001f60001] - */ - BFV_THRESHOLD: { - degree: 8192, - plaintextModulus: 1000n, - moduli: [0x00800000022a0001n, 0x00800000021a0001n, 0x0080000002120001n, 0x0080000001f60001n], - error1Variance: '10', - } as const satisfies ProtocolParams, -} + DKG: 'INSECURE_DKG_512', + THRESHOLD: 'INSECURE_THRESHOLD_BFV_512', +} as const satisfies Record /** * The result of encrypting a value and generating a proof diff --git a/packages/enclave-sdk/src/utils.ts b/packages/enclave-sdk/src/utils.ts index 75f33a25bc..611ede683c 100644 --- a/packages/enclave-sdk/src/utils.ts +++ b/packages/enclave-sdk/src/utils.ts @@ -5,6 +5,7 @@ // or FITNESS FOR A PARTICULAR PURPOSE. import { type Address, type Hash, type Log, encodeAbiParameters } from 'viem' +import type { ProtocolParams } from './types' export class SDKError extends Error { constructor( @@ -58,25 +59,6 @@ export function getCurrentTimestamp(): number { return Math.floor(Date.now() / 1000) } -// BFV parameter set matching the Rust INSECURE_SET_2048_1032193_1 configuration -export const INSECURE_SET_2048_1032193_1 = { - degree: 2048, - plaintext_modulus: 1032193, - moduli: [0x3fffffff000001n], // BigInt for the modulus - error1_variance: '10', -} as const - -// BFV parameter set matching the Rust SET_8192_1000_4 configuration -export const SET_8192_1000_4 = { - degree: 8192, - plaintext_modulus: 1000, - moduli: [0x00800000022a0001n, 0x00800000021a0001n, 0x0080000002120001n, 0x0080000001f60001n], - error1_variance: '52309181128222339698631578526730685514457152477762943514050560000', -} - -// Set default parameter set -export const BFV_PARAMS_SET = INSECURE_SET_2048_1032193_1 - // Compute provider parameters structure export interface ComputeProviderParams { name: string @@ -104,12 +86,16 @@ export const DEFAULT_E3_CONFIG = { * Encode BFV parameters for the smart contract * BFV (Brakerski-Fan-Vercauteren) is a type of fully homomorphic encryption */ -export function encodeBfvParams( - degree: number = BFV_PARAMS_SET.degree, - plaintext_modulus: number = BFV_PARAMS_SET.plaintext_modulus, - moduli: readonly bigint[] = BFV_PARAMS_SET.moduli, - error1_variance: string = BFV_PARAMS_SET.error1_variance, -): `0x${string}` { +export function encodeBfvParams(params: ProtocolParams): `0x${string}` { + const { degree, plaintextModulus, moduli, error1Variance } = params + + if (error1Variance === undefined) { + throw new SDKError( + 'error1Variance is required in ProtocolParams. All BFV parameter sets must specify error1_variance.', + 'MISSING_ERROR1_VARIANCE' + ) + } + return encodeAbiParameters( [ { @@ -126,9 +112,9 @@ export function encodeBfvParams( [ { degree: BigInt(degree), - plaintext_modulus: BigInt(plaintext_modulus), + plaintext_modulus: BigInt(plaintextModulus), moduli: [...moduli], - error1_variance, + error1_variance: error1Variance, }, ], ) diff --git a/packages/enclave-sdk/tests/sdk.test.ts b/packages/enclave-sdk/tests/sdk.test.ts index 531b86ea8a..654cd21a0a 100644 --- a/packages/enclave-sdk/tests/sdk.test.ts +++ b/packages/enclave-sdk/tests/sdk.test.ts @@ -11,7 +11,7 @@ import { CompiledCircuit } from '@noir-lang/noir_js' import { EnclaveSDK } from '../src/enclave-sdk' import { zeroAddress } from 'viem' -import { FheProtocol } from '../src/types' +import { BfvParamSetType } from '../src/types' import demoCircuit from './fixtures/demo_circuit.json' describe('encryptNumber', () => { @@ -26,7 +26,7 @@ describe('encryptNumber', () => { }, rpcUrl: '', privateKey: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', - protocol: FheProtocol.TRBFV, + protocol: BfvParamSetType.THRESHOLD, }) it('should encrypt a number without crashing in a node environent', async () => { diff --git a/templates/default/client/src/pages/steps/RequestComputation.tsx b/templates/default/client/src/pages/steps/RequestComputation.tsx index e24314469e..11f9f3c392 100644 --- a/templates/default/client/src/pages/steps/RequestComputation.tsx +++ b/templates/default/client/src/pages/steps/RequestComputation.tsx @@ -106,7 +106,8 @@ const RequestComputation: React.FC = () => { const threshold: [number, number] = [DEFAULT_E3_CONFIG.threshold_min, DEFAULT_E3_CONFIG.threshold_max] const startWindow = calculateStartWindow(60) // 1 minute const duration = BigInt(60) // 1 minute - const e3ProgramParams = encodeBfvParams() + const protocolParams = await sdk.getProtocolParams() + const e3ProgramParams = encodeBfvParams(protocolParams) const computeProviderParams = encodeComputeProviderParams(DEFAULT_COMPUTE_PROVIDER_PARAMS) console.log('requestE3') diff --git a/templates/default/client/src/utils/sdk-config.ts b/templates/default/client/src/utils/sdk-config.ts index 60c56a2f8f..4c1f8239c2 100644 --- a/templates/default/client/src/utils/sdk-config.ts +++ b/templates/default/client/src/utils/sdk-config.ts @@ -4,7 +4,7 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -import { FheProtocol } from '@enclave-e3/sdk' +import { BfvParamSetType } from '@enclave-e3/sdk' import { getContractAddresses } from './env-config' /** @@ -19,6 +19,6 @@ export function getEnclaveSDKConfig() { ciphernodeRegistry: contracts.ciphernodeRegistry, feeToken: contracts.feeToken, }, - protocol: FheProtocol.BFV, + protocol: BfvParamSetType.DKG, } } diff --git a/templates/default/program/src/lib.rs b/templates/default/program/src/lib.rs index 0bdd444763..aed7988e1a 100644 --- a/templates/default/program/src/lib.rs +++ b/templates/default/program/src/lib.rs @@ -26,8 +26,7 @@ pub fn fhe_processor(fhe_inputs: &FHEInputs) -> Vec { mod tests { use super::*; use anyhow::Result; - use e3_bfv_helpers::BfvParamSet; - use e3_bfv_helpers::{BfvParamSets, build_bfv_params_arc, encode_bfv_params}; + use e3_bfv_helpers::{build_bfv_params_arc, encode_bfv_params, BfvParamSet, BfvPreset}; use fhe::bfv::{Encoding, Plaintext, PublicKey, SecretKey}; use fhe_traits::FheEncoder; use fhe_traits::FheEncrypter; @@ -38,7 +37,7 @@ mod tests { fn test() -> Result<()> { let mut rng = thread_rng(); - let params_set: BfvParamSet = BfvParamSets::InsecureSet2048_1032193_1.into(); + let params_set: BfvParamSet = BfvPreset::InsecureThresholdBfv512.into(); let params = build_bfv_params_arc( params_set.degree, params_set.plaintext_modulus, diff --git a/templates/default/server/index.ts b/templates/default/server/index.ts index 36de70d6b0..b4990eea25 100644 --- a/templates/default/server/index.ts +++ b/templates/default/server/index.ts @@ -5,7 +5,7 @@ // or FITNESS FOR A PARTICULAR PURPOSE. import express, { Request, Response } from 'express' -import { EnclaveSDK, EnclaveEventType, type E3ActivatedData, FheProtocol } from '@enclave-e3/sdk' +import { EnclaveSDK, EnclaveEventType, type E3ActivatedData, BfvParamSetType } from '@enclave-e3/sdk' import { Log, PublicClient } from 'viem' import { handleTestInteraction } from './testHandler' import { getCheckedEnvVars } from './utils' @@ -40,7 +40,7 @@ async function createPrivateSDK() { feeToken: FEE_TOKEN_CONTRACT as `0x${string}`, }, chainId: CHAIN_ID, - protocol: FheProtocol.BFV, + protocol: BfvParamSetType.THRESHOLD, }) await sdk.initialize() diff --git a/templates/default/tests/integration.spec.ts b/templates/default/tests/integration.spec.ts index 1da9f994f0..486ef476ff 100644 --- a/templates/default/tests/integration.spec.ts +++ b/templates/default/tests/integration.spec.ts @@ -16,7 +16,7 @@ import { encodeBfvParams, encodeComputeProviderParams, RegistryEventType, - FheProtocol, + BfvParamSetType, } from '@enclave-e3/sdk' import { hexToBytes } from 'viem' import assert from 'assert' @@ -167,7 +167,7 @@ describe('Integration', () => { }, rpcUrl: 'ws://localhost:8545', privateKey: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', - protocol: FheProtocol.BFV, + protocol: BfvParamSetType.THRESHOLD, }) it('should run an integration test', async () => { From 3b856e121d2d317a38ae65efc5ef6691ff169c8a Mon Sep 17 00:00:00 2001 From: 0xjei Date: Thu, 22 Jan 2026 20:23:47 +0100 Subject: [PATCH 02/19] format --- packages/enclave-sdk/src/enclave-sdk.ts | 2 +- packages/enclave-sdk/src/types.ts | 8 ++------ packages/enclave-sdk/src/utils.ts | 6 +++--- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/enclave-sdk/src/enclave-sdk.ts b/packages/enclave-sdk/src/enclave-sdk.ts index 7a1b653b36..95af090286 100644 --- a/packages/enclave-sdk/src/enclave-sdk.ts +++ b/packages/enclave-sdk/src/enclave-sdk.ts @@ -548,4 +548,4 @@ export class EnclaveSDK { protocolParams: options.protocolParams, }) } -} \ No newline at end of file +} diff --git a/packages/enclave-sdk/src/types.ts b/packages/enclave-sdk/src/types.ts index 35a9bdc8d6..5c02bd2739 100644 --- a/packages/enclave-sdk/src/types.ts +++ b/packages/enclave-sdk/src/types.ts @@ -265,7 +265,7 @@ export interface VerifiableEncryptionResult { /** * BFV parameter set type for FHE operations. - * + * * The protocol is always FHE BFV, but different parameter sets are needed: * - DKG: Used during Distributed Key Generation (PVSS phase 0-1) where each * ciphernode generates a standard BFV key-pair to encrypt secret shares. @@ -310,11 +310,7 @@ export interface ProtocolParams { error1Variance: string | undefined } -export type ProtocolParamsName = - | 'INSECURE_THRESHOLD_BFV_512' - | 'INSECURE_DKG_512' - | 'SECURE_THRESHOLD_BFV_8192' - | 'SECURE_DKG_8192' +export type ProtocolParamsName = 'INSECURE_THRESHOLD_BFV_512' | 'INSECURE_DKG_512' | 'SECURE_THRESHOLD_BFV_8192' | 'SECURE_DKG_8192' /** * Preset identifiers for BFV/TRBFV parameter selection. diff --git a/packages/enclave-sdk/src/utils.ts b/packages/enclave-sdk/src/utils.ts index 611ede683c..0390bb888d 100644 --- a/packages/enclave-sdk/src/utils.ts +++ b/packages/enclave-sdk/src/utils.ts @@ -88,14 +88,14 @@ export const DEFAULT_E3_CONFIG = { */ export function encodeBfvParams(params: ProtocolParams): `0x${string}` { const { degree, plaintextModulus, moduli, error1Variance } = params - + if (error1Variance === undefined) { throw new SDKError( 'error1Variance is required in ProtocolParams. All BFV parameter sets must specify error1_variance.', - 'MISSING_ERROR1_VARIANCE' + 'MISSING_ERROR1_VARIANCE', ) } - + return encodeAbiParameters( [ { From 3fb850f98fe442c70c82a1d464b21ea69287ca56 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Thu, 22 Jan 2026 22:42:45 +0100 Subject: [PATCH 03/19] update crisp verifier contract --- .../packages/crisp-contracts/contracts/CRISPVerifier.sol | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol b/examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol index 5282fc495d..0a1e45bce1 100644 --- a/examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol +++ b/examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol @@ -1,8 +1,5 @@ -// SPDX-License-Identifier: LGPL-3.0-only -// -// This file is provided WITHOUT ANY WARRANTY; -// without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2022 Aztec pragma solidity >=0.8.21; uint256 constant N = 524288; From 779740e2410e11abcb7bc7cb17c7753fd8ea92be Mon Sep 17 00:00:00 2001 From: 0xjei Date: Fri, 23 Jan 2026 16:47:07 +0100 Subject: [PATCH 04/19] move greco conversions to dedicated crate --- Cargo.lock | 15 ++ Cargo.toml | 2 + crates/bfv-helpers/Cargo.toml | 1 + crates/bfv-helpers/src/client.rs | 2 +- crates/bfv-helpers/src/lib.rs | 2 - crates/bfv-helpers/src/utils/mod.rs | 136 ------------------ crates/evm/src/enclave_sol_reader.rs | 9 +- crates/fhe-params/src/builder.rs | 6 + crates/fhe-params/src/constants.rs | 6 + crates/fhe-params/src/encoding.rs | 6 + crates/fhe-params/src/lib.rs | 6 + crates/fhe-params/src/presets.rs | 6 + crates/greco-helpers/Cargo.toml | 19 +++ .../greco.rs => greco-helpers/src/lib.rs} | 10 +- 14 files changed, 79 insertions(+), 147 deletions(-) delete mode 100644 crates/bfv-helpers/src/utils/mod.rs create mode 100644 crates/greco-helpers/Cargo.toml rename crates/{bfv-helpers/src/utils/greco.rs => greco-helpers/src/lib.rs} (97%) diff --git a/Cargo.lock b/Cargo.lock index e3df0e8236..acb70be022 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2762,6 +2762,7 @@ version = "0.1.7" dependencies = [ "anyhow", "e3-fhe-params", + "e3-greco-helpers", "fhe", "fhe-math", "fhe-traits", @@ -3080,6 +3081,20 @@ dependencies = [ "vfs", ] +[[package]] +name = "e3-greco-helpers" +version = "0.1.7" +dependencies = [ + "e3-fhe-params", + "fhe", + "fhe-math", + "fhe-traits", + "num-bigint", + "rand 0.8.5", + "zkfhe-greco", + "zkfhe-shared", +] + [[package]] name = "e3-indexer" version = "0.1.7" diff --git a/Cargo.toml b/Cargo.toml index 15d0db39fb..6459228ed6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ members = [ "crates/fhe", "crates/fhe-params", "crates/fs", + "crates/greco-helpers", "crates/indexer", "crates/init", "crates/keyshare", @@ -81,6 +82,7 @@ e3-evm-helpers = { version = "0.1.7", path = "./crates/evm-helpers" } e3-fhe = { version = "0.1.7", path = "./crates/fhe" } e3-fhe-params = { version = "0.1.7", path = "./crates/fhe-params" } e3-fs = { version = "0.1.7", path = "./crates/fs" } +e3-greco-helpers = { version = "0.1.7", path = "./crates/greco-helpers" } e3-indexer = { version = "0.1.7", path = "./crates/indexer" } e3-multithread = { version = "0.1.7", path = "./crates/multithread" } e3-keyshare = { version = "0.1.7", path = "./crates/keyshare" } diff --git a/crates/bfv-helpers/Cargo.toml b/crates/bfv-helpers/Cargo.toml index ae6ba4f0e4..f8b6250330 100644 --- a/crates/bfv-helpers/Cargo.toml +++ b/crates/bfv-helpers/Cargo.toml @@ -9,6 +9,7 @@ repository = "https://github.com/gnosisguild/enclave/crates/bfv-helpers" [dependencies] anyhow.workspace = true e3-fhe-params = { workspace = true, features = ["abi-encoding"] } +e3-greco-helpers = { workspace = true } fhe-math = { git = "https://github.com/gnosisguild/fhe.rs" } fhe-traits.workspace = true fhe-util = { git = "https://github.com/gnosisguild/fhe.rs" } diff --git a/crates/bfv-helpers/src/client.rs b/crates/bfv-helpers/src/client.rs index f76df5bad6..99eabb1431 100644 --- a/crates/bfv-helpers/src/client.rs +++ b/crates/bfv-helpers/src/client.rs @@ -5,8 +5,8 @@ // or FITNESS FOR A PARTICULAR PURPOSE. use crate::build_bfv_params_arc; -use crate::utils::greco::{bfv_ciphertext_to_greco, bfv_public_key_to_greco}; use anyhow::{anyhow, Result}; +use e3_greco_helpers::{bfv_ciphertext_to_greco, bfv_public_key_to_greco}; use fhe::bfv::{Ciphertext, Encoding, Plaintext, PublicKey}; use fhe::Error as FheError; use fhe_traits::{DeserializeParametrized, FheEncoder, FheEncrypter, Serialize}; diff --git a/crates/bfv-helpers/src/lib.rs b/crates/bfv-helpers/src/lib.rs index 8cdd84e720..3fdd1f7b80 100644 --- a/crates/bfv-helpers/src/lib.rs +++ b/crates/bfv-helpers/src/lib.rs @@ -5,8 +5,6 @@ // or FITNESS FOR A PARTICULAR PURPOSE. pub mod client; -pub mod utils; - use fhe::bfv::{Encoding, Plaintext}; use fhe_traits::FheDecoder; use thiserror::Error as ThisError; diff --git a/crates/bfv-helpers/src/utils/mod.rs b/crates/bfv-helpers/src/utils/mod.rs deleted file mode 100644 index 97658678b9..0000000000 --- a/crates/bfv-helpers/src/utils/mod.rs +++ /dev/null @@ -1,136 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-only -// -// This file is provided WITHOUT ANY WARRANTY; -// without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. -//! Utility functions - -use fhe::bfv; -use fhe_traits::FheEncoder; -use fhe_util::transcode_from_bytes; -use std::{cmp::min, fmt, sync::Arc, time::Duration}; - -pub mod greco; - -/// Macros to time code and display a human-readable duration. -pub mod timeit { - #[allow(unused_macros)] - macro_rules! timeit_n { - ($name:expr, $loops:expr, $code:expr) => {{ - use crate::utils::DisplayDuration; - let start = std::time::Instant::now(); - let r = $code; - for _ in 1..$loops { - let _ = $code; - } - println!( - "⏱ {}: {}", - $name, - DisplayDuration(start.elapsed() / $loops) - ); - r - }}; - } - - #[allow(unused_macros)] - macro_rules! timeit { - ($name:expr, $code:expr) => {{ - use crate::utils::DisplayDuration; - let start = std::time::Instant::now(); - let r = $code; - println!("⏱ {}: {}", $name, DisplayDuration(start.elapsed())); - r - }}; - } - - #[allow(unused_imports)] - pub(crate) use timeit; - #[allow(unused_imports)] - pub(crate) use timeit_n; -} - -/// Utility struct for displaying human-readable duration of the form "10.5 ms", -/// "350 μs", or "27 ns". -pub struct DisplayDuration(pub Duration); - -impl fmt::Display for DisplayDuration { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let duration_ns = self.0.as_nanos(); - if duration_ns < 1_000_u128 { - write!(f, "{duration_ns} ns") - } else if duration_ns < 1_000_000_u128 { - write!(f, "{} μs", (duration_ns + 500) / 1_000) - } else { - let duration_ms_times_10 = (duration_ns + 50_000) / (100_000); - write!(f, "{} ms", (duration_ms_times_10 as f64) / 10.0) - } - } -} - -// Utility functions for Private Information Retrieval. - -/// Generate a database of elements of the form [i || 0...0] where i is the 4B -/// little endian encoding of the index. When the element size is less than 4B, -/// the encoding is truncated. -#[allow(dead_code)] -pub fn generate_database(database_size: usize, elements_size: usize) -> Vec> { - assert!(database_size > 0 && elements_size > 0); - let mut database = vec![vec![0u8; elements_size]; database_size]; - for (i, element) in database.iter_mut().enumerate() { - element[..min(4, elements_size)] - .copy_from_slice(&(i as u32).to_le_bytes()[..min(4, elements_size)]); - } - database -} - -#[allow(dead_code)] -pub fn number_elements_per_plaintext( - degree: usize, - plaintext_nbits: usize, - elements_size: usize, -) -> usize { - (plaintext_nbits * degree) / (elements_size * 8) -} - -#[allow(dead_code)] -pub fn encode_database( - database: &Vec>, - par: Arc, - level: usize, -) -> (Vec, (usize, usize)) { - assert!(!database.is_empty()); - - let elements_size = database[0].len(); - let plaintext_nbits = par.plaintext().ilog2() as usize; - let number_elements_per_plaintext = - number_elements_per_plaintext(par.degree(), plaintext_nbits, elements_size); - let number_rows = - (database.len() + number_elements_per_plaintext - 1) / number_elements_per_plaintext; - println!("number_rows = {number_rows}"); - println!("number_elements_per_plaintext = {number_elements_per_plaintext}"); - let dimension_1 = (number_rows as f64).sqrt().ceil() as usize; - let dimension_2 = (number_rows + dimension_1 - 1) / dimension_1; - println!("dimensions = {dimension_1} {dimension_2}"); - println!("dimension = {}", dimension_1 * dimension_2); - let mut preprocessed_database = - vec![ - bfv::Plaintext::zero(bfv::Encoding::poly_at_level(level), &par).unwrap(); - dimension_1 * dimension_2 - ]; - (0..number_rows).for_each(|i| { - let mut serialized_plaintext = vec![0u8; number_elements_per_plaintext * elements_size]; - for j in 0..number_elements_per_plaintext { - if let Some(pt) = database.get(j + i * number_elements_per_plaintext) { - serialized_plaintext[j * elements_size..(j + 1) * elements_size].copy_from_slice(pt) - } - } - let pt_values = transcode_from_bytes(&serialized_plaintext, plaintext_nbits); - preprocessed_database[i] = - bfv::Plaintext::try_encode(&pt_values, bfv::Encoding::poly_at_level(level), &par) - .unwrap(); - }); - (preprocessed_database, (dimension_1, dimension_2)) -} - -#[allow(dead_code)] -fn main() {} diff --git a/crates/evm/src/enclave_sol_reader.rs b/crates/evm/src/enclave_sol_reader.rs index 078a4a7b81..41b6148b6e 100644 --- a/crates/evm/src/enclave_sol_reader.rs +++ b/crates/evm/src/enclave_sol_reader.rs @@ -33,7 +33,7 @@ impl From for e3_events::E3Requested { let params_bytes = value.0.e3.e3ProgramParams.to_vec(); let threshold_m = value.0.e3.threshold[0] as usize; let threshold_n = value.0.e3.threshold[1] as usize; - let params_arc = decode_bfv_params_arc(¶ms_bytes); + let params_arc = decode_bfv_params_arc(¶ms_bytes).expect("Failed to decode BFV params"); // TODO: These should be delivered from the e3_program contract // For now, using defaults that match the test configuration: @@ -42,7 +42,12 @@ impl From for e3_events::E3Requested { let lambda = 2; let esi_per_ct = 3; - let error_size = match calculate_error_size(params_arc, threshold_n, threshold_m, lambda) { + let error_size = match calculate_error_size( + params_arc.clone(), + threshold_n, + threshold_m, + lambda, + ) { Ok(size) => { let size_bytes = size.to_bytes_be(); info!( diff --git a/crates/fhe-params/src/builder.rs b/crates/fhe-params/src/builder.rs index 1308762255..b4edeb617f 100644 --- a/crates/fhe-params/src/builder.rs +++ b/crates/fhe-params/src/builder.rs @@ -1,3 +1,9 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + use crate::constants::{insecure_512, secure_8192}; use crate::presets::{BfvParamSet, BfvPreset, PresetError}; use fhe::bfv::{BfvParameters, BfvParametersBuilder}; diff --git a/crates/fhe-params/src/constants.rs b/crates/fhe-params/src/constants.rs index bab8940af9..4ccff52349 100644 --- a/crates/fhe-params/src/constants.rs +++ b/crates/fhe-params/src/constants.rs @@ -1,3 +1,9 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + //! Constants for BFV presets //! //! This module contains all hardcoded values used in preset definitions. diff --git a/crates/fhe-params/src/encoding.rs b/crates/fhe-params/src/encoding.rs index 2150227c63..0ad4b15633 100644 --- a/crates/fhe-params/src/encoding.rs +++ b/crates/fhe-params/src/encoding.rs @@ -1,3 +1,9 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + //! BFV Parameter Encoding/Decoding //! //! This module provides functions for encoding and decoding BFV parameters diff --git a/crates/fhe-params/src/lib.rs b/crates/fhe-params/src/lib.rs index e5d15b7e24..3f411e3566 100644 --- a/crates/fhe-params/src/lib.rs +++ b/crates/fhe-params/src/lib.rs @@ -1,3 +1,9 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + //! Preset definitions and builders for zkFHE parameters. pub mod builder; diff --git a/crates/fhe-params/src/presets.rs b/crates/fhe-params/src/presets.rs index 131e82da1c..9912cb2b81 100644 --- a/crates/fhe-params/src/presets.rs +++ b/crates/fhe-params/src/presets.rs @@ -1,3 +1,9 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + use crate::builder::build_pair_for_preset; use crate::builder::{build_bfv_params_from_set, build_bfv_params_from_set_arc}; use crate::constants::{ diff --git a/crates/greco-helpers/Cargo.toml b/crates/greco-helpers/Cargo.toml new file mode 100644 index 0000000000..b69428eb6d --- /dev/null +++ b/crates/greco-helpers/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "e3-greco-helpers" +version.workspace = true +edition.workspace = true +license.workspace = true +description = "E3 - Greco conversion helpers" +repository = "https://github.com/gnosisguild/enclave/crates/greco-helpers" + +[dependencies] +fhe = { workspace = true } +fhe-math = { git = "https://github.com/gnosisguild/fhe.rs" } +num-bigint = { workspace = true } +shared = { package = "zkfhe-shared", git = "https://github.com/gnosisguild/zkfhe-generator" } + +[dev-dependencies] +e3-fhe-params = { workspace = true } +fhe-traits = { workspace = true } +greco = { package = "zkfhe-greco", git = "https://github.com/gnosisguild/zkfhe-generator" } +rand = { workspace = true } diff --git a/crates/bfv-helpers/src/utils/greco.rs b/crates/greco-helpers/src/lib.rs similarity index 97% rename from crates/bfv-helpers/src/utils/greco.rs rename to crates/greco-helpers/src/lib.rs index 82d8683db6..0ac3618642 100644 --- a/crates/bfv-helpers/src/utils/greco.rs +++ b/crates/greco-helpers/src/lib.rs @@ -170,15 +170,16 @@ pub fn bfv_public_key_to_greco( #[cfg(test)] mod tests { use super::*; + use e3_fhe_params::{BfvParamSet, BfvPreset}; use fhe::bfv::{Encoding, Plaintext, PublicKey, SecretKey}; use fhe_traits::FheEncoder; use greco::bounds::GrecoBounds; use greco::vectors::GrecoVectors; use rand::thread_rng; + use shared::template::calculate_bit_width; #[test] fn test_bfv_public_key_to_greco() { - use crate::{BfvParamSet, BfvPreset}; let params = BfvParamSet::from(BfvPreset::InsecureThresholdBfv512).build_arc(); let mut rng = thread_rng(); @@ -187,8 +188,7 @@ mod tests { // Get expected pk0is and pk1is from GrecoVectors let (_, bounds) = GrecoBounds::compute(¶ms, 0).unwrap(); - let bit_pk = - shared::template::calculate_bit_width(&bounds.pk_bounds[0].to_string()).unwrap(); + let bit_pk = calculate_bit_width(&bounds.pk_bounds[0].to_string()).unwrap(); let vote = vec![1u64, 0u64, 0u64]; let pt = Plaintext::try_encode(&vote, Encoding::poly(), ¶ms).unwrap(); @@ -267,7 +267,6 @@ mod tests { #[test] fn test_bfv_ciphertext_to_greco() { - use crate::{BfvParamSet, BfvPreset}; let params = BfvParamSet::from(BfvPreset::InsecureThresholdBfv512).build_arc(); let mut rng = thread_rng(); @@ -276,8 +275,7 @@ mod tests { // Get expected ct0is and ct1is from GrecoVectors let (_, bounds) = GrecoBounds::compute(¶ms, 0).unwrap(); - let bit_pk = - shared::template::calculate_bit_width(&bounds.pk_bounds[0].to_string()).unwrap(); + let bit_pk = calculate_bit_width(&bounds.pk_bounds[0].to_string()).unwrap(); let vote = vec![1u64, 0u64, 0u64]; let pt = Plaintext::try_encode(&vote, Encoding::poly(), ¶ms).unwrap(); From bb808b6df0807530b1bbfa63ad563eed92de5927 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Fri, 23 Jan 2026 17:41:42 +0100 Subject: [PATCH 05/19] remove bfv-helpers --- Cargo.lock | 69 ++++++------- Cargo.toml | 4 +- crates/Dockerfile | 3 +- crates/aggregator/Cargo.toml | 2 +- crates/aggregator/src/publickey_aggregator.rs | 2 +- crates/{bfv-helpers => bfv-client}/Cargo.toml | 22 ++--- .../{bfv-helpers => bfv-client}/src/client.rs | 12 +-- crates/{bfv-helpers => bfv-client}/src/lib.rs | 13 +-- crates/compute-provider/Cargo.toml | 3 +- .../src/merkle_tree_builder.rs | 3 +- crates/evm/Cargo.toml | 2 +- crates/evm/src/enclave_sol_reader.rs | 2 +- crates/fhe/Cargo.toml | 3 +- crates/fhe/src/fhe.rs | 6 +- crates/fhe/src/utils.rs | 2 +- crates/indexer/Cargo.toml | 3 +- crates/indexer/tests/integration.rs | 3 +- crates/init/src/lib.rs | 9 +- crates/sdk/Cargo.toml | 5 +- crates/sdk/src/lib.rs | 4 +- crates/support/host/Cargo.toml | 2 +- crates/support/host/src/bin/profile_risc0.rs | 2 +- crates/support/program/Cargo.toml | 2 +- crates/support/program/src/lib.rs | 2 +- crates/test-helpers/Cargo.toml | 2 + crates/test-helpers/src/bin/fake_encrypt.rs | 2 +- crates/test-helpers/src/bin/pack_e3_params.rs | 2 +- crates/test-helpers/src/lib.rs | 2 +- crates/test-helpers/src/plaintext_writer.rs | 2 +- crates/tests/Cargo.toml | 3 +- crates/tests/tests/integration.rs | 3 +- crates/tests/tests/integration_legacy.rs | 7 +- crates/trbfv/Cargo.toml | 3 +- .../src/calculate_threshold_decryption.rs | 2 +- crates/trbfv/src/helpers.rs | 4 +- crates/trbfv/src/trbfv_config.rs | 2 +- crates/trbfv/tests/integration.rs | 3 +- crates/wasm/Cargo.toml | 3 +- crates/wasm/src/lib.rs | 8 +- docs/pages/hello-world-tutorial.mdx | 4 +- examples/CRISP/Cargo.lock | 73 ++++++++------ examples/CRISP/Cargo.toml | 3 +- .../CRISP/crates/crisp-constants/Cargo.toml | 1 + .../CRISP/crates/crisp-constants/src/lib.rs | 2 +- examples/CRISP/crates/crisp-utils/Cargo.toml | 1 + examples/CRISP/crates/crisp-utils/src/lib.rs | 2 +- examples/CRISP/crates/zk-inputs/Cargo.toml | 2 + examples/CRISP/crates/zk-inputs/src/lib.rs | 4 +- examples/CRISP/program/Cargo.toml | 2 +- examples/CRISP/program/src/lib.rs | 4 +- examples/CRISP/server/Cargo.toml | 1 + examples/CRISP/server/Dockerfile | 3 +- examples/CRISP/server/src/cli/commands.rs | 2 +- .../CRISP/server/src/server/routes/rounds.rs | 2 +- templates/default/Cargo.lock | 99 +++++++++---------- templates/default/Cargo.toml | 3 +- templates/default/program/Cargo.toml | 2 +- templates/default/program/src/lib.rs | 6 +- 58 files changed, 229 insertions(+), 215 deletions(-) rename crates/{bfv-helpers => bfv-client}/Cargo.toml (55%) rename crates/{bfv-helpers => bfv-client}/src/client.rs (96%) rename crates/{bfv-helpers => bfv-client}/src/lib.rs (78%) diff --git a/Cargo.lock b/Cargo.lock index 10fb3cdbcd..fad058fe24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1824,17 +1824,6 @@ version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" -[[package]] -name = "bigint-poly" -version = "0.1.0" -source = "git+https://github.com/gnosisguild/bigint-poly#9eca04d2aa473c5ead1e5a13adc8ad11bf250e4a" -dependencies = [ - "num-bigint", - "num-traits", - "serde", - "thiserror 1.0.69", -] - [[package]] name = "bimap" version = "0.6.3" @@ -2817,7 +2806,7 @@ dependencies = [ "anyhow", "async-trait", "bincode", - "e3-bfv-helpers", + "e3-bfv-client", "e3-config", "e3-data", "e3-events", @@ -2833,23 +2822,15 @@ dependencies = [ ] [[package]] -name = "e3-bfv-helpers" +name = "e3-bfv-client" version = "0.1.7" dependencies = [ "anyhow", "e3-fhe-params", "e3-greco-helpers", "fhe", - "fhe-math", "fhe-traits", - "fhe-util", - "hex", - "itertools 0.14.0", - "ndarray", - "num-bigint", - "num-traits", "rand 0.8.5", - "strum", "thiserror 1.0.69", "zkfhe-greco", "zkfhe-shared", @@ -2923,7 +2904,8 @@ version = "0.1.7" dependencies = [ "ark-bn254 0.4.0", "ark-ff 0.4.2", - "e3-bfv-helpers", + "e3-bfv-client", + "e3-fhe-params", "hex", "lean-imt", "light-poseidon", @@ -3073,13 +3055,13 @@ dependencies = [ "anyhow", "async-trait", "base64", - "e3-bfv-helpers", "e3-ciphernode-builder", "e3-config", "e3-crypto", "e3-data", "e3-entrypoint", "e3-events", + "e3-fhe-params", "e3-sortition", "e3-trbfv", "e3-utils", @@ -3116,10 +3098,11 @@ dependencies = [ "anyhow", "async-trait", "bincode", - "e3-bfv-helpers", + "e3-bfv-client", "e3-config", "e3-data", "e3-events", + "e3-fhe-params", "e3-request", "e3-trbfv", "e3-utils", @@ -3178,8 +3161,9 @@ dependencies = [ "alloy", "async-trait", "bincode", - "e3-bfv-helpers", + "e3-bfv-client", "e3-evm-helpers", + "e3-fhe-params", "eyre", "fhe", "fhe-traits", @@ -3326,8 +3310,9 @@ dependencies = [ name = "e3-sdk" version = "0.1.7" dependencies = [ - "e3-bfv-helpers", + "e3-bfv-client", "e3-evm-helpers", + "e3-fhe-params", "e3-indexer", ] @@ -3373,11 +3358,13 @@ dependencies = [ "bincode", "clap", "e3-aggregator", + "e3-bfv-client", "e3-ciphernode-builder", "e3-crypto", "e3-data", "e3-events", "e3-fhe", + "e3-fhe-params", "e3-keyshare", "e3-multithread", "e3-net", @@ -3408,13 +3395,14 @@ dependencies = [ "bincode", "clap", "e3-aggregator", - "e3-bfv-helpers", + "e3-bfv-client", "e3-ciphernode-builder", "e3-crypto", "e3-data", "e3-events", "e3-evm", "e3-fhe", + "e3-fhe-params", "e3-keyshare", "e3-logger", "e3-multithread", @@ -3445,10 +3433,11 @@ dependencies = [ "anyhow", "bincode", "derivative", - "e3-bfv-helpers", + "e3-bfv-client", "e3-crypto", "e3-events", "e3-fhe", + "e3-fhe-params", "e3-test-helpers", "e3-utils", "fhe", @@ -3485,7 +3474,8 @@ dependencies = [ name = "e3-wasm" version = "0.1.7" dependencies = [ - "e3-bfv-helpers", + "e3-bfv-client", + "e3-fhe-params", "getrandom 0.2.17", "serde", "serde-wasm-bindgen", @@ -6514,6 +6504,17 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "polynomial" +version = "0.1.7" +source = "git+https://github.com/gnosisguild/enclave?branch=main#54db685297b55d517aa86a6005e77e9a0354af02" +dependencies = [ + "num-bigint", + "num-traits", + "serde", + "thiserror 1.0.69", +] + [[package]] name = "polyval" version = "0.6.2" @@ -7400,7 +7401,7 @@ dependencies = [ [[package]] name = "safe" version = "0.1.7" -source = "git+https://github.com/gnosisguild/enclave#a3ef19d64142e5dd6916864c6d3dbc82f55f2bf8" +source = "git+https://github.com/gnosisguild/enclave#54db685297b55d517aa86a6005e77e9a0354af02" dependencies = [ "ark-bn254 0.5.0", "ark-ff 0.5.0", @@ -9555,12 +9556,11 @@ dependencies = [ [[package]] name = "zkfhe-greco" version = "0.1.0" -source = "git+https://github.com/gnosisguild/zkfhe-generator#d8c501e3eace1f9c5038b24caa654991a4d6f978" +source = "git+https://github.com/gnosisguild/zkfhe-generator#02131ceea13a9ff154a4d8cdd534261dacbfc724" dependencies = [ "anyhow", "ark-bn254 0.5.0", "ark-ff 0.5.0", - "bigint-poly", "blake3", "fhe", "fhe-math", @@ -9568,6 +9568,7 @@ dependencies = [ "itertools 0.14.0", "num-bigint", "num-traits", + "polynomial 0.1.7 (git+https://github.com/gnosisguild/enclave?branch=main)", "rand 0.8.5", "rayon", "serde", @@ -9580,18 +9581,18 @@ dependencies = [ [[package]] name = "zkfhe-shared" version = "0.1.0" -source = "git+https://github.com/gnosisguild/zkfhe-generator#d8c501e3eace1f9c5038b24caa654991a4d6f978" +source = "git+https://github.com/gnosisguild/zkfhe-generator#02131ceea13a9ff154a4d8cdd534261dacbfc724" dependencies = [ "anyhow", "ark-bn254 0.5.0", "ark-ff 0.5.0", - "bigint-poly", "chrono", "fhe", "fhe-math", "fhe-traits", "num-bigint", "num-traits", + "polynomial 0.1.7 (git+https://github.com/gnosisguild/enclave?branch=main)", "rand 0.8.5", "safe 0.1.7 (git+https://github.com/gnosisguild/enclave)", "serde", diff --git a/Cargo.toml b/Cargo.toml index eb654fab7d..b9f2fc3b7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [workspace] members = [ "crates/aggregator", - "crates/bfv-helpers", + "crates/bfv-client", "crates/ciphernode-builder", "crates/cli", "crates/compute-provider", @@ -67,7 +67,7 @@ repository = "https://github.com/gnosisguild/enclave" [workspace.dependencies] e3-aggregator = { version = "0.1.7", path = "./crates/aggregator" } -e3-bfv-helpers = { version = "0.1.7", path = "./crates/bfv-helpers" } +e3-bfv-client = { version = "0.1.7", path = "./crates/bfv-client" } e3-config = { version = "0.1.7", path = "./crates/config" } e3-ciphernode-builder = { version = "0.1.7", path = "./crates/ciphernode-builder" } e3-crypto = { version = "0.1.7", path = "./crates/crypto" } diff --git a/crates/Dockerfile b/crates/Dockerfile index 4def0daf20..5ef4a1255b 100644 --- a/crates/Dockerfile +++ b/crates/Dockerfile @@ -43,7 +43,8 @@ COPY --from=evm-builder /build/packages/enclave-contracts/deployed_contracts.jso # find crates/* -name "Cargo.toml" -not -path "*/support/*" -printf "COPY %p %p\n" | sed 's|COPY \(.*\) crates/|COPY \1 ./|' COPY crates/aggregator/Cargo.toml ./aggregator/Cargo.toml -COPY crates/bfv-helpers/Cargo.toml ./bfv-helpers/Cargo.toml +COPY crates/bfv-client/Cargo.toml ./bfv-client/Cargo.toml +COPY crates/greco-helpers/Cargo.toml ./greco-helpers/Cargo.toml COPY crates/cli/Cargo.toml ./cli/Cargo.toml COPY crates/ciphernode-builder/Cargo.toml ./ciphernode-builder/Cargo.toml COPY crates/compute-provider/Cargo.toml ./compute-provider/Cargo.toml diff --git a/crates/aggregator/Cargo.toml b/crates/aggregator/Cargo.toml index 8b5ad04afc..fccc0d3556 100644 --- a/crates/aggregator/Cargo.toml +++ b/crates/aggregator/Cargo.toml @@ -18,7 +18,7 @@ e3-evm = { workspace = true } e3-fhe = { workspace = true } e3-multithread = { workspace = true } e3-trbfv = { workspace = true } -e3-bfv-helpers = { workspace = true } +e3-bfv-client = { workspace = true } e3-request = { workspace = true } e3-sortition = { workspace = true } e3-utils = { workspace = true } diff --git a/crates/aggregator/src/publickey_aggregator.rs b/crates/aggregator/src/publickey_aggregator.rs index 2d8fe09f7c..a3ea9d3d04 100644 --- a/crates/aggregator/src/publickey_aggregator.rs +++ b/crates/aggregator/src/publickey_aggregator.rs @@ -6,7 +6,7 @@ use actix::prelude::*; use anyhow::Result; -use e3_bfv_helpers::client::compute_pk_commitment; +use e3_bfv_client::client::compute_pk_commitment; use e3_data::Persistable; use e3_events::{ prelude::*, BusHandle, Die, E3id, EnclaveEvent, EnclaveEventData, KeyshareCreated, OrderedSet, diff --git a/crates/bfv-helpers/Cargo.toml b/crates/bfv-client/Cargo.toml similarity index 55% rename from crates/bfv-helpers/Cargo.toml rename to crates/bfv-client/Cargo.toml index f8b6250330..4042e44773 100644 --- a/crates/bfv-helpers/Cargo.toml +++ b/crates/bfv-client/Cargo.toml @@ -1,28 +1,18 @@ [package] -name = "e3-bfv-helpers" +name = "e3-bfv-client" version.workspace = true edition.workspace = true license.workspace = true -description = "E3 - Enclave BFV Helpers" -repository = "https://github.com/gnosisguild/enclave/crates/bfv-helpers" +description = "E3 - BFV client helpers" +repository = "https://github.com/gnosisguild/enclave/crates/bfv-client" [dependencies] anyhow.workspace = true -e3-fhe-params = { workspace = true, features = ["abi-encoding"] } +e3-fhe-params = { workspace = true } e3-greco-helpers = { workspace = true } -fhe-math = { git = "https://github.com/gnosisguild/fhe.rs" } -fhe-traits.workspace = true -fhe-util = { git = "https://github.com/gnosisguild/fhe.rs" } fhe.workspace = true +fhe-traits.workspace = true greco = { package = "zkfhe-greco", git = "https://github.com/gnosisguild/zkfhe-generator" } -itertools = "0.14.0" -ndarray = "0.15" -num-bigint = { workspace = true } -num-traits = "0.2" -shared = { package = "zkfhe-shared", git = "https://github.com/gnosisguild/zkfhe-generator" } -strum.workspace = true rand.workspace = true +shared = { package = "zkfhe-shared", git = "https://github.com/gnosisguild/zkfhe-generator" } thiserror = { workspace = true } - -[dev-dependencies] -hex.workspace = true diff --git a/crates/bfv-helpers/src/client.rs b/crates/bfv-client/src/client.rs similarity index 96% rename from crates/bfv-helpers/src/client.rs rename to crates/bfv-client/src/client.rs index 99eabb1431..e2ea23dd4a 100644 --- a/crates/bfv-helpers/src/client.rs +++ b/crates/bfv-client/src/client.rs @@ -4,8 +4,8 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use crate::build_bfv_params_arc; use anyhow::{anyhow, Result}; +use e3_fhe_params::build_bfv_params_arc; use e3_greco_helpers::{bfv_ciphertext_to_greco, bfv_public_key_to_greco}; use fhe::bfv::{Ciphertext, Encoding, Plaintext, PublicKey}; use fhe::Error as FheError; @@ -31,7 +31,7 @@ use shared::template::calculate_bit_width; /// # Errors /// Returns error string if: /// - Public key deserialization fails -/// - Plaintext encoding fails +/// - Plaintext encoding fails /// - Encryption fails /// - Input validation vector computation fails pub fn bfv_encrypt( @@ -82,7 +82,7 @@ pub struct VerifiableEncryptionResult { /// # Errors /// Returns error string if: /// - Public key deserialization fails -/// - Plaintext encoding fails +/// - Plaintext encoding fails /// - Encryption fails /// - Input validation vector computation fails pub fn bfv_verifiable_encrypt( @@ -209,13 +209,12 @@ pub fn compute_ct_commitment( #[cfg(test)] mod tests { - use crate::{BfvParamSet, BfvPreset}; + use e3_fhe_params::{build_bfv_params_from_set_arc, BfvParamSet, BfvPreset}; use super::*; #[test] fn test_bfv_encrypt_a64() { - use crate::build_bfv_params_from_set_arc; use fhe::bfv::{Ciphertext, PublicKey, SecretKey}; use fhe_traits::{DeserializeParametrized, FheDecrypter, Serialize}; @@ -240,7 +239,6 @@ mod tests { #[test] fn test_bfv_encrypt_v64() { - use crate::build_bfv_params_from_set_arc; use fhe::bfv::{Ciphertext, PublicKey, SecretKey}; use fhe_traits::{DeserializeParametrized, FheDecrypter, Serialize}; @@ -272,7 +270,6 @@ mod tests { #[test] fn test_bfv_verifiable_encrypt_a64() { - use crate::build_bfv_params_from_set_arc; use fhe::bfv::{Ciphertext, PublicKey, SecretKey}; use fhe_traits::{DeserializeParametrized, FheDecrypter, Serialize}; @@ -303,7 +300,6 @@ mod tests { #[test] fn test_bfv_verifiable_encrypt_v64() { - use crate::build_bfv_params_from_set_arc; use fhe::bfv::{Ciphertext, PublicKey, SecretKey}; use fhe_traits::{DeserializeParametrized, FheDecrypter, Serialize}; diff --git a/crates/bfv-helpers/src/lib.rs b/crates/bfv-client/src/lib.rs similarity index 78% rename from crates/bfv-helpers/src/lib.rs rename to crates/bfv-client/src/lib.rs index 3fdd1f7b80..07eda233ad 100644 --- a/crates/bfv-helpers/src/lib.rs +++ b/crates/bfv-client/src/lib.rs @@ -5,17 +5,14 @@ // or FITNESS FOR A PARTICULAR PURPOSE. pub mod client; + use fhe::bfv::{Encoding, Plaintext}; use fhe_traits::FheDecoder; use thiserror::Error as ThisError; -pub use e3_fhe_params::{ - build_bfv_params, build_bfv_params_arc, build_bfv_params_from_set, - build_bfv_params_from_set_arc, BfvParamSet, BfvPreset, PresetError, PresetMetadata, - PresetSearchDefaults, -}; -pub use e3_fhe_params::{ - decode_bfv_params, decode_bfv_params_arc, encode_bfv_params, EncodingError, +pub use client::VerifiableEncryptionResult; +pub use client::{ + bfv_encrypt, bfv_verifiable_encrypt, compute_ct_commitment, compute_pk_commitment, }; #[derive(ThisError, Debug)] @@ -26,7 +23,7 @@ pub enum Error { BadEncoding, } -/// Result that returns a type T or a BfvHelpersError +/// Result that returns a type T or a BfvClientError type Result = std::result::Result; /// Decode Plaintext to a Vec diff --git a/crates/compute-provider/Cargo.toml b/crates/compute-provider/Cargo.toml index f4e832224d..411cd94b2c 100644 --- a/crates/compute-provider/Cargo.toml +++ b/crates/compute-provider/Cargo.toml @@ -18,4 +18,5 @@ ark-ff = "=0.4.2" ark-bn254 = "=0.4.0" rayon = "=1.10.0" zk-kit-imt = "0.0.7" -e3-bfv-helpers = { workspace = true } +e3-bfv-client = { workspace = true } +e3-fhe-params = { workspace = true, features = ["abi-encoding"] } diff --git a/crates/compute-provider/src/merkle_tree_builder.rs b/crates/compute-provider/src/merkle_tree_builder.rs index 9384948181..b83d398baa 100644 --- a/crates/compute-provider/src/merkle_tree_builder.rs +++ b/crates/compute-provider/src/merkle_tree_builder.rs @@ -6,7 +6,8 @@ use ark_bn254::Fr; use ark_ff::{BigInt, BigInteger}; -use e3_bfv_helpers::{client::compute_ct_commitment, decode_bfv_params}; +use e3_bfv_client::client::compute_ct_commitment; +use e3_fhe_params::decode_bfv_params; use light_poseidon::{Poseidon, PoseidonHasher}; use num_bigint::BigUint; use num_traits::Num; diff --git a/crates/evm/Cargo.toml b/crates/evm/Cargo.toml index 3a638e9153..e7071e3870 100644 --- a/crates/evm/Cargo.toml +++ b/crates/evm/Cargo.toml @@ -14,7 +14,7 @@ alloy-primitives = { workspace = true } anyhow = { workspace = true } async-trait = { workspace = true } base64 = { workspace = true } -e3-bfv-helpers = { workspace = true } +e3-fhe-params = { workspace = true } e3-crypto = { workspace = true } e3-config = { workspace = true } e3-data = { workspace = true } diff --git a/crates/evm/src/enclave_sol_reader.rs b/crates/evm/src/enclave_sol_reader.rs index 41b6148b6e..8ae7a7529d 100644 --- a/crates/evm/src/enclave_sol_reader.rs +++ b/crates/evm/src/enclave_sol_reader.rs @@ -12,7 +12,7 @@ use alloy::primitives::{LogData, B256}; use alloy::providers::Provider; use alloy::{sol, sol_types::SolEvent}; use anyhow::Result; -use e3_bfv_helpers::decode_bfv_params_arc; +use e3_fhe_params::decode_bfv_params_arc; use e3_data::Repository; use e3_events::{BusHandle, E3id, EnclaveEventData}; use e3_trbfv::helpers::calculate_error_size; diff --git a/crates/fhe/Cargo.toml b/crates/fhe/Cargo.toml index 7fb794c5fa..defab46628 100644 --- a/crates/fhe/Cargo.toml +++ b/crates/fhe/Cargo.toml @@ -23,5 +23,6 @@ rand_chacha = { workspace = true } e3-request = { workspace = true } serde = { workspace = true } tracing = { workspace = true } -e3-bfv-helpers = { workspace = true } +e3-bfv-client = { workspace = true } +e3-fhe-params = { workspace = true } e3-trbfv = { workspace = true } diff --git a/crates/fhe/src/fhe.rs b/crates/fhe/src/fhe.rs index 4c4629c32e..605a4b06bc 100644 --- a/crates/fhe/src/fhe.rs +++ b/crates/fhe/src/fhe.rs @@ -7,10 +7,8 @@ use super::create_crp; use anyhow::*; use async_trait::async_trait; -use e3_bfv_helpers::{ - build_bfv_params_arc, decode_bfv_params_arc, decode_plaintext_to_vec_u64, - encode_vec_u64_to_bytes, -}; +use e3_bfv_client::{decode_plaintext_to_vec_u64, encode_vec_u64_to_bytes}; +use e3_fhe_params::{build_bfv_params_arc, decode_bfv_params_arc}; use e3_data::{FromSnapshotWithParams, Snapshot}; use e3_events::{OrderedSet, Seed}; use e3_utils::{ArcBytes, SharedRng}; diff --git a/crates/fhe/src/utils.rs b/crates/fhe/src/utils.rs index 3985b0d0ca..e81da98c50 100644 --- a/crates/fhe/src/utils.rs +++ b/crates/fhe/src/utils.rs @@ -4,7 +4,7 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use e3_bfv_helpers::build_bfv_params_arc; +use e3_fhe_params::build_bfv_params_arc; use e3_utils::SharedRng; use fhe::bfv::BfvParameters; use fhe::mbfv::CommonRandomPoly; diff --git a/crates/indexer/Cargo.toml b/crates/indexer/Cargo.toml index 545b796206..8a173ae6c7 100644 --- a/crates/indexer/Cargo.toml +++ b/crates/indexer/Cargo.toml @@ -18,7 +18,8 @@ tokio.workspace = true tracing.workspace = true [dev-dependencies] -e3-bfv-helpers.workspace = true +e3-bfv-client.workspace = true +e3-fhe-params.workspace = true fhe.workspace = true fhe-traits.workspace = true rand.workspace = true diff --git a/crates/indexer/tests/integration.rs b/crates/indexer/tests/integration.rs index 7dfa3c7712..0e14b4e5f0 100644 --- a/crates/indexer/tests/integration.rs +++ b/crates/indexer/tests/integration.rs @@ -9,7 +9,8 @@ use alloy::{ primitives::{Bytes, FixedBytes, Uint}, sol, }; -use e3_bfv_helpers::{build_bfv_params_from_set_arc, client::compute_pk_commitment, BfvPreset}; +use e3_bfv_client::client::compute_pk_commitment; +use e3_fhe_params::{build_bfv_params_from_set_arc, BfvPreset}; use e3_evm_helpers::contracts::ReadOnly; use e3_indexer::{DataStore, EnclaveIndexer, InMemoryStore}; use eyre::Result; diff --git a/crates/init/src/lib.rs b/crates/init/src/lib.rs index a396229313..3cfc9af80a 100644 --- a/crates/init/src/lib.rs +++ b/crates/init/src/lib.rs @@ -124,8 +124,13 @@ async fn install_enclave(cwd: &PathBuf, template: Option, verbose: bool) ), Filter::new( "**/Cargo.toml", - r"(?m)^e3-bfv-helpers =.*\n?", - &format!("e3-bfv-helpers = {{ git = \"https://github.com/gnosisguild/enclave\", rev = \"{}\" }}\n",commit_hash), + r"(?m)^e3-bfv-client =.*\n?", + &format!("e3-bfv-client = {{ git = \"https://github.com/gnosisguild/enclave\", rev = \"{}\" }}\n",commit_hash), + ), + Filter::new( + "**/Cargo.toml", + r"(?m)^e3-fhe-params =.*\n?", + &format!("e3-fhe-params = {{ git = \"https://github.com/gnosisguild/enclave\", rev = \"{}\" }}\n",commit_hash), ), Filter::new( "**/Cargo.toml", diff --git a/crates/sdk/Cargo.toml b/crates/sdk/Cargo.toml index a021995a58..5ff326b21a 100644 --- a/crates/sdk/Cargo.toml +++ b/crates/sdk/Cargo.toml @@ -8,7 +8,8 @@ repository = "https://github.com/gnosisguild/enclave/crates/sdk" [dependencies] e3-evm-helpers = { workspace = true, optional = true } -e3-bfv-helpers = { workspace = true, optional = true } +e3-bfv-client = { workspace = true, optional = true } +e3-fhe-params = { workspace = true, optional = true } e3-indexer = { workspace = true, optional = true } [features] @@ -16,4 +17,4 @@ default = ["full"] full = ["evm", "bfv", "indexer"] indexer = ["dep:e3-indexer"] evm = ["dep:e3-evm-helpers"] -bfv = ["dep:e3-bfv-helpers"] +bfv = ["dep:e3-bfv-client", "dep:e3-fhe-params"] diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs index 6dd328db42..a746197f87 100644 --- a/crates/sdk/src/lib.rs +++ b/crates/sdk/src/lib.rs @@ -5,7 +5,9 @@ // or FITNESS FOR A PARTICULAR PURPOSE. #[cfg(feature = "bfv")] -pub use e3_bfv_helpers as bfv_helpers; +pub use e3_bfv_client as bfv_client; +#[cfg(feature = "bfv")] +pub use e3_fhe_params as bfv_params; #[cfg(feature = "evm")] pub use e3_evm_helpers as evm_helpers; diff --git a/crates/support/host/Cargo.toml b/crates/support/host/Cargo.toml index 0960f72ebb..0173e262e6 100644 --- a/crates/support/host/Cargo.toml +++ b/crates/support/host/Cargo.toml @@ -26,4 +26,4 @@ tracing-subscriber = { workspace = true } boundless-market = { workspace = true } url = { workspace = true } dotenvy = { workspace = true } -e3-bfv-helpers = { path = "../../bfv-helpers" } +e3-fhe-params = { workspace = true } diff --git a/crates/support/host/src/bin/profile_risc0.rs b/crates/support/host/src/bin/profile_risc0.rs index fe371340eb..584032acb5 100644 --- a/crates/support/host/src/bin/profile_risc0.rs +++ b/crates/support/host/src/bin/profile_risc0.rs @@ -4,7 +4,7 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use e3_bfv_helpers::{build_bfv_params_from_set_arc, encode_bfv_params, BfvPreset}; +use e3_fhe_params::{build_bfv_params_from_set_arc, encode_bfv_params, BfvPreset}; use e3_compute_provider::FHEInputs; use e3_support_host::run_risc0_compute; use fhe::bfv::{Encoding, Plaintext, PublicKey, SecretKey}; diff --git a/crates/support/program/Cargo.toml b/crates/support/program/Cargo.toml index da82159363..335c36901b 100644 --- a/crates/support/program/Cargo.toml +++ b/crates/support/program/Cargo.toml @@ -7,4 +7,4 @@ edition = "2024" fhe = { workspace = true } fhe-traits = { workspace = true } e3-compute-provider = { git = "https://github.com/gnosisguild/enclave", rev = "632766e4ed1ceeccdeb023a56f16413a33be6f46" } -e3-bfv-helpers = { git = "https://github.com/gnosisguild/enclave", rev = "632766e4ed1ceeccdeb023a56f16413a33be6f46" } +e3-fhe-params = { git = "https://github.com/gnosisguild/enclave", rev = "632766e4ed1ceeccdeb023a56f16413a33be6f46" } diff --git a/crates/support/program/src/lib.rs b/crates/support/program/src/lib.rs index 5ade113aa7..2a9809fcfd 100644 --- a/crates/support/program/src/lib.rs +++ b/crates/support/program/src/lib.rs @@ -4,7 +4,7 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use e3_bfv_helpers::decode_bfv_params_arc; +use e3_fhe_params::decode_bfv_params_arc; use e3_compute_provider::FHEInputs; use fhe::bfv::Ciphertext; use fhe_traits::{DeserializeParametrized, Serialize}; diff --git a/crates/test-helpers/Cargo.toml b/crates/test-helpers/Cargo.toml index 518da04118..10c882f257 100644 --- a/crates/test-helpers/Cargo.toml +++ b/crates/test-helpers/Cargo.toml @@ -16,6 +16,8 @@ e3-aggregator = { workspace = true } e3-crypto = { workspace = true } e3-ciphernode-builder = { workspace = true } e3-data = { workspace = true } +e3-bfv-client = { workspace = true } +e3-fhe-params = { workspace = true } e3-events = { workspace = true } e3-fhe = { workspace = true } e3-keyshare = { workspace = true } diff --git a/crates/test-helpers/src/bin/fake_encrypt.rs b/crates/test-helpers/src/bin/fake_encrypt.rs index bd302023e6..8031bc38ef 100644 --- a/crates/test-helpers/src/bin/fake_encrypt.rs +++ b/crates/test-helpers/src/bin/fake_encrypt.rs @@ -6,7 +6,7 @@ // This is a test script designed to encrypt some fixed data to a fhe public key use clap::Parser; -use e3_sdk::bfv_helpers::{build_bfv_params_from_set_arc, decode_bfv_params_arc, BfvPreset}; +use e3_fhe_params::{build_bfv_params_from_set_arc, decode_bfv_params_arc, BfvPreset}; use fhe::bfv::{Encoding, Plaintext, PublicKey}; use fhe_traits::{DeserializeParametrized, FheEncoder, FheEncrypter, Serialize}; use rand::SeedableRng; diff --git a/crates/test-helpers/src/bin/pack_e3_params.rs b/crates/test-helpers/src/bin/pack_e3_params.rs index f5ac101a35..42fba09648 100644 --- a/crates/test-helpers/src/bin/pack_e3_params.rs +++ b/crates/test-helpers/src/bin/pack_e3_params.rs @@ -5,7 +5,7 @@ // or FITNESS FOR A PARTICULAR PURPOSE. use clap::{command, Parser}; -use e3_sdk::bfv_helpers::{build_bfv_params_arc, encode_bfv_params}; +use e3_fhe_params::{build_bfv_params_arc, encode_bfv_params}; use std::{error::Error, num::ParseIntError, process}; fn parse_hex(arg: &str) -> Result { diff --git a/crates/test-helpers/src/lib.rs b/crates/test-helpers/src/lib.rs index fe3eb1fa64..976fa56705 100644 --- a/crates/test-helpers/src/lib.rs +++ b/crates/test-helpers/src/lib.rs @@ -20,7 +20,7 @@ use e3_events::{ }; use e3_fhe::{create_crp, setup_crp_params, ParamsWithCrp}; use e3_net::{DocumentPublisher, NetEventTranslator}; -use e3_sdk::bfv_helpers::{BfvParamSet, BfvPreset}; +use e3_fhe_params::{BfvParamSet, BfvPreset}; use e3_utils::SharedRng; use fhe::bfv::{BfvParameters, Ciphertext, Encoding, Plaintext, PublicKey}; use fhe::mbfv::CommonRandomPoly; diff --git a/crates/test-helpers/src/plaintext_writer.rs b/crates/test-helpers/src/plaintext_writer.rs index c74a111d3c..5e5df23899 100644 --- a/crates/test-helpers/src/plaintext_writer.rs +++ b/crates/test-helpers/src/plaintext_writer.rs @@ -9,7 +9,7 @@ use std::path::PathBuf; use super::write_file_with_dirs; use actix::{Actor, Addr, Context, Handler}; use e3_events::{prelude::*, BusHandle, EnclaveEvent, EnclaveEventData}; -use e3_sdk::bfv_helpers::decode_bytes_to_vec_u64; +use e3_bfv_client::decode_bytes_to_vec_u64; use tracing::{error, info}; pub struct PlaintextWriter { diff --git a/crates/tests/Cargo.toml b/crates/tests/Cargo.toml index 8c910328d9..2ebbf31e48 100644 --- a/crates/tests/Cargo.toml +++ b/crates/tests/Cargo.toml @@ -31,7 +31,8 @@ e3-sdk = { workspace = true } e3-sortition = { workspace = true } e3-test-helpers = { workspace = true } e3-trbfv = { workspace = true } -e3-bfv-helpers = { workspace = true } +e3-bfv-client = { workspace = true } +e3-fhe-params = { workspace = true } e3-utils = { workspace = true } fhe-traits = { workspace = true } fhe-util = { workspace = true } diff --git a/crates/tests/tests/integration.rs b/crates/tests/tests/integration.rs index 69a556b9f1..6afd66e482 100644 --- a/crates/tests/tests/integration.rs +++ b/crates/tests/tests/integration.rs @@ -15,7 +15,8 @@ use e3_events::{ TicketBalanceUpdated, }; use e3_multithread::{Multithread, MultithreadReport, ToReport}; -use e3_sdk::bfv_helpers::{build_bfv_params_arc, decode_bytes_to_vec_u64, encode_bfv_params}; +use e3_bfv_client::decode_bytes_to_vec_u64; +use e3_fhe_params::{build_bfv_params_arc, encode_bfv_params}; use e3_test_helpers::ciphernode_system::CiphernodeSystemBuilder; use e3_test_helpers::{create_seed_from_u64, create_shared_rng_from_u64, AddToCommittee}; use e3_trbfv::helpers::calculate_error_size; diff --git a/crates/tests/tests/integration_legacy.rs b/crates/tests/tests/integration_legacy.rs index ebdcb67727..6378bc5e3b 100644 --- a/crates/tests/tests/integration_legacy.rs +++ b/crates/tests/tests/integration_legacy.rs @@ -8,7 +8,7 @@ use actix::prelude::*; use actix::Actor; use alloy::primitives::{FixedBytes, I256, U256}; use anyhow::*; -use e3_bfv_helpers::client::compute_pk_commitment; +use e3_bfv_client::client::compute_pk_commitment; use e3_ciphernode_builder::CiphernodeBuilder; use e3_ciphernode_builder::CiphernodeHandle; use e3_ciphernode_builder::EventSystem; @@ -27,9 +27,8 @@ use e3_events::{ }; use e3_net::events::GossipData; use e3_net::{events::NetEvent, NetEventTranslator}; -use e3_sdk::bfv_helpers::decode_bytes_to_vec_u64; -use e3_sdk::bfv_helpers::decode_plaintext_to_vec_u64; -use e3_sdk::bfv_helpers::encode_bfv_params; +use e3_bfv_client::{decode_bytes_to_vec_u64, decode_plaintext_to_vec_u64}; +use e3_fhe_params::encode_bfv_params; use e3_test_helpers::encrypt_ciphertext; use e3_test_helpers::{ create_random_eth_addrs, create_shared_rng_from_u64, get_common_setup, simulate_libp2p_net, diff --git a/crates/trbfv/Cargo.toml b/crates/trbfv/Cargo.toml index b3a232134c..49ee31ee20 100644 --- a/crates/trbfv/Cargo.toml +++ b/crates/trbfv/Cargo.toml @@ -10,7 +10,8 @@ repository.workspace = true anyhow.workspace = true bincode.workspace = true derivative.workspace = true -e3-bfv-helpers.workspace = true +e3-bfv-client.workspace = true +e3-fhe-params = { workspace = true, features = ["abi-encoding"] } e3-crypto.workspace = true e3-utils.workspace = true fhe-math.workspace = true diff --git a/crates/trbfv/src/calculate_threshold_decryption.rs b/crates/trbfv/src/calculate_threshold_decryption.rs index 8bd4831a7b..e4e4dbc414 100644 --- a/crates/trbfv/src/calculate_threshold_decryption.rs +++ b/crates/trbfv/src/calculate_threshold_decryption.rs @@ -9,7 +9,7 @@ use std::sync::Arc; /// This module defines event payloads that will dcrypt a ciphertext with a threshold quorum of decryption shares use crate::{helpers::try_poly_from_bytes, PartyId, TrBFVConfig}; use anyhow::*; -use e3_bfv_helpers::{decode_plaintext_to_vec_u64, encode_vec_u64_to_bytes}; +use e3_bfv_client::{decode_plaintext_to_vec_u64, encode_vec_u64_to_bytes}; use e3_utils::utility_types::ArcBytes; use fhe::bfv::Plaintext; use fhe::{bfv::Ciphertext, trbfv::ShareManager}; diff --git a/crates/trbfv/src/helpers.rs b/crates/trbfv/src/helpers.rs index d878bc5b79..a1474fe5e8 100644 --- a/crates/trbfv/src/helpers.rs +++ b/crates/trbfv/src/helpers.rs @@ -6,7 +6,7 @@ use crate::shares::ShamirShare; use anyhow::Result; -use e3_bfv_helpers::{BfvParamSet, BfvPreset}; +use e3_fhe_params::{BfvParamSet, BfvPreset}; use e3_crypto::{Cipher, SensitiveBytes}; use fhe::mbfv::PublicKeyShare; use fhe::{ @@ -45,7 +45,7 @@ pub fn deserialize_secret_key(bytes: &[u8], params: &Arc) -> Resu /// TODO: Make this modular pub fn get_share_encryption_params() -> Arc { - let param_set: BfvParamSet = BfvPreset::SecureThresholdBfv8192.into(); + let param_set: BfvParamSet = BfvPreset::SecureDkg8192.into(); param_set.build_arc() } diff --git a/crates/trbfv/src/trbfv_config.rs b/crates/trbfv/src/trbfv_config.rs index 203b1174ae..ab8860a5c0 100644 --- a/crates/trbfv/src/trbfv_config.rs +++ b/crates/trbfv/src/trbfv_config.rs @@ -4,7 +4,7 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use e3_bfv_helpers::decode_bfv_params_arc; +use e3_fhe_params::decode_bfv_params_arc; use e3_utils::utility_types::ArcBytes; use fhe::bfv::BfvParameters; use serde::{Deserialize, Serialize}; diff --git a/crates/trbfv/tests/integration.rs b/crates/trbfv/tests/integration.rs index addc5575d0..0dbe9d7c43 100644 --- a/crates/trbfv/tests/integration.rs +++ b/crates/trbfv/tests/integration.rs @@ -9,7 +9,8 @@ use std::{ }; use anyhow::Result; -use e3_bfv_helpers::{build_bfv_params_arc, decode_bytes_to_vec_u64, encode_bfv_params}; +use e3_bfv_client::decode_bytes_to_vec_u64; +use e3_fhe_params::{build_bfv_params_arc, encode_bfv_params}; use e3_crypto::Cipher; use e3_fhe::create_crp; use e3_test_helpers::{create_seed_from_u64, create_shared_rng_from_u64, usecase_helpers}; diff --git a/crates/wasm/Cargo.toml b/crates/wasm/Cargo.toml index f7f00696dd..e5b5551dc5 100644 --- a/crates/wasm/Cargo.toml +++ b/crates/wasm/Cargo.toml @@ -10,7 +10,8 @@ repository.workspace = true crate-type = ["cdylib"] [dependencies] -e3-bfv-helpers.workspace = true +e3-bfv-client.workspace = true +e3-fhe-params.workspace = true serde.workspace = true serde-wasm-bindgen.workspace = true getrandom = { version = "0.2", features = ["js"] } diff --git a/crates/wasm/src/lib.rs b/crates/wasm/src/lib.rs index 9d71fbe096..f5b41c85a3 100644 --- a/crates/wasm/src/lib.rs +++ b/crates/wasm/src/lib.rs @@ -4,12 +4,10 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use e3_bfv_helpers::{ - client::{ - bfv_encrypt, bfv_verifiable_encrypt, compute_pk_commitment as _compute_pk_commitment, - }, - BfvParamSet, BfvPreset, +use e3_bfv_client::client::{ + bfv_encrypt, bfv_verifiable_encrypt, compute_pk_commitment as _compute_pk_commitment, }; +use e3_fhe_params::{BfvParamSet, BfvPreset}; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; diff --git a/docs/pages/hello-world-tutorial.mdx b/docs/pages/hello-world-tutorial.mdx index 3db59eac73..26663804cb 100644 --- a/docs/pages/hello-world-tutorial.mdx +++ b/docs/pages/hello-world-tutorial.mdx @@ -53,7 +53,7 @@ hello-world-e3/ The heart of your E3 program is in `./program/src/lib.rs`. Let's examine the default implementation: ```rust -use e3_bfv_helpers::decode_bfv_params_arc; +use e3_fhe_params::decode_bfv_params_arc; use e3_compute_provider::FHEInputs; use fhe::bfv::Ciphertext; use fhe_traits::{DeserializeParametrized, Serialize}; @@ -89,7 +89,7 @@ pub fn fhe_processor(fhe_inputs: &FHEInputs) -> Vec { Let's create a more interesting computation. Replace the content of `./program/src/lib.rs`: ```rust -use e3_bfv_helpers::decode_bfv_params_arc; +use e3_fhe_params::decode_bfv_params_arc; use e3_compute_provider::FHEInputs; use fhe::bfv::Ciphertext; use fhe_traits::{DeserializeParametrized, Serialize}; diff --git a/examples/CRISP/Cargo.lock b/examples/CRISP/Cargo.lock index e5355f1f2f..952006a379 100644 --- a/examples/CRISP/Cargo.lock +++ b/examples/CRISP/Cargo.lock @@ -1582,17 +1582,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "bigint-poly" -version = "0.1.0" -source = "git+https://github.com/gnosisguild/bigint-poly#9eca04d2aa473c5ead1e5a13adc8ad11bf250e4a" -dependencies = [ - "num-bigint", - "num-traits", - "serde", - "thiserror 1.0.69", -] - [[package]] name = "bimap" version = "0.6.3" @@ -2072,6 +2061,7 @@ dependencies = [ "dialoguer", "dotenvy", "e3-compute-provider", + "e3-fhe-params", "e3-sdk", "env_logger", "evm-helpers", @@ -2097,6 +2087,7 @@ dependencies = [ name = "crisp-constants" version = "0.1.0" dependencies = [ + "e3-fhe-params", "e3-sdk", ] @@ -2104,6 +2095,7 @@ dependencies = [ name = "crisp-utils" version = "0.1.0" dependencies = [ + "e3-bfv-client", "e3-sdk", "eyre", "hex", @@ -2382,21 +2374,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] -name = "e3-bfv-helpers" +name = "e3-bfv-client" version = "0.1.7" dependencies = [ "anyhow", "e3-fhe-params", + "e3-greco-helpers", "fhe", - "fhe-math", "fhe-traits", - "fhe-util", - "itertools 0.14.0", - "ndarray", - "num-bigint", - "num-traits", "rand 0.8.5", - "strum", "thiserror 1.0.69", "zkfhe-greco", "zkfhe-shared", @@ -2408,7 +2394,8 @@ version = "0.1.7" dependencies = [ "ark-bn254 0.4.0", "ark-ff 0.4.2", - "e3-bfv-helpers", + "e3-bfv-client", + "e3-fhe-params", "hex", "lean-imt", "light-poseidon 0.2.0", @@ -2448,6 +2435,16 @@ dependencies = [ "zkfhe-shared", ] +[[package]] +name = "e3-greco-helpers" +version = "0.1.7" +dependencies = [ + "fhe", + "fhe-math", + "num-bigint", + "zkfhe-shared", +] + [[package]] name = "e3-indexer" version = "0.1.7" @@ -2482,8 +2479,9 @@ dependencies = [ name = "e3-sdk" version = "0.1.7" dependencies = [ - "e3-bfv-helpers", + "e3-bfv-client", "e3-evm-helpers", + "e3-fhe-params", "e3-indexer", ] @@ -2502,8 +2500,8 @@ dependencies = [ name = "e3-user-program" version = "0.1.0" dependencies = [ - "e3-bfv-helpers", "e3-compute-provider", + "e3-fhe-params", "fhe", "fhe-traits", ] @@ -2650,7 +2648,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -4341,6 +4339,17 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "polynomial" +version = "0.1.7" +source = "git+https://github.com/gnosisguild/enclave?branch=main#54db685297b55d517aa86a6005e77e9a0354af02" +dependencies = [ + "num-bigint", + "num-traits", + "serde", + "thiserror 1.0.69", +] + [[package]] name = "portable-atomic" version = "1.12.0" @@ -4990,7 +4999,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -5055,7 +5064,7 @@ checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea" [[package]] name = "safe" version = "0.1.7" -source = "git+https://github.com/gnosisguild/enclave#dd9095cb560ff1b8c3c8e36cfd6ed2edf86ed2c2" +source = "git+https://github.com/gnosisguild/enclave#54db685297b55d517aa86a6005e77e9a0354af02" dependencies = [ "ark-bn254 0.5.0", "ark-ff 0.5.0", @@ -5598,7 +5607,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6734,6 +6743,8 @@ dependencies = [ "ark-bn254 0.5.0", "ark-ff 0.5.0", "crisp-constants", + "e3-bfv-client", + "e3-fhe-params", "e3-sdk", "eyre", "fhe", @@ -6744,7 +6755,7 @@ dependencies = [ "num-bigint", "num-integer", "num-traits", - "polynomial", + "polynomial 0.1.7", "rand 0.8.5", "rayon", "serde", @@ -6766,12 +6777,11 @@ dependencies = [ [[package]] name = "zkfhe-greco" version = "0.1.0" -source = "git+https://github.com/gnosisguild/zkfhe-generator#d8c501e3eace1f9c5038b24caa654991a4d6f978" +source = "git+https://github.com/gnosisguild/zkfhe-generator#02131ceea13a9ff154a4d8cdd534261dacbfc724" dependencies = [ "anyhow", "ark-bn254 0.5.0", "ark-ff 0.5.0", - "bigint-poly", "blake3", "fhe", "fhe-math", @@ -6779,6 +6789,7 @@ dependencies = [ "itertools 0.14.0", "num-bigint", "num-traits", + "polynomial 0.1.7 (git+https://github.com/gnosisguild/enclave?branch=main)", "rand 0.8.5", "rayon", "serde", @@ -6791,18 +6802,18 @@ dependencies = [ [[package]] name = "zkfhe-shared" version = "0.1.0" -source = "git+https://github.com/gnosisguild/zkfhe-generator#d8c501e3eace1f9c5038b24caa654991a4d6f978" +source = "git+https://github.com/gnosisguild/zkfhe-generator#02131ceea13a9ff154a4d8cdd534261dacbfc724" dependencies = [ "anyhow", "ark-bn254 0.5.0", "ark-ff 0.5.0", - "bigint-poly", "chrono", "fhe", "fhe-math", "fhe-traits", "num-bigint", "num-traits", + "polynomial 0.1.7 (git+https://github.com/gnosisguild/enclave?branch=main)", "rand 0.8.5", "safe", "serde", diff --git a/examples/CRISP/Cargo.toml b/examples/CRISP/Cargo.toml index fc00926ba2..d865596241 100644 --- a/examples/CRISP/Cargo.toml +++ b/examples/CRISP/Cargo.toml @@ -37,7 +37,8 @@ bytemuck = { version = "=1.23.1" } derivative = "=2.2.0" e3-compute-provider = { path = "../../crates/compute-provider" } e3-program-server = { path = "../../crates/program-server" } -e3-bfv-helpers = { path = "../../crates/bfv-helpers" } +e3-bfv-client = { path = "../../crates/bfv-client" } +e3-fhe-params = { path = "../../crates/fhe-params" } e3-sdk = { path = "../../crates/sdk", default-features = false } polynomial = { path = "../../crates/polynomial" } eyre = "=0.6.12" diff --git a/examples/CRISP/crates/crisp-constants/Cargo.toml b/examples/CRISP/crates/crisp-constants/Cargo.toml index 443b493f99..0eda4f5b1c 100644 --- a/examples/CRISP/crates/crisp-constants/Cargo.toml +++ b/examples/CRISP/crates/crisp-constants/Cargo.toml @@ -8,3 +8,4 @@ repository.workspace = true [dependencies] e3-sdk = { workspace = true, default-features = false, features=["bfv"] } +e3-fhe-params = { workspace = true } \ No newline at end of file diff --git a/examples/CRISP/crates/crisp-constants/src/lib.rs b/examples/CRISP/crates/crisp-constants/src/lib.rs index b26aa859df..adc0890f47 100644 --- a/examples/CRISP/crates/crisp-constants/src/lib.rs +++ b/examples/CRISP/crates/crisp-constants/src/lib.rs @@ -4,7 +4,7 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use e3_sdk::bfv_helpers::{BfvParamSet, BfvPreset}; +use e3_fhe_params::{BfvParamSet, BfvPreset}; // This could eventually be set here with an environment var once we allow for dynamic circuit selection. pub fn get_default_paramset() -> BfvParamSet { diff --git a/examples/CRISP/crates/crisp-utils/Cargo.toml b/examples/CRISP/crates/crisp-utils/Cargo.toml index 158925e92f..517e0c6235 100644 --- a/examples/CRISP/crates/crisp-utils/Cargo.toml +++ b/examples/CRISP/crates/crisp-utils/Cargo.toml @@ -8,6 +8,7 @@ repository.workspace = true [dependencies] e3-sdk = { workspace = true, default-features = false, features=["bfv"] } +e3-bfv-client = { workspace = true } eyre = { workspace = true } hex = { workspace = true } num-bigint = "=0.4.6" diff --git a/examples/CRISP/crates/crisp-utils/src/lib.rs b/examples/CRISP/crates/crisp-utils/src/lib.rs index 0979e47d91..9a1ce7a4f7 100644 --- a/examples/CRISP/crates/crisp-utils/src/lib.rs +++ b/examples/CRISP/crates/crisp-utils/src/lib.rs @@ -4,7 +4,7 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use e3_sdk::bfv_helpers::decode_bytes_to_vec_u64; +use e3_bfv_client::decode_bytes_to_vec_u64; use eyre::Result; use num_bigint::BigUint; diff --git a/examples/CRISP/crates/zk-inputs/Cargo.toml b/examples/CRISP/crates/zk-inputs/Cargo.toml index d0e5a0d589..c730ecc5af 100644 --- a/examples/CRISP/crates/zk-inputs/Cargo.toml +++ b/examples/CRISP/crates/zk-inputs/Cargo.toml @@ -12,6 +12,8 @@ crisp-constants.workspace = true fhe.workspace = true fhe-math.workspace = true fhe-traits.workspace = true +e3-bfv-client = { workspace = true } +e3-fhe-params = { workspace = true } greco = { package = "zkfhe-greco", git = "https://github.com/gnosisguild/zkfhe-generator" } shared = { package = "zkfhe-shared", git = "https://github.com/gnosisguild/zkfhe-generator" } polynomial = { workspace = true, features = ["serde"] } diff --git a/examples/CRISP/crates/zk-inputs/src/lib.rs b/examples/CRISP/crates/zk-inputs/src/lib.rs index 7e42e6e2be..63dd746f67 100644 --- a/examples/CRISP/crates/zk-inputs/src/lib.rs +++ b/examples/CRISP/crates/zk-inputs/src/lib.rs @@ -10,8 +10,8 @@ use crate::commitments::compute_commitment; use crisp_constants::get_default_paramset; -use e3_sdk::bfv_helpers::build_bfv_params_arc; -use e3_sdk::bfv_helpers::BfvParamSet; +use e3_fhe_params::build_bfv_params_arc; +use e3_fhe_params::BfvParamSet; use eyre::{Context, Result}; use fhe::bfv::BfvParameters; use fhe::bfv::Ciphertext; diff --git a/examples/CRISP/program/Cargo.toml b/examples/CRISP/program/Cargo.toml index 367c79bf9b..521505b0f6 100644 --- a/examples/CRISP/program/Cargo.toml +++ b/examples/CRISP/program/Cargo.toml @@ -7,4 +7,4 @@ edition = { workspace = true } fhe = { workspace = true } fhe-traits = { workspace = true } e3-compute-provider = { workspace = true } -e3-bfv-helpers = { workspace = true } +e3-fhe-params = { workspace = true } diff --git a/examples/CRISP/program/src/lib.rs b/examples/CRISP/program/src/lib.rs index 7e54fb13e3..179ccc75e2 100644 --- a/examples/CRISP/program/src/lib.rs +++ b/examples/CRISP/program/src/lib.rs @@ -4,14 +4,14 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use e3_bfv_helpers::decode_bfv_params_arc; use e3_compute_provider::FHEInputs; +use e3_fhe_params::decode_bfv_params_arc; use fhe::bfv::Ciphertext; use fhe_traits::{DeserializeParametrized, Serialize}; /// CRISP Implementation of the CiphertextProcessor function pub fn fhe_processor(fhe_inputs: &FHEInputs) -> Vec { - let params = decode_bfv_params_arc(&fhe_inputs.params); + let params = decode_bfv_params_arc(&fhe_inputs.params).unwrap(); let mut sum = Ciphertext::zero(¶ms); for ciphertext_bytes in &fhe_inputs.ciphertexts { diff --git a/examples/CRISP/server/Cargo.toml b/examples/CRISP/server/Cargo.toml index 7a06c4dfb3..1835adae35 100644 --- a/examples/CRISP/server/Cargo.toml +++ b/examples/CRISP/server/Cargo.toml @@ -44,6 +44,7 @@ lean-imt = "=0.1.2" # Local dependencies e3-compute-provider.workspace = true e3-sdk = { workspace = true, default-features = false, features=["full"] } +e3-fhe-params = { workspace = true } evm-helpers = { path = "../crates/evm_helpers" } crisp-constants.workspace = true crisp-utils.workspace = true diff --git a/examples/CRISP/server/Dockerfile b/examples/CRISP/server/Dockerfile index 1421dd3e49..ff2041bdc2 100644 --- a/examples/CRISP/server/Dockerfile +++ b/examples/CRISP/server/Dockerfile @@ -59,7 +59,8 @@ COPY Cargo.toml ./Cargo.toml # find crates/* -name "Cargo.toml" -not -path "*/support/*" -printf "COPY %p %p\n" COPY crates/aggregator/Cargo.toml crates/aggregator/Cargo.toml -COPY crates/bfv-helpers/Cargo.toml crates/bfv-helpers/Cargo.toml +COPY crates/bfv-client/Cargo.toml crates/bfv-client/Cargo.toml +COPY crates/greco-helpers/Cargo.toml crates/greco-helpers/Cargo.toml COPY crates/ciphernode-builder/Cargo.toml crates/ciphernode-builder/Cargo.toml COPY crates/cli/Cargo.toml crates/cli/Cargo.toml COPY crates/compute-provider/Cargo.toml crates/compute-provider/Cargo.toml diff --git a/examples/CRISP/server/src/cli/commands.rs b/examples/CRISP/server/src/cli/commands.rs index d9aa9a7529..2ee0236e3d 100644 --- a/examples/CRISP/server/src/cli/commands.rs +++ b/examples/CRISP/server/src/cli/commands.rs @@ -16,7 +16,7 @@ use alloy::primitives::{Address, Bytes, FixedBytes, U256}; use alloy::providers::{Provider, ProviderBuilder}; use alloy::sol_types::SolValue; use crisp::config::CONFIG; -use e3_sdk::bfv_helpers::{build_bfv_params_from_set_arc, encode_bfv_params}; +use e3_fhe_params::{build_bfv_params_from_set_arc, encode_bfv_params}; use e3_sdk::evm_helpers::contracts::{EnclaveContract, EnclaveRead, EnclaveWrite, E3}; use fhe::bfv::{BfvParameters, Ciphertext, Encoding, Plaintext, PublicKey, SecretKey}; use fhe_traits::{ diff --git a/examples/CRISP/server/src/server/routes/rounds.rs b/examples/CRISP/server/src/server/routes/rounds.rs index 1431efba5a..06fceac3da 100644 --- a/examples/CRISP/server/src/server/routes/rounds.rs +++ b/examples/CRISP/server/src/server/routes/rounds.rs @@ -16,7 +16,7 @@ use alloy::primitives::{Address, Bytes, U256}; use alloy::sol_types::SolValue; use chrono::Utc; use crisp_constants::get_default_paramset; -use e3_sdk::bfv_helpers::{build_bfv_params_from_set_arc, encode_bfv_params}; +use e3_fhe_params::{build_bfv_params_from_set_arc, encode_bfv_params}; use e3_sdk::evm_helpers::contracts::{EnclaveContract, EnclaveRead, EnclaveWrite}; use log::{error, info}; diff --git a/templates/default/Cargo.lock b/templates/default/Cargo.lock index f7eb90d5d0..96072886cc 100644 --- a/templates/default/Cargo.lock +++ b/templates/default/Cargo.lock @@ -761,17 +761,6 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" -[[package]] -name = "bigint-poly" -version = "0.1.0" -source = "git+https://github.com/gnosisguild/bigint-poly#9eca04d2aa473c5ead1e5a13adc8ad11bf250e4a" -dependencies = [ - "num-bigint", - "num-traits", - "serde", - "thiserror", -] - [[package]] name = "bincode" version = "1.3.3" @@ -1174,22 +1163,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] -name = "e3-bfv-helpers" +name = "e3-bfv-client" version = "0.1.7" dependencies = [ - "alloy-dyn-abi", - "alloy-primitives", "anyhow", + "e3-fhe-params", + "e3-greco-helpers", "fhe", - "fhe-math", "fhe-traits", - "fhe-util", - "itertools 0.14.0", - "ndarray", - "num-bigint", - "num-traits", "rand 0.8.5", - "strum", "thiserror", "zkfhe-greco", "zkfhe-shared", @@ -1201,7 +1183,8 @@ version = "0.1.7" dependencies = [ "ark-bn254 0.4.0", "ark-ff 0.4.2", - "e3-bfv-helpers", + "e3-bfv-client", + "e3-fhe-params", "hex", "lean-imt", "light-poseidon", @@ -1213,6 +1196,28 @@ dependencies = [ "zk-kit-imt", ] +[[package]] +name = "e3-fhe-params" +version = "0.1.7" +dependencies = [ + "alloy-dyn-abi", + "alloy-primitives", + "fhe", + "num-bigint", + "thiserror", + "zkfhe-shared", +] + +[[package]] +name = "e3-greco-helpers" +version = "0.1.7" +dependencies = [ + "fhe", + "fhe-math", + "num-bigint", + "zkfhe-shared", +] + [[package]] name = "e3-program-server" version = "0.1.7" @@ -1244,8 +1249,8 @@ name = "e3-user-program" version = "0.1.0" dependencies = [ "anyhow", - "e3-bfv-helpers", "e3-compute-provider", + "e3-fhe-params", "fhe", "fhe-traits", "rand 0.8.5", @@ -1344,7 +1349,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.52.0", ] [[package]] @@ -2586,6 +2591,17 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "polynomial" +version = "0.1.7" +source = "git+https://github.com/gnosisguild/enclave?branch=main#54db685297b55d517aa86a6005e77e9a0354af02" +dependencies = [ + "num-bigint", + "num-traits", + "serde", + "thiserror", +] + [[package]] name = "potential_utf" version = "0.1.4" @@ -3085,7 +3101,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys 0.52.0", ] [[package]] @@ -3148,7 +3164,7 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "safe" version = "0.1.7" -source = "git+https://github.com/gnosisguild/enclave#5f3b221938efc52ad48cee3db8fcbda795b08e9e" +source = "git+https://github.com/gnosisguild/enclave#54db685297b55d517aa86a6005e77e9a0354af02" dependencies = [ "ark-bn254 0.5.0", "ark-ff 0.5.0", @@ -3429,27 +3445,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strum" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.111", -] - [[package]] name = "subtle" version = "2.6.1" @@ -3560,7 +3555,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.60.2", + "windows-sys 0.52.0", ] [[package]] @@ -4428,12 +4423,11 @@ dependencies = [ [[package]] name = "zkfhe-greco" version = "0.1.0" -source = "git+https://github.com/gnosisguild/zkfhe-generator#fec2bc0ceb372e8ea03fce1ea1c90f561acfebfc" +source = "git+https://github.com/gnosisguild/zkfhe-generator#02131ceea13a9ff154a4d8cdd534261dacbfc724" dependencies = [ "anyhow", "ark-bn254 0.5.0", "ark-ff 0.5.0", - "bigint-poly", "blake3", "fhe", "fhe-math", @@ -4441,6 +4435,7 @@ dependencies = [ "itertools 0.14.0", "num-bigint", "num-traits", + "polynomial", "rand 0.8.5", "rayon", "serde", @@ -4453,18 +4448,18 @@ dependencies = [ [[package]] name = "zkfhe-shared" version = "0.1.0" -source = "git+https://github.com/gnosisguild/zkfhe-generator#fec2bc0ceb372e8ea03fce1ea1c90f561acfebfc" +source = "git+https://github.com/gnosisguild/zkfhe-generator#02131ceea13a9ff154a4d8cdd534261dacbfc724" dependencies = [ "anyhow", "ark-bn254 0.5.0", "ark-ff 0.5.0", - "bigint-poly", "chrono", "fhe", "fhe-math", "fhe-traits", "num-bigint", "num-traits", + "polynomial", "rand 0.8.5", "safe", "serde", diff --git a/templates/default/Cargo.toml b/templates/default/Cargo.toml index a3625effa6..a7aad2d571 100644 --- a/templates/default/Cargo.toml +++ b/templates/default/Cargo.toml @@ -10,7 +10,8 @@ e3-user-program = { path = "./program" } fhe = { package = "fhe", git = "https://github.com/gnosisguild/fhe.rs" } fhe-traits = { git = "https://github.com/gnosisguild/fhe.rs" } e3-program-server = { path = "../../crates/program-server" } -e3-bfv-helpers = { path = "../../crates/bfv-helpers" } +e3-bfv-client = { path = "../../crates/bfv-client" } +e3-fhe-params = { path = "../../crates/fhe-params" } e3-compute-provider = { path = "../../crates/compute-provider" } rand = "0.8.5" anyhow = "1.0.86" diff --git a/templates/default/program/Cargo.toml b/templates/default/program/Cargo.toml index 48522176b6..068a0ec483 100644 --- a/templates/default/program/Cargo.toml +++ b/templates/default/program/Cargo.toml @@ -7,7 +7,7 @@ edition = "2024" fhe = { workspace = true } fhe-traits = { workspace = true } e3-compute-provider = { workspace = true } -e3-bfv-helpers = { workspace = true } +e3-fhe-params = { workspace = true } [dev-dependencies] rand = { workspace = true } diff --git a/templates/default/program/src/lib.rs b/templates/default/program/src/lib.rs index aed7988e1a..cf36581c1f 100644 --- a/templates/default/program/src/lib.rs +++ b/templates/default/program/src/lib.rs @@ -4,14 +4,14 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -use e3_bfv_helpers::decode_bfv_params_arc; use e3_compute_provider::FHEInputs; +use e3_fhe_params::decode_bfv_params_arc; use fhe::bfv::Ciphertext; use fhe_traits::{DeserializeParametrized, Serialize}; /// Implementation of the CiphertextProcessor function pub fn fhe_processor(fhe_inputs: &FHEInputs) -> Vec { - let params = decode_bfv_params_arc(&fhe_inputs.params); + let params = decode_bfv_params_arc(&fhe_inputs.params).unwrap(); let mut sum = Ciphertext::zero(¶ms); for ciphertext_bytes in &fhe_inputs.ciphertexts { @@ -26,7 +26,7 @@ pub fn fhe_processor(fhe_inputs: &FHEInputs) -> Vec { mod tests { use super::*; use anyhow::Result; - use e3_bfv_helpers::{build_bfv_params_arc, encode_bfv_params, BfvParamSet, BfvPreset}; + use e3_fhe_params::{BfvParamSet, BfvPreset, build_bfv_params_arc, encode_bfv_params}; use fhe::bfv::{Encoding, Plaintext, PublicKey, SecretKey}; use fhe_traits::FheEncoder; use fhe_traits::FheEncrypter; From 7a361de36d7ccd8f421b874008895cc07f246b80 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Fri, 23 Jan 2026 17:42:14 +0100 Subject: [PATCH 06/19] fmt cargo --- crates/evm/src/enclave_sol_reader.rs | 2 +- crates/fhe/src/fhe.rs | 2 +- crates/indexer/tests/integration.rs | 2 +- crates/test-helpers/src/lib.rs | 2 +- crates/test-helpers/src/plaintext_writer.rs | 2 +- crates/tests/tests/integration.rs | 4 ++-- crates/tests/tests/integration_legacy.rs | 4 ++-- crates/trbfv/src/helpers.rs | 2 +- crates/trbfv/tests/integration.rs | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/evm/src/enclave_sol_reader.rs b/crates/evm/src/enclave_sol_reader.rs index 8ae7a7529d..11c4343fe8 100644 --- a/crates/evm/src/enclave_sol_reader.rs +++ b/crates/evm/src/enclave_sol_reader.rs @@ -12,9 +12,9 @@ use alloy::primitives::{LogData, B256}; use alloy::providers::Provider; use alloy::{sol, sol_types::SolEvent}; use anyhow::Result; -use e3_fhe_params::decode_bfv_params_arc; use e3_data::Repository; use e3_events::{BusHandle, E3id, EnclaveEventData}; +use e3_fhe_params::decode_bfv_params_arc; use e3_trbfv::helpers::calculate_error_size; use e3_utils::utility_types::ArcBytes; use num_bigint::BigUint; diff --git a/crates/fhe/src/fhe.rs b/crates/fhe/src/fhe.rs index 605a4b06bc..becf28c126 100644 --- a/crates/fhe/src/fhe.rs +++ b/crates/fhe/src/fhe.rs @@ -8,9 +8,9 @@ use super::create_crp; use anyhow::*; use async_trait::async_trait; use e3_bfv_client::{decode_plaintext_to_vec_u64, encode_vec_u64_to_bytes}; -use e3_fhe_params::{build_bfv_params_arc, decode_bfv_params_arc}; use e3_data::{FromSnapshotWithParams, Snapshot}; use e3_events::{OrderedSet, Seed}; +use e3_fhe_params::{build_bfv_params_arc, decode_bfv_params_arc}; use e3_utils::{ArcBytes, SharedRng}; use fhe::{ bfv::{BfvParameters, Ciphertext, Plaintext, PublicKey, SecretKey}, diff --git a/crates/indexer/tests/integration.rs b/crates/indexer/tests/integration.rs index 0e14b4e5f0..23a091a7e8 100644 --- a/crates/indexer/tests/integration.rs +++ b/crates/indexer/tests/integration.rs @@ -10,8 +10,8 @@ use alloy::{ sol, }; use e3_bfv_client::client::compute_pk_commitment; -use e3_fhe_params::{build_bfv_params_from_set_arc, BfvPreset}; use e3_evm_helpers::contracts::ReadOnly; +use e3_fhe_params::{build_bfv_params_from_set_arc, BfvPreset}; use e3_indexer::{DataStore, EnclaveIndexer, InMemoryStore}; use eyre::Result; use fhe::bfv::{PublicKey, SecretKey}; diff --git a/crates/test-helpers/src/lib.rs b/crates/test-helpers/src/lib.rs index 976fa56705..6d77879166 100644 --- a/crates/test-helpers/src/lib.rs +++ b/crates/test-helpers/src/lib.rs @@ -19,8 +19,8 @@ use e3_events::{ EventPublisher, HistoryCollector, Seed, Subscribe, }; use e3_fhe::{create_crp, setup_crp_params, ParamsWithCrp}; -use e3_net::{DocumentPublisher, NetEventTranslator}; use e3_fhe_params::{BfvParamSet, BfvPreset}; +use e3_net::{DocumentPublisher, NetEventTranslator}; use e3_utils::SharedRng; use fhe::bfv::{BfvParameters, Ciphertext, Encoding, Plaintext, PublicKey}; use fhe::mbfv::CommonRandomPoly; diff --git a/crates/test-helpers/src/plaintext_writer.rs b/crates/test-helpers/src/plaintext_writer.rs index 5e5df23899..4f8feb1a61 100644 --- a/crates/test-helpers/src/plaintext_writer.rs +++ b/crates/test-helpers/src/plaintext_writer.rs @@ -8,8 +8,8 @@ use std::path::PathBuf; use super::write_file_with_dirs; use actix::{Actor, Addr, Context, Handler}; -use e3_events::{prelude::*, BusHandle, EnclaveEvent, EnclaveEventData}; use e3_bfv_client::decode_bytes_to_vec_u64; +use e3_events::{prelude::*, BusHandle, EnclaveEvent, EnclaveEventData}; use tracing::{error, info}; pub struct PlaintextWriter { diff --git a/crates/tests/tests/integration.rs b/crates/tests/tests/integration.rs index 6afd66e482..bcbf1e236c 100644 --- a/crates/tests/tests/integration.rs +++ b/crates/tests/tests/integration.rs @@ -7,6 +7,7 @@ use actix::Actor; use alloy::primitives::{FixedBytes, I256, U256}; use anyhow::{bail, Result}; +use e3_bfv_client::decode_bytes_to_vec_u64; use e3_ciphernode_builder::{CiphernodeBuilder, EventSystem}; use e3_crypto::Cipher; use e3_events::{ @@ -14,9 +15,8 @@ use e3_events::{ E3Requested, E3id, EnclaveEventData, OperatorActivationChanged, PlaintextAggregated, TicketBalanceUpdated, }; -use e3_multithread::{Multithread, MultithreadReport, ToReport}; -use e3_bfv_client::decode_bytes_to_vec_u64; use e3_fhe_params::{build_bfv_params_arc, encode_bfv_params}; +use e3_multithread::{Multithread, MultithreadReport, ToReport}; use e3_test_helpers::ciphernode_system::CiphernodeSystemBuilder; use e3_test_helpers::{create_seed_from_u64, create_shared_rng_from_u64, AddToCommittee}; use e3_trbfv::helpers::calculate_error_size; diff --git a/crates/tests/tests/integration_legacy.rs b/crates/tests/tests/integration_legacy.rs index 6378bc5e3b..ac0cf22569 100644 --- a/crates/tests/tests/integration_legacy.rs +++ b/crates/tests/tests/integration_legacy.rs @@ -9,6 +9,7 @@ use actix::Actor; use alloy::primitives::{FixedBytes, I256, U256}; use anyhow::*; use e3_bfv_client::client::compute_pk_commitment; +use e3_bfv_client::{decode_bytes_to_vec_u64, decode_plaintext_to_vec_u64}; use e3_ciphernode_builder::CiphernodeBuilder; use e3_ciphernode_builder::CiphernodeHandle; use e3_ciphernode_builder::EventSystem; @@ -25,10 +26,9 @@ use e3_events::{ OperatorActivationChanged, OrderedSet, PlaintextAggregated, PublicKeyAggregated, Seed, Shutdown, TakeEvents, TicketBalanceUpdated, }; +use e3_fhe_params::encode_bfv_params; use e3_net::events::GossipData; use e3_net::{events::NetEvent, NetEventTranslator}; -use e3_bfv_client::{decode_bytes_to_vec_u64, decode_plaintext_to_vec_u64}; -use e3_fhe_params::encode_bfv_params; use e3_test_helpers::encrypt_ciphertext; use e3_test_helpers::{ create_random_eth_addrs, create_shared_rng_from_u64, get_common_setup, simulate_libp2p_net, diff --git a/crates/trbfv/src/helpers.rs b/crates/trbfv/src/helpers.rs index a1474fe5e8..6080338d34 100644 --- a/crates/trbfv/src/helpers.rs +++ b/crates/trbfv/src/helpers.rs @@ -6,8 +6,8 @@ use crate::shares::ShamirShare; use anyhow::Result; -use e3_fhe_params::{BfvParamSet, BfvPreset}; use e3_crypto::{Cipher, SensitiveBytes}; +use e3_fhe_params::{BfvParamSet, BfvPreset}; use fhe::mbfv::PublicKeyShare; use fhe::{ bfv::{self, BfvParameters, SecretKey}, diff --git a/crates/trbfv/tests/integration.rs b/crates/trbfv/tests/integration.rs index 0dbe9d7c43..78a81f0b71 100644 --- a/crates/trbfv/tests/integration.rs +++ b/crates/trbfv/tests/integration.rs @@ -10,9 +10,9 @@ use std::{ use anyhow::Result; use e3_bfv_client::decode_bytes_to_vec_u64; -use e3_fhe_params::{build_bfv_params_arc, encode_bfv_params}; use e3_crypto::Cipher; use e3_fhe::create_crp; +use e3_fhe_params::{build_bfv_params_arc, encode_bfv_params}; use e3_test_helpers::{create_seed_from_u64, create_shared_rng_from_u64, usecase_helpers}; use e3_trbfv::{ calculate_decryption_share::{ From dfa982bcb7a1dce70ae2faaab72fd564e5fc9b25 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Fri, 23 Jan 2026 17:50:44 +0100 Subject: [PATCH 07/19] missing crate in dockerfile --- crates/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/Dockerfile b/crates/Dockerfile index 5ef4a1255b..1144356fd6 100644 --- a/crates/Dockerfile +++ b/crates/Dockerfile @@ -57,6 +57,7 @@ COPY crates/events/Cargo.toml ./events/Cargo.toml COPY crates/evm/Cargo.toml ./evm/Cargo.toml COPY crates/evm-helpers/Cargo.toml ./evm-helpers/Cargo.toml COPY crates/fhe/Cargo.toml ./fhe/Cargo.toml +COPY crates/fhe-params/Cargo.toml ./fhe-params/Cargo.toml COPY crates/fs/Cargo.toml ./fs/Cargo.toml COPY crates/indexer/Cargo.toml ./indexer/Cargo.toml COPY crates/init/Cargo.toml ./init/Cargo.toml From 91d430399c84eebf86146d88ee98155bc9c5582d Mon Sep 17 00:00:00 2001 From: 0xjei Date: Fri, 23 Jan 2026 17:57:15 +0100 Subject: [PATCH 08/19] fix server dockerfile and revs --- crates/support/program/Cargo.toml | 4 ++-- examples/CRISP/server/Dockerfile | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/support/program/Cargo.toml b/crates/support/program/Cargo.toml index 335c36901b..9bde077c7f 100644 --- a/crates/support/program/Cargo.toml +++ b/crates/support/program/Cargo.toml @@ -6,5 +6,5 @@ edition = "2024" [dependencies] fhe = { workspace = true } fhe-traits = { workspace = true } -e3-compute-provider = { git = "https://github.com/gnosisguild/enclave", rev = "632766e4ed1ceeccdeb023a56f16413a33be6f46" } -e3-fhe-params = { git = "https://github.com/gnosisguild/enclave", rev = "632766e4ed1ceeccdeb023a56f16413a33be6f46" } +e3-compute-provider = { git = "https://github.com/gnosisguild/enclave", rev = "7a361de36d7ccd8f421b874008895cc07f246b80" } +e3-fhe-params = { git = "https://github.com/gnosisguild/enclave", rev = "7a361de36d7ccd8f421b874008895cc07f246b80" } diff --git a/examples/CRISP/server/Dockerfile b/examples/CRISP/server/Dockerfile index ff2041bdc2..0cb6f8241b 100644 --- a/examples/CRISP/server/Dockerfile +++ b/examples/CRISP/server/Dockerfile @@ -72,6 +72,7 @@ COPY crates/events/Cargo.toml crates/events/Cargo.toml COPY crates/evm/Cargo.toml crates/evm/Cargo.toml COPY crates/evm-helpers/Cargo.toml crates/evm-helpers/Cargo.toml COPY crates/fhe/Cargo.toml crates/fhe/Cargo.toml +COPY crates/fhe-params/Cargo.toml crates/fhe-params/Cargo.toml COPY crates/fs/Cargo.toml crates/fs/Cargo.toml COPY crates/indexer/Cargo.toml crates/indexer/Cargo.toml COPY crates/init/Cargo.toml crates/init/Cargo.toml From 5d1c2b7408c6af5e634a63c764c2be76dfaa0900 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Fri, 23 Jan 2026 18:35:17 +0100 Subject: [PATCH 09/19] update integration legacy test --- crates/tests/tests/integration_legacy.rs | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/crates/tests/tests/integration_legacy.rs b/crates/tests/tests/integration_legacy.rs index ac0cf22569..46fcaf30a1 100644 --- a/crates/tests/tests/integration_legacy.rs +++ b/crates/tests/tests/integration_legacy.rs @@ -197,8 +197,8 @@ async fn test_public_key_aggregation_and_decryption() -> Result<()> { e3_id: e3_id.clone(), params: ArcBytes::from_bytes(&encode_bfv_params(¶ms)), seed: seed.clone(), - threshold_m: 3, - threshold_n: 3, // Need to use n now to suggest committee size + threshold_m: 2, + threshold_n: 5, // Need to use n now to suggest committee size ..E3Requested::default() }; @@ -255,7 +255,7 @@ async fn test_public_key_aggregation_and_decryption() -> Result<()> { println!("Aggregating decryption..."); // Aggregate decryption - let raw_plaintext = vec![vec![1234, 567890]]; + let raw_plaintext = vec![vec![4, 5]]; let (ciphertext, expected) = encrypt_ciphertext(¶ms, test_pubkey, raw_plaintext)?; // Setup Ciphertext Published Event @@ -318,7 +318,7 @@ async fn test_stopped_keyshares_retain_state() -> Result<()> { bus.publish(E3Requested { e3_id: e3_id.clone(), threshold_m: 2, - threshold_n: 2, + threshold_n: 5, seed: seed.clone(), params: ArcBytes::from_bytes(&encode_bfv_params(¶ms)), ..E3Requested::default() @@ -408,7 +408,7 @@ async fn test_stopped_keyshares_retain_state() -> Result<()> { .aggregate()?; // Publish the ciphertext - let raw_plaintext = vec![vec![1234, 567890]]; + let raw_plaintext = vec![vec![4, 5]]; let (ciphertext, expected) = encrypt_ciphertext(¶ms, pubkey, raw_plaintext)?; bus.publish(CiphertextOutputPublished { ciphertext_output: ciphertext @@ -501,8 +501,8 @@ async fn test_p2p_actor_forwards_events_to_network() -> Result<()> { let local_evt_3 = CiphernodeSelected { e3_id: E3id::new("1235", 1), - threshold_m: 3, - threshold_n: 3, + threshold_m: 2, + threshold_n: 5, ..CiphernodeSelected::default() }; @@ -550,8 +550,8 @@ async fn test_duplicate_e3_id_with_different_chain_id() -> Result<()> { // Send the computation requested event bus.publish(E3Requested { e3_id: E3id::new("1234", 1), - threshold_m: 3, - threshold_n: 3, + threshold_m: 2, + threshold_n: 5, seed: seed.clone(), params: ArcBytes::from_bytes(&encode_bfv_params(¶ms)), ..E3Requested::default() @@ -594,8 +594,8 @@ async fn test_duplicate_e3_id_with_different_chain_id() -> Result<()> { // Send the computation requested event bus.publish(E3Requested { e3_id: E3id::new("1234", 2), - threshold_m: 3, - threshold_n: 3, + threshold_m: 2, + threshold_n: 5, seed: seed.clone(), params: ArcBytes::from_bytes(&encode_bfv_params(¶ms)), ..E3Requested::default() @@ -652,8 +652,8 @@ async fn test_p2p_actor_forwards_events_to_bus() -> Result<()> { // Capture messages from output on msgs vec let event = E3Requested { e3_id: E3id::new("1235", 1), - threshold_m: 3, - threshold_n: 3, + threshold_m: 2, + threshold_n: 5, seed: seed.clone(), params: ArcBytes::from_bytes(&[1, 2, 3, 4]), ..E3Requested::default() From ac35174bde0b978e9b305a7cd0f02adabdc288df Mon Sep 17 00:00:00 2001 From: 0xjei Date: Fri, 23 Jan 2026 18:59:16 +0100 Subject: [PATCH 10/19] update templates default integration tests --- templates/default/tests/integration.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/default/tests/integration.spec.ts b/templates/default/tests/integration.spec.ts index 486ef476ff..11ceebeaf5 100644 --- a/templates/default/tests/integration.spec.ts +++ b/templates/default/tests/integration.spec.ts @@ -176,7 +176,8 @@ describe('Integration', () => { const threshold: [number, number] = [DEFAULT_E3_CONFIG.threshold_min, DEFAULT_E3_CONFIG.threshold_max] const startWindow = calculateStartWindow(130) const duration = BigInt(20) - const e3ProgramParams = encodeBfvParams() + const protocolParams = await sdk.getProtocolParams() + const e3ProgramParams = encodeBfvParams(protocolParams) const computeProviderParams = encodeComputeProviderParams( DEFAULT_COMPUTE_PROVIDER_PARAMS, true, // Mock the compute provider parameters, return 32 bytes of 0x00 From 52d32185c3c2d27441ddedf87f16e1634decef80 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Fri, 23 Jan 2026 19:23:17 +0100 Subject: [PATCH 11/19] update to reflect plaintext mod of 10 --- templates/default/tests/integration.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/default/tests/integration.spec.ts b/templates/default/tests/integration.spec.ts index 11ceebeaf5..f62529c60b 100644 --- a/templates/default/tests/integration.spec.ts +++ b/templates/default/tests/integration.spec.ts @@ -235,8 +235,8 @@ describe('Integration', () => { // INPUT PUBLISHING phase console.log('PUBLISHING PRIVATE INPUT') - const num1 = 12n - const num2 = 21n + const num1 = 1n + const num2 = 2n console.log('ENCRYPTING NUMBERS') const enc1 = await sdk.encryptNumber(num1, publicKeyBytes) From 95f3469f6186df35d657656de5b7a707de48aa0c Mon Sep 17 00:00:00 2001 From: 0xjei Date: Mon, 26 Jan 2026 14:55:09 +0100 Subject: [PATCH 12/19] update enclave-sdk to simplify params handling --- crates/indexer/tests/integration.rs | 2 +- crates/trbfv/src/helpers.rs | 2 +- packages/enclave-react/src/useEnclaveSDK.ts | 3 - packages/enclave-sdk/src/enclave-sdk.ts | 62 ++++++++------------- packages/enclave-sdk/src/index.ts | 4 +- packages/enclave-sdk/src/types.ts | 50 +++-------------- packages/enclave-sdk/src/utils.ts | 4 +- packages/enclave-sdk/tests/sdk.test.ts | 3 +- 8 files changed, 39 insertions(+), 91 deletions(-) diff --git a/crates/indexer/tests/integration.rs b/crates/indexer/tests/integration.rs index 23a091a7e8..3ba6d8e762 100644 --- a/crates/indexer/tests/integration.rs +++ b/crates/indexer/tests/integration.rs @@ -9,7 +9,7 @@ use alloy::{ primitives::{Bytes, FixedBytes, Uint}, sol, }; -use e3_bfv_client::client::compute_pk_commitment; +use e3_bfv_client::compute_pk_commitment; use e3_evm_helpers::contracts::ReadOnly; use e3_fhe_params::{build_bfv_params_from_set_arc, BfvPreset}; use e3_indexer::{DataStore, EnclaveIndexer, InMemoryStore}; diff --git a/crates/trbfv/src/helpers.rs b/crates/trbfv/src/helpers.rs index 6080338d34..cefc67104a 100644 --- a/crates/trbfv/src/helpers.rs +++ b/crates/trbfv/src/helpers.rs @@ -45,7 +45,7 @@ pub fn deserialize_secret_key(bytes: &[u8], params: &Arc) -> Resu /// TODO: Make this modular pub fn get_share_encryption_params() -> Arc { - let param_set: BfvParamSet = BfvPreset::SecureDkg8192.into(); + let param_set: BfvParamSet = BfvPreset::InsecureDkg512.into(); param_set.build_arc() } diff --git a/packages/enclave-react/src/useEnclaveSDK.ts b/packages/enclave-react/src/useEnclaveSDK.ts index 77e8936cb2..3a7cabf1c0 100644 --- a/packages/enclave-react/src/useEnclaveSDK.ts +++ b/packages/enclave-react/src/useEnclaveSDK.ts @@ -11,7 +11,6 @@ import { type SDKConfig, type AllEventTypes, type EventCallback, - BfvParamSetType, type ProtocolParams, EnclaveEventType, RegistryEventType, @@ -26,7 +25,6 @@ export interface UseEnclaveSDKConfig { } chainId?: number autoConnect?: boolean - protocol: BfvParamSetType protocolParams?: ProtocolParams } @@ -69,7 +67,6 @@ export interface UseEnclaveSDKReturn { * enclave: '0x...', * ciphernodeRegistry: '0x...' * }, - * protocol: BfvParamSetType.DKG, * protocolParams: { * degree: 2048, * plaintextModulus: 1032193n, diff --git a/packages/enclave-sdk/src/enclave-sdk.ts b/packages/enclave-sdk/src/enclave-sdk.ts index 95af090286..6378395cfd 100644 --- a/packages/enclave-sdk/src/enclave-sdk.ts +++ b/packages/enclave-sdk/src/enclave-sdk.ts @@ -12,7 +12,7 @@ import initializeWasm from '@enclave-e3/wasm/init' import { CiphernodeRegistryOwnable__factory, Enclave__factory } from '@enclave-e3/contracts/types' import { ContractClient } from './contract-client' import { EventListener } from './event-listener' -import { BfvParamSetType, EnclaveEventType } from './types' +import { EnclaveEventType, ThresholdBfvParamsPresetNames } from './types' import { SDKError, isValidAddress } from './utils' import type { @@ -20,10 +20,10 @@ import type { E3, EventCallback, SDKConfig, - ProtocolParams, + BfvParams, VerifiableEncryptionResult, EncryptedValueAndPublicInputs, - ProtocolParamsName, + ThresholdBfvParamsPresetName, } from './types' import { bfv_encrypt_number, @@ -47,8 +47,7 @@ export class EnclaveSDK { private eventListener: EventListener private contractClient: ContractClient private initialized = false - private protocol: BfvParamSetType - private protocolParams?: ProtocolParams + private thresholdBfvParamsPresetName?: ThresholdBfvParamsPresetName private publicClient: PublicClient // TODO: use zod for config validation @@ -69,19 +68,20 @@ export class EnclaveSDK { throw new SDKError('Invalid FeeToken contract address', 'INVALID_ADDRESS') } - this.eventListener = new EventListener(config.publicClient) - this.contractClient = new ContractClient(config.publicClient, config.walletClient, config.contracts) - - if (!Object.values(BfvParamSetType).includes(config.protocol)) { - throw new SDKError(`Invalid BFV parameter set type: ${config.protocol}`, 'INVALID_PARAM_SET_TYPE') + if (!config.thresholdBfvParamsPresetName) { + throw new SDKError('Threshold BFV parameters preset name is required', 'MISSING_THRESHOLD_BFV_PARAMS_PRESET_NAME') } - this.protocol = config.protocol - - if (config.protocolParams) { - this.protocolParams = config.protocolParams + if (!Object.values(ThresholdBfvParamsPresetNames).includes(config.thresholdBfvParamsPresetName)) { + throw new SDKError( + `Invalid threshold BFV parameters preset name: ${config.thresholdBfvParamsPresetName}`, + 'INVALID_THRESHOLD_BFV_PARAMS_PRESET_NAME', + ) } + this.thresholdBfvParamsPresetName = config.thresholdBfvParamsPresetName + this.eventListener = new EventListener(config.publicClient) + this.contractClient = new ContractClient(config.publicClient, config.walletClient, config.contracts) this.publicClient = config.publicClient } @@ -108,9 +108,9 @@ export class EnclaveSDK { return this.publicClient } - public async getBfvParamsSet(name: ProtocolParamsName): Promise { + public async getThresholdBfvParamsSet(): Promise { await initializeWasm() - let params = get_bfv_params(name as string) + let params = get_bfv_params(this.thresholdBfvParamsPresetName as ThresholdBfvParamsPresetName) return { degree: Number(params.degree), // degree is returned as a bigint from wasm plaintextModulus: params.plaintext_modulus as bigint, @@ -119,23 +119,9 @@ export class EnclaveSDK { } } - public async getProtocolParams(): Promise { - await initializeWasm() - if (this.protocolParams) { - return this.protocolParams - } - - switch (this.protocol) { - case BfvParamSetType.DKG: - return await this.getBfvParamsSet('INSECURE_DKG_512') - case BfvParamSetType.THRESHOLD: - return await this.getBfvParamsSet('INSECURE_THRESHOLD_BFV_512') - } - } - public async computePublicKeyCommitment(publicKey: Uint8Array): Promise { await initializeWasm() - const protocolParams = await this.getProtocolParams() + const protocolParams = await this.getThresholdBfvParamsSet() return compute_pk_commitment( publicKey, @@ -153,7 +139,7 @@ export class EnclaveSDK { */ public async encryptNumber(data: bigint, publicKey: Uint8Array): Promise { await initializeWasm() - const protocolParams = await this.getProtocolParams() + const protocolParams = await this.getThresholdBfvParamsSet() return bfv_encrypt_number( data, @@ -172,7 +158,7 @@ export class EnclaveSDK { */ public async encryptVector(data: BigUint64Array, publicKey: Uint8Array): Promise { await initializeWasm() - const protocolParams = await this.getProtocolParams() + const protocolParams = await this.getThresholdBfvParamsSet() return bfv_encrypt_vector( data, @@ -192,7 +178,7 @@ export class EnclaveSDK { */ public async encryptNumberAndGenInputs(data: bigint, publicKey: Uint8Array): Promise { await initializeWasm() - const protocolParams = await this.getProtocolParams() + const protocolParams = await this.getThresholdBfvParamsSet() const [encryptedData, circuitInputs] = bfv_verifiable_encrypt_number( data, @@ -238,7 +224,7 @@ export class EnclaveSDK { */ public async encryptVectorAndGenInputs(data: BigUint64Array, publicKey: Uint8Array): Promise { await initializeWasm() - const protocolParams = await this.getProtocolParams() + const protocolParams = await this.getThresholdBfvParamsSet() const [encryptedData, circuitInputs] = bfv_verifiable_encrypt_vector( data, @@ -513,8 +499,7 @@ export class EnclaveSDK { } privateKey?: `0x${string}` chainId: keyof typeof EnclaveSDK.chains - protocol: BfvParamSetType - protocolParams?: ProtocolParams + thresholdBfvParamsPresetName: ThresholdBfvParamsPresetName }): EnclaveSDK { const chain = EnclaveSDK.chains[options.chainId] @@ -544,8 +529,7 @@ export class EnclaveSDK { walletClient, contracts: options.contracts, chainId: options.chainId, - protocol: options.protocol, - protocolParams: options.protocolParams, + thresholdBfvParamsPresetName: options.thresholdBfvParamsPresetName, }) } } diff --git a/packages/enclave-sdk/src/index.ts b/packages/enclave-sdk/src/index.ts index 3b470965b1..769445a417 100644 --- a/packages/enclave-sdk/src/index.ts +++ b/packages/enclave-sdk/src/index.ts @@ -34,13 +34,13 @@ export type { CommitteeFinalizedData, EnclaveEventData, RegistryEventData, - ProtocolParams, + BfvParams, VerifiableEncryptionResult, EncryptedValueAndPublicInputs, } from './types' // enums and constants -export { EnclaveEventType, RegistryEventType, BfvParamSetType, BfvProtocolParams } from './types' +export { EnclaveEventType, RegistryEventType, ThresholdBfvParamsPresetName, ThresholdBfvParamsPresetNames } from './types' // Export utilities export { diff --git a/packages/enclave-sdk/src/types.ts b/packages/enclave-sdk/src/types.ts index 5c02bd2739..701be1c1f0 100644 --- a/packages/enclave-sdk/src/types.ts +++ b/packages/enclave-sdk/src/types.ts @@ -50,16 +50,9 @@ export interface SDKConfig { chainId?: number /** - * The BFV parameter set type to use for FHE operations. - * DKG: Parameters for Distributed Key Generation (PVSS phase) - * THRESHOLD: Parameters for threshold encryption/decryption operations + * The threshold BFV parameters preset name to use for the Enclave requests */ - protocol: BfvParamSetType - - /** - * The protocol parameters to use for the Enclave requests - */ - protocolParams?: ProtocolParams + thresholdBfvParamsPresetName: ThresholdBfvParamsPresetName } export interface EventListenerConfig { @@ -264,34 +257,13 @@ export interface VerifiableEncryptionResult { } /** - * BFV parameter set type for FHE operations. - * - * The protocol is always FHE BFV, but different parameter sets are needed: - * - DKG: Used during Distributed Key Generation (PVSS phase 0-1) where each - * ciphernode generates a standard BFV key-pair to encrypt secret shares. - * - THRESHOLD: Used for threshold encryption/decryption operations (PVSS phase 2-4) - * where the threshold public key is used for encryption and T+1 parties - * collaborate for decryption. - */ -export enum BfvParamSetType { - /** - * DKG parameter set - for Distributed Key Generation phase - */ - DKG = 'DKG', - /** - * Threshold parameter set - for threshold encryption/decryption operations - */ - THRESHOLD = 'THRESHOLD', -} - -/** - * Protocol parameters for an Enclave program request + * BFV parameters for an Enclave program request * Example for BFV * 2048, // degree * 1032193, // plaintext_modulus * 0x3FFFFFFF000001, // moduli */ -export interface ProtocolParams { +export interface BfvParams { /** * The degree of the polynomial */ @@ -310,16 +282,12 @@ export interface ProtocolParams { error1Variance: string | undefined } -export type ProtocolParamsName = 'INSECURE_THRESHOLD_BFV_512' | 'INSECURE_DKG_512' | 'SECURE_THRESHOLD_BFV_8192' | 'SECURE_DKG_8192' +export type ThresholdBfvParamsPresetName = 'INSECURE_THRESHOLD_BFV_512' | 'SECURE_THRESHOLD_BFV_8192' -/** - * Preset identifiers for BFV/TRBFV parameter selection. - * Use these with `EnclaveSDK.getBfvParamsSet()` to fetch the actual parameters. - */ -export const BfvProtocolParams = { - DKG: 'INSECURE_DKG_512', - THRESHOLD: 'INSECURE_THRESHOLD_BFV_512', -} as const satisfies Record +export const ThresholdBfvParamsPresetNames = [ + 'INSECURE_THRESHOLD_BFV_512', + 'SECURE_THRESHOLD_BFV_8192', +] as const satisfies ReadonlyArray /** * The result of encrypting a value and generating a proof diff --git a/packages/enclave-sdk/src/utils.ts b/packages/enclave-sdk/src/utils.ts index 0390bb888d..71d821bae3 100644 --- a/packages/enclave-sdk/src/utils.ts +++ b/packages/enclave-sdk/src/utils.ts @@ -5,7 +5,7 @@ // or FITNESS FOR A PARTICULAR PURPOSE. import { type Address, type Hash, type Log, encodeAbiParameters } from 'viem' -import type { ProtocolParams } from './types' +import type { BfvParams } from './types' export class SDKError extends Error { constructor( @@ -86,7 +86,7 @@ export const DEFAULT_E3_CONFIG = { * Encode BFV parameters for the smart contract * BFV (Brakerski-Fan-Vercauteren) is a type of fully homomorphic encryption */ -export function encodeBfvParams(params: ProtocolParams): `0x${string}` { +export function encodeBfvParams(params: BfvParams): `0x${string}` { const { degree, plaintextModulus, moduli, error1Variance } = params if (error1Variance === undefined) { diff --git a/packages/enclave-sdk/tests/sdk.test.ts b/packages/enclave-sdk/tests/sdk.test.ts index 654cd21a0a..82aa570603 100644 --- a/packages/enclave-sdk/tests/sdk.test.ts +++ b/packages/enclave-sdk/tests/sdk.test.ts @@ -11,7 +11,6 @@ import { CompiledCircuit } from '@noir-lang/noir_js' import { EnclaveSDK } from '../src/enclave-sdk' import { zeroAddress } from 'viem' -import { BfvParamSetType } from '../src/types' import demoCircuit from './fixtures/demo_circuit.json' describe('encryptNumber', () => { @@ -26,7 +25,7 @@ describe('encryptNumber', () => { }, rpcUrl: '', privateKey: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', - protocol: BfvParamSetType.THRESHOLD, + thresholdBfvParamsPresetName: 'INSECURE_THRESHOLD_BFV_512', }) it('should encrypt a number without crashing in a node environent', async () => { From 416610073e48994549d02d182106dbdec59096c0 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Mon, 26 Jan 2026 15:54:13 +0100 Subject: [PATCH 13/19] update template --- packages/enclave-react/src/useEnclaveSDK.ts | 20 ++++++++++--------- .../src/pages/steps/RequestComputation.tsx | 8 ++++++-- .../default/client/src/utils/env-config.ts | 3 +++ .../default/client/src/utils/sdk-config.ts | 5 +++-- templates/default/deployed_contracts.json | 15 ++------------ templates/default/server/index.ts | 4 ++-- templates/default/tests/integration.spec.ts | 7 +++---- 7 files changed, 30 insertions(+), 32 deletions(-) diff --git a/packages/enclave-react/src/useEnclaveSDK.ts b/packages/enclave-react/src/useEnclaveSDK.ts index 3a7cabf1c0..9c1ae0d78d 100644 --- a/packages/enclave-react/src/useEnclaveSDK.ts +++ b/packages/enclave-react/src/useEnclaveSDK.ts @@ -11,7 +11,7 @@ import { type SDKConfig, type AllEventTypes, type EventCallback, - type ProtocolParams, + type ThresholdBfvParamsPresetName, EnclaveEventType, RegistryEventType, SDKError, @@ -25,7 +25,7 @@ export interface UseEnclaveSDKConfig { } chainId?: number autoConnect?: boolean - protocolParams?: ProtocolParams + thresholdBfvParamsPresetName: ThresholdBfvParamsPresetName } export interface UseEnclaveSDKReturn { @@ -36,6 +36,7 @@ export interface UseEnclaveSDKReturn { requestE3: typeof EnclaveSDK.prototype.requestE3 activateE3: typeof EnclaveSDK.prototype.activateE3 publishInput: typeof EnclaveSDK.prototype.publishInput + getThresholdBfvParamsSet: typeof EnclaveSDK.prototype.getThresholdBfvParamsSet // Event handling onEnclaveEvent: (eventType: T, callback: EventCallback) => void off: (eventType: T, callback: EventCallback) => void @@ -67,11 +68,7 @@ export interface UseEnclaveSDKReturn { * enclave: '0x...', * ciphernodeRegistry: '0x...' * }, - * protocolParams: { - * degree: 2048, - * plaintextModulus: 1032193n, - * moduli: 0x3FFFFFFF000001n, - * }, + * thresholdBfvParamsPresetName: 'INSECURE_THRESHOLD_BFV_512', * }); * * // Use the SDK... @@ -108,8 +105,7 @@ export const useEnclaveSDK = (config: UseEnclaveSDKConfig): UseEnclaveSDKReturn feeToken: '0x0000000000000000000000000000000000000000', }, chainId: config.chainId, - protocol: config.protocol, - protocolParams: config.protocolParams, + thresholdBfvParamsPresetName: config.thresholdBfvParamsPresetName, } const newSdk = new EnclaveSDK(sdkConfig) @@ -172,6 +168,11 @@ export const useEnclaveSDK = (config: UseEnclaveSDKConfig): UseEnclaveSDKReturn [sdk], ) + const getThresholdBfvParamsSet = useCallback(async () => { + if (!sdk) throw new Error('SDK not initialized') + return sdk.getThresholdBfvParamsSet() + }, [sdk]) + // Event handling methods const onEnclaveEvent = useCallback( (eventType: T, callback: EventCallback) => { @@ -196,6 +197,7 @@ export const useEnclaveSDK = (config: UseEnclaveSDKConfig): UseEnclaveSDKReturn requestE3, activateE3, publishInput, + getThresholdBfvParamsSet, onEnclaveEvent, off, EnclaveEventType, diff --git a/templates/default/client/src/pages/steps/RequestComputation.tsx b/templates/default/client/src/pages/steps/RequestComputation.tsx index 11f9f3c392..2b06cbc524 100644 --- a/templates/default/client/src/pages/steps/RequestComputation.tsx +++ b/templates/default/client/src/pages/steps/RequestComputation.tsx @@ -103,11 +103,15 @@ const RequestComputation: React.FC = () => { }) try { + if (!sdk.sdk) { + throw new Error('SDK not initialized') + } + const threshold: [number, number] = [DEFAULT_E3_CONFIG.threshold_min, DEFAULT_E3_CONFIG.threshold_max] const startWindow = calculateStartWindow(60) // 1 minute const duration = BigInt(60) // 1 minute - const protocolParams = await sdk.getProtocolParams() - const e3ProgramParams = encodeBfvParams(protocolParams) + const thresholdBfvParams = await sdk.getThresholdBfvParamsSet() + const e3ProgramParams = encodeBfvParams(thresholdBfvParams) const computeProviderParams = encodeComputeProviderParams(DEFAULT_COMPUTE_PROVIDER_PARAMS) console.log('requestE3') diff --git a/templates/default/client/src/utils/env-config.ts b/templates/default/client/src/utils/env-config.ts index ec681fa2b5..311d5db428 100644 --- a/templates/default/client/src/utils/env-config.ts +++ b/templates/default/client/src/utils/env-config.ts @@ -10,6 +10,7 @@ export const REGISTRY_ADDRESS = import.meta.env.VITE_REGISTRY_ADDRESS export const BONDING_REGISTRY_ADDRESS = import.meta.env.VITE_BONDING_REGISTRY_ADDRESS export const FEE_TOKEN_ADDRESS = import.meta.env.VITE_FEE_TOKEN_ADDRESS export const RPC_URL = import.meta.env.VITE_RPC_URL || 'http://localhost:8545' +export const THRESHOLD_BFV_PARAMS_PRESET_NAME = import.meta.env.VITE_THRESHOLD_BFV_PARAMS_PRESET_NAME || 'INSECURE_THRESHOLD_BFV_512' const requiredEnvVars = { VITE_ENCLAVE_ADDRESS: ENCLAVE_ADDRESS, @@ -17,6 +18,8 @@ const requiredEnvVars = { VITE_REGISTRY_ADDRESS: REGISTRY_ADDRESS, VITE_BONDING_REGISTRY_ADDRESS: BONDING_REGISTRY_ADDRESS, VITE_FEE_TOKEN_ADDRESS: FEE_TOKEN_ADDRESS, + VITE_RPC_URL: RPC_URL, + VITE_THRESHOLD_BFV_PARAMS_PRESET_NAME: THRESHOLD_BFV_PARAMS_PRESET_NAME, } export const MISSING_ENV_VARS = Object.entries(requiredEnvVars) diff --git a/templates/default/client/src/utils/sdk-config.ts b/templates/default/client/src/utils/sdk-config.ts index 4c1f8239c2..ead4d519ba 100644 --- a/templates/default/client/src/utils/sdk-config.ts +++ b/templates/default/client/src/utils/sdk-config.ts @@ -4,8 +4,9 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -import { BfvParamSetType } from '@enclave-e3/sdk' import { getContractAddresses } from './env-config' +import type { ThresholdBfvParamsPresetName } from '@enclave-e3/sdk' +import { THRESHOLD_BFV_PARAMS_PRESET_NAME } from './env-config' /** * Get the Enclave SDK configuration. @@ -19,6 +20,6 @@ export function getEnclaveSDKConfig() { ciphernodeRegistry: contracts.ciphernodeRegistry, feeToken: contracts.feeToken, }, - protocol: BfvParamSetType.DKG, + thresholdBfvParamsPresetName: THRESHOLD_BFV_PARAMS_PRESET_NAME as ThresholdBfvParamsPresetName, } } diff --git a/templates/default/deployed_contracts.json b/templates/default/deployed_contracts.json index 791ac0276c..c88dfd2586 100644 --- a/templates/default/deployed_contracts.json +++ b/templates/default/deployed_contracts.json @@ -101,11 +101,11 @@ "feeToken": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", "maxDuration": "2592000", "params": [ - "0x000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000fc00100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000003fffffff000001" + "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000ffffee0010000000000000000000000000000000000000000000000000000000ffffc400100000000000000000000000000000000000000000000000000000000000000013300000000000000000000000000000000000000000000000000000000000000" ] }, "proxyRecords": { - "initData": "0xefe0308b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000610178da211fef7d417bc0e6fed39f05609ad7880000000000000000000000002279b7a0a67db372996a5fab50d91eaa73d2ebe60000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e00000000000000000000000000000000000000000000000000000000000278d0000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000fc00100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000003fffffff000001", + "initData": "0xefe0308b000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000610178da211fef7d417bc0e6fed39f05609ad7880000000000000000000000002279b7a0a67db372996a5fab50d91eaa73d2ebe60000000000000000000000009fe46736679d2d9a65f0992f2272de9f3c7fa6e00000000000000000000000000000000000000000000000000000000000278d0000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000ffffee0010000000000000000000000000000000000000000000000000000000ffffc400100000000000000000000000000000000000000000000000000000000000000013300000000000000000000000000000000000000000000000000000000000000", "initialOwner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "proxyAddress": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", "proxyAdminAddress": "0x1F708C24a0D3A740cD47cC0444E9480899f3dA7D", @@ -126,19 +126,8 @@ "blockNumber": 25, "address": "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" }, - "MockRISC0Verifier": { - "address": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F" - }, "ImageID": { "address": "0x09635F643e140090A9A8Dcd712eD6285858ceBef" - }, - "MyProgram": { - "address": "0xc5a5C42992dECbae36851359345FE25997F5C42d", - "constructorArgs": { - "enclave": "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0", - "verifier": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F", - "programId": "0xaf928ebf39fec4696c3f41f473a1a9473b67d723c6373149c6ab99ba4c1a76ef" - } } } } \ No newline at end of file diff --git a/templates/default/server/index.ts b/templates/default/server/index.ts index b4990eea25..8664cac095 100644 --- a/templates/default/server/index.ts +++ b/templates/default/server/index.ts @@ -5,7 +5,7 @@ // or FITNESS FOR A PARTICULAR PURPOSE. import express, { Request, Response } from 'express' -import { EnclaveSDK, EnclaveEventType, type E3ActivatedData, BfvParamSetType } from '@enclave-e3/sdk' +import { EnclaveSDK, EnclaveEventType, type E3ActivatedData, ThresholdBfvParamsPresetName } from '@enclave-e3/sdk' import { Log, PublicClient } from 'viem' import { handleTestInteraction } from './testHandler' import { getCheckedEnvVars } from './utils' @@ -40,7 +40,7 @@ async function createPrivateSDK() { feeToken: FEE_TOKEN_CONTRACT as `0x${string}`, }, chainId: CHAIN_ID, - protocol: BfvParamSetType.THRESHOLD, + thresholdBfvParamsPresetName: 'INSECURE_THRESHOLD_BFV_512', }) await sdk.initialize() diff --git a/templates/default/tests/integration.spec.ts b/templates/default/tests/integration.spec.ts index f62529c60b..822229c867 100644 --- a/templates/default/tests/integration.spec.ts +++ b/templates/default/tests/integration.spec.ts @@ -16,7 +16,6 @@ import { encodeBfvParams, encodeComputeProviderParams, RegistryEventType, - BfvParamSetType, } from '@enclave-e3/sdk' import { hexToBytes } from 'viem' import assert from 'assert' @@ -167,7 +166,7 @@ describe('Integration', () => { }, rpcUrl: 'ws://localhost:8545', privateKey: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', - protocol: BfvParamSetType.THRESHOLD, + thresholdBfvParamsPresetName: 'INSECURE_THRESHOLD_BFV_512', }) it('should run an integration test', async () => { @@ -176,8 +175,8 @@ describe('Integration', () => { const threshold: [number, number] = [DEFAULT_E3_CONFIG.threshold_min, DEFAULT_E3_CONFIG.threshold_max] const startWindow = calculateStartWindow(130) const duration = BigInt(20) - const protocolParams = await sdk.getProtocolParams() - const e3ProgramParams = encodeBfvParams(protocolParams) + const thresholdBfvParams = await sdk.getThresholdBfvParamsSet() + const e3ProgramParams = encodeBfvParams(thresholdBfvParams) const computeProviderParams = encodeComputeProviderParams( DEFAULT_COMPUTE_PROVIDER_PARAMS, true, // Mock the compute provider parameters, return 32 bytes of 0x00 From c4dc6fa47a972f0f2a6e8118fde946705f545225 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Mon, 26 Jan 2026 15:55:12 +0100 Subject: [PATCH 14/19] removed unused import --- templates/default/server/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/default/server/index.ts b/templates/default/server/index.ts index 8664cac095..46e879ca38 100644 --- a/templates/default/server/index.ts +++ b/templates/default/server/index.ts @@ -5,7 +5,7 @@ // or FITNESS FOR A PARTICULAR PURPOSE. import express, { Request, Response } from 'express' -import { EnclaveSDK, EnclaveEventType, type E3ActivatedData, ThresholdBfvParamsPresetName } from '@enclave-e3/sdk' +import { EnclaveSDK, EnclaveEventType, type E3ActivatedData } from '@enclave-e3/sdk' import { Log, PublicClient } from 'viem' import { handleTestInteraction } from './testHandler' import { getCheckedEnvVars } from './utils' From 54ac979a17fbffdf089788ad6a4b24ae823f3537 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Mon, 26 Jan 2026 16:34:35 +0100 Subject: [PATCH 15/19] update integration tests to insecure params --- crates/tests/tests/integration.rs | 29 ++++++++++------------------- crates/trbfv/tests/integration.rs | 26 ++++++++++---------------- tests/integration/base.sh | 10 ++++------ tests/integration/persist.sh | 10 ++++------ 4 files changed, 28 insertions(+), 47 deletions(-) diff --git a/crates/tests/tests/integration.rs b/crates/tests/tests/integration.rs index bcbf1e236c..5fbae9fd85 100644 --- a/crates/tests/tests/integration.rs +++ b/crates/tests/tests/integration.rs @@ -15,7 +15,7 @@ use e3_events::{ E3Requested, E3id, EnclaveEventData, OperatorActivationChanged, PlaintextAggregated, TicketBalanceUpdated, }; -use e3_fhe_params::{build_bfv_params_arc, encode_bfv_params}; +use e3_fhe_params::{encode_bfv_params, BfvParamSet, BfvPreset}; use e3_multithread::{Multithread, MultithreadReport, ToReport}; use e3_test_helpers::ciphernode_system::CiphernodeSystemBuilder; use e3_test_helpers::{create_seed_from_u64, create_shared_rng_from_u64, AddToCommittee}; @@ -124,20 +124,7 @@ async fn test_trbfv_actor() -> Result<()> { let bus = system.handle()?; // Parameters (128bits of security) - let (degree, plaintext_modulus, moduli) = ( - 8192, - 1000, - &[ - 36028797055270913, - 36028797054222337, - 36028797053698049, - 36028797051863041, - ], - ); - - // Params for BFV - // TODO: use params set with secure params in test - let params_raw = build_bfv_params_arc(degree, plaintext_modulus, moduli, None); + let params_raw = BfvParamSet::from(BfvPreset::InsecureThresholdBfv512).build_arc(); // Encoded Params let params = ArcBytes::from_bytes(&encode_bfv_params(¶ms_raw.clone())); @@ -365,8 +352,11 @@ async fn test_trbfv_actor() -> Result<()> { let running_app_timer = Instant::now(); println!("Running application to generate outputs..."); - let outputs = - e3_test_helpers::application::run_application(&inputs, params_raw, num_votes_per_voter); + let outputs = e3_test_helpers::application::run_application( + &inputs, + params_raw.clone(), + num_votes_per_voter, + ); report.push(("Running FHE Application", running_app_timer.elapsed())); let publishing_ct_timer = Instant::now(); @@ -428,11 +418,12 @@ async fn test_trbfv_actor() -> Result<()> { .map(|r| r.first().unwrap().clone()) .collect(); - // Show summation result + // Show summation result (mod plaintext modulus) + let plaintext_modulus = params_raw.clone().plaintext(); let mut expected_result = vec![0u64; 3]; for vals in &numbers { for j in 0..num_votes_per_voter { - expected_result[j] += vals[j]; + expected_result[j] = (expected_result[j] + vals[j]) % plaintext_modulus; } } diff --git a/crates/trbfv/tests/integration.rs b/crates/trbfv/tests/integration.rs index 78a81f0b71..048fb8a3ec 100644 --- a/crates/trbfv/tests/integration.rs +++ b/crates/trbfv/tests/integration.rs @@ -12,7 +12,7 @@ use anyhow::Result; use e3_bfv_client::decode_bytes_to_vec_u64; use e3_crypto::Cipher; use e3_fhe::create_crp; -use e3_fhe_params::{build_bfv_params_arc, encode_bfv_params}; +use e3_fhe_params::{encode_bfv_params, BfvParamSet, BfvPreset}; use e3_test_helpers::{create_seed_from_u64, create_shared_rng_from_u64, usecase_helpers}; use e3_trbfv::{ calculate_decryption_share::{ @@ -44,18 +44,7 @@ async fn test_trbfv_isolation() -> Result<()> { let _guard = tracing::subscriber::set_default(subscriber); let rng = create_shared_rng_from_u64(42); - let (degree, plaintext_modulus, moduli) = ( - 8192usize, - 16384u64, - &[ - 0x1FFFFFFEA0001u64, // 562949951979521 - 0x1FFFFFFE88001u64, // 562949951881217 - 0x1FFFFFFE48001u64, // 562949951619073 - 0xfffffebc001u64, // - ] as &[u64], - ); - - let params_raw = build_bfv_params_arc(degree, plaintext_modulus, moduli, None); + let params_raw = BfvParamSet::from(BfvPreset::InsecureThresholdBfv512).build_arc(); let params = ArcBytes::from_bytes(&encode_bfv_params(¶ms_raw.clone())); // E3Parameters @@ -112,8 +101,11 @@ async fn test_trbfv_isolation() -> Result<()> { num_votes_per_voter, ); - let outputs = - e3_test_helpers::application::run_application(&inputs, params_raw, num_votes_per_voter); + let outputs = e3_test_helpers::application::run_application( + &inputs, + params_raw.clone(), + num_votes_per_voter, + ); // Encrypt the plaintext let ciphertexts = outputs @@ -163,10 +155,12 @@ async fn test_trbfv_isolation() -> Result<()> { .collect(); // Show summation result + let plaintext_modulus = params_raw.clone().plaintext(); + let mut expected_result = vec![0u64; 3]; for vals in &numbers { for j in 0..num_votes_per_voter { - expected_result[j] += vals[j]; + expected_result[j] = (expected_result[j] + vals[j]) % plaintext_modulus; } } diff --git a/tests/integration/base.sh b/tests/integration/base.sh index 1d5b06a072..9bd345b2c6 100755 --- a/tests/integration/base.sh +++ b/tests/integration/base.sh @@ -54,12 +54,10 @@ pnpm ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_5 --network localho heading "Request Committee" ENCODED_PARAMS=0x$($SCRIPT_DIR/lib/pack_e3_params.sh \ - --moduli 0x800000022a0001 \ - --moduli 0x800000021a0001 \ - --moduli 0x80000002120001 \ - --moduli 0x80000001f60001 \ - --degree 8192 \ - --plaintext-modulus 1032193) + --moduli 0xffffee001 \ + --moduli 0xffffc4001 \ + --degree 512 \ + --plaintext-modulus 10) sleep 4 diff --git a/tests/integration/persist.sh b/tests/integration/persist.sh index 809092120c..096050c966 100755 --- a/tests/integration/persist.sh +++ b/tests/integration/persist.sh @@ -50,12 +50,10 @@ pnpm ciphernode:add --ciphernode-address $CIPHERNODE_ADDRESS_5 --network localho heading "Request Committee" ENCODED_PARAMS=0x$($SCRIPT_DIR/lib/pack_e3_params.sh \ - --moduli 0x800000022a0001 \ - --moduli 0x800000021a0001 \ - --moduli 0x80000002120001 \ - --moduli 0x80000001f60001 \ - --degree 8192 \ - --plaintext-modulus 1032193) + --moduli 0xffffee001 \ + --moduli 0xffffc4001 \ + --degree 512 \ + --plaintext-modulus 10) pnpm committee:new \ --network localhost \ From 7ebfbbe7e4ab67574f05834ba98a837d3d6c03e6 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Mon, 26 Jan 2026 16:41:22 +0100 Subject: [PATCH 16/19] get rid of stale 2048 or wrong hardcoded params --- .../CRISP/crates/zk-inputs-wasm/Cargo.toml | 1 + .../CRISP/crates/zk-inputs-wasm/src/lib.rs | 12 ++++++---- examples/CRISP/crates/zk-inputs/src/lib.rs | 24 +++++++------------ .../enclave-contracts/test/Enclave.spec.ts | 9 ++++--- packages/enclave-sdk/src/types.ts | 7 +++--- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/examples/CRISP/crates/zk-inputs-wasm/Cargo.toml b/examples/CRISP/crates/zk-inputs-wasm/Cargo.toml index 67274e1eb3..f9d4553162 100644 --- a/examples/CRISP/crates/zk-inputs-wasm/Cargo.toml +++ b/examples/CRISP/crates/zk-inputs-wasm/Cargo.toml @@ -20,3 +20,4 @@ num-bigint = "0.4.6" [dev-dependencies] wasm-bindgen-test = "0.2" +e3-fhe-params = { workspace = true } diff --git a/examples/CRISP/crates/zk-inputs-wasm/src/lib.rs b/examples/CRISP/crates/zk-inputs-wasm/src/lib.rs index 72f859013d..55fdc262ea 100644 --- a/examples/CRISP/crates/zk-inputs-wasm/src/lib.rs +++ b/examples/CRISP/crates/zk-inputs-wasm/src/lib.rs @@ -236,8 +236,9 @@ impl ZKInputsGenerator { #[cfg(test)] mod tests { use super::*; + use e3_fhe_params::constants::insecure_512; use wasm_bindgen_test::*; - const DEFAULT_DEGREE: usize = 512; + const DEFAULT_DEGREE: usize = insecure_512::DEGREE; wasm_bindgen_test_configure!(run_in_browser); @@ -278,9 +279,12 @@ mod tests { #[wasm_bindgen_test] fn test_js_with_custom_params() { - let degree = 2048; - let plaintext_modulus = 1032193i64; - let moduli = vec![0x3FFFFFFF000001i64]; + let degree = insecure_512::DEGREE; + let plaintext_modulus = insecure_512::threshold::PLAINTEXT_MODULUS as i64; + let moduli = insecure_512::threshold::MODULI + .iter() + .map(|m| *m as i64) + .collect(); // Create generator with custom parameters. let generator = ZKInputsGenerator::new(degree, plaintext_modulus, moduli).unwrap(); diff --git a/examples/CRISP/crates/zk-inputs/src/lib.rs b/examples/CRISP/crates/zk-inputs/src/lib.rs index 63dd746f67..b6dc3df8c8 100644 --- a/examples/CRISP/crates/zk-inputs/src/lib.rs +++ b/examples/CRISP/crates/zk-inputs/src/lib.rs @@ -11,7 +11,7 @@ use crate::commitments::compute_commitment; use crisp_constants::get_default_paramset; use e3_fhe_params::build_bfv_params_arc; -use e3_fhe_params::BfvParamSet; +use e3_fhe_params::{constants::insecure_512, BfvParamSet, BfvPreset}; use eyre::{Context, Result}; use fhe::bfv::BfvParameters; use fhe::bfv::Ciphertext; @@ -312,12 +312,8 @@ mod tests { #[test] fn test_inputs_generation_with_custom_params() { - let generator = ZKInputsGenerator::from_set(BfvParamSet { - degree: 2048, - plaintext_modulus: 1032193, - moduli: &[0x3FFFFFFF000001], - error1_variance: None, - }); + let generator = + ZKInputsGenerator::from_set(BfvParamSet::from(BfvPreset::InsecureThresholdBfv512)); let public_key = generator .generate_public_key() .expect("failed to generate public key"); @@ -361,17 +357,13 @@ mod tests { #[test] fn test_get_bfv_params() { - let generator = ZKInputsGenerator::from_set(BfvParamSet { - degree: 2048, - plaintext_modulus: 1032193, - moduli: &[0x3FFFFFFF000001], - error1_variance: None, - }); + let generator = + ZKInputsGenerator::from_set(BfvParamSet::from(BfvPreset::InsecureThresholdBfv512)); let bfv_params = generator.get_bfv_params(); - assert!(bfv_params.degree() == 2048); - assert!(bfv_params.plaintext() == 1032193 as u64); - assert!(bfv_params.moduli() == &[0x3FFFFFFF000001]); + assert!(bfv_params.degree() == insecure_512::DEGREE); + assert!(bfv_params.plaintext() == insecure_512::threshold::PLAINTEXT_MODULUS); + assert!(bfv_params.moduli() == insecure_512::threshold::MODULI); } #[test] diff --git a/packages/enclave-contracts/test/Enclave.spec.ts b/packages/enclave-contracts/test/Enclave.spec.ts index 2eaaa491e2..a7c5e53fc4 100644 --- a/packages/enclave-contracts/test/Enclave.spec.ts +++ b/packages/enclave-contracts/test/Enclave.spec.ts @@ -45,9 +45,12 @@ describe("Enclave", function () { const abiCoder = ethers.AbiCoder.defaultAbiCoder(); - const polynomial_degree = ethers.toBigInt(2048); - const plaintext_modulus = ethers.toBigInt(1032193); - const moduli = [ethers.toBigInt("18014398492704769")]; // 0x3FFFFFFF000001 + const polynomial_degree = ethers.toBigInt(512); + const plaintext_modulus = ethers.toBigInt(10); + const moduli = [ + ethers.toBigInt("0xffffee001"), + ethers.toBigInt("0xffffc4001"), + ]; const encodedE3ProgramParams = abiCoder.encode( ["uint256", "uint256", "uint256[]"], diff --git a/packages/enclave-sdk/src/types.ts b/packages/enclave-sdk/src/types.ts index 701be1c1f0..71f0bb497b 100644 --- a/packages/enclave-sdk/src/types.ts +++ b/packages/enclave-sdk/src/types.ts @@ -259,9 +259,10 @@ export interface VerifiableEncryptionResult { /** * BFV parameters for an Enclave program request * Example for BFV - * 2048, // degree - * 1032193, // plaintext_modulus - * 0x3FFFFFFF000001, // moduli + * 512, // degree + * 10, // plaintext_modulus + * 0xffffee001, // moduli + * 0xffffc4001, // moduli */ export interface BfvParams { /** From 878e0c88c15fa1cb1b013d81553c8cc835a674b4 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Mon, 26 Jan 2026 16:46:27 +0100 Subject: [PATCH 17/19] update CRISP cargo lock --- examples/CRISP/Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/CRISP/Cargo.lock b/examples/CRISP/Cargo.lock index 952006a379..48f6cb8f20 100644 --- a/examples/CRISP/Cargo.lock +++ b/examples/CRISP/Cargo.lock @@ -2106,6 +2106,7 @@ dependencies = [ name = "crisp-zk-inputs" version = "0.1.0" dependencies = [ + "e3-fhe-params", "getrandom 0.2.16", "js-sys", "num-bigint", From a57db44a7b75338eea787e2c4feed6316a5e9692 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Mon, 26 Jan 2026 17:07:24 +0100 Subject: [PATCH 18/19] update exp plaintext mod ptx mod insecure --- tests/integration/fns.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/fns.sh b/tests/integration/fns.sh index d8119acc6d..1a09dd3182 100644 --- a/tests/integration/fns.sh +++ b/tests/integration/fns.sh @@ -4,7 +4,7 @@ set -euo pipefail # Stricter error handling # Get the script's location SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" -PLAINTEXT="1234,567890" +PLAINTEXT="4,0" ID=$(date +%s) if [[ "$SCRIPT_DIR" != "$(pwd)" ]]; then From 20c0d6898c86532b5cf88e167750e906aa7630f8 Mon Sep 17 00:00:00 2001 From: 0xjei Date: Mon, 26 Jan 2026 17:49:04 +0100 Subject: [PATCH 19/19] align to 1999 --- crates/tests/tests/integration_legacy.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/tests/tests/integration_legacy.rs b/crates/tests/tests/integration_legacy.rs index 46fcaf30a1..d3f5eb5604 100644 --- a/crates/tests/tests/integration_legacy.rs +++ b/crates/tests/tests/integration_legacy.rs @@ -167,6 +167,7 @@ fn aggregate_public_key(shares: &Vec) -> Result { } #[actix::test] +#[ignore = "Needs to be deleted after #1999 is merged"] async fn test_public_key_aggregation_and_decryption() -> Result<()> { use tracing_subscriber::{fmt, EnvFilter}; @@ -300,6 +301,7 @@ async fn test_public_key_aggregation_and_decryption() -> Result<()> { } #[actix::test] +#[ignore = "Needs to be ported to trBFV system after Sync is completed"] async fn test_stopped_keyshares_retain_state() -> Result<()> { let e3_id = E3id::new("1234", 1); let (rng, cn1_address, cn1_data, cn2_address, cn2_data, cipher, history, params, crpoly) = { @@ -535,6 +537,7 @@ async fn test_p2p_actor_forwards_events_to_network() -> Result<()> { } #[actix::test] +#[ignore = "Needs to be ported to trBFV system"] async fn test_duplicate_e3_id_with_different_chain_id() -> Result<()> { // Setup let (bus, rng, seed, params, crpoly, _, _) = get_common_setup(None)?;