Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ e3-trbfv = { version = "0.1.8", path = "./crates/trbfv" }
e3-utils = { version = "0.1.8", path = "./crates/utils" }
e3-safe = { version = "0.1.8", path = "./crates/safe" }
e3-zk-helpers = { version = "0.1.8", path = "./crates/zk-helpers" }
e3-parity-matrix = { version = "0.1.8", path = "./crates/parity-matrix" }

actix = "=0.13.5"
actix-web = "=4.11.0"
Expand Down
6 changes: 3 additions & 3 deletions circuits/lib/src/configs/insecure/dkg.nr
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ share_computation_sk (CIRCUIT 2a)
************************************/

// share_computation_sk - bit parameters
pub global SHARE_COMPUTATION_BIT_SHARE: u32 = 37;
pub global SHARE_COMPUTATION_SK_BIT_SECRET: u32 = 2;
pub global SHARE_COMPUTATION_BIT_SHARE: u32 = 36;
pub global SHARE_COMPUTATION_SK_BIT_SECRET: u32 = 1;

// share_computation_sk - configs
pub global SHARE_COMPUTATION_SK_CONFIGS: ShareComputationConfigs<L_THRESHOLD> =
Expand All @@ -62,7 +62,7 @@ share_computation_e_sm (CIRCUIT 2b)
************************************/

// share_computation_e_sm - bit parameters
pub global SHARE_COMPUTATION_E_SM_BIT_SECRET: u32 = 18;
pub global SHARE_COMPUTATION_E_SM_BIT_SECRET: u32 = 24;

// verify_shares - configs
pub global SHARE_COMPUTATION_E_SM_CONFIGS: ShareComputationConfigs<L_THRESHOLD> =
Expand Down
8 changes: 4 additions & 4 deletions circuits/lib/src/configs/secure/dkg.nr
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ share_computation_sk (CIRCUIT 2a)
************************************/

// share_computation_sk - bit parameters
pub global SHARE_COMPUTATION_SK_BIT_SHARE: u32 = 54;
pub global SHARE_COMPUTATION_SK_BIT_SECRET_SK: u32 = 2;
pub global SHARE_COMPUTATION_BIT_SHARE: u32 = 53;
pub global SHARE_COMPUTATION_SK_BIT_SECRET: u32 = 1;

// share_computation_sk - configs
pub global SHARE_COMPUTATION_SK_CONFIGS: ShareComputationConfigs<L_THRESHOLD> =
Expand All @@ -74,9 +74,9 @@ share_computation_e_sm (CIRCUIT 2b)
************************************/

// share_computation_e_sm - bit parameters
pub global SHARE_COMPUTATION_E_SM_BIT_E_SM: u32 = 187;
pub global SHARE_COMPUTATION_E_SM_BIT_SECRET: u32 = 192;

// share_computation_e_sm - configs
// verify_shares - configs
pub global SHARE_COMPUTATION_E_SM_CONFIGS: ShareComputationConfigs<L_THRESHOLD> =
ShareComputationConfigs::new(QIS_THRESHOLD);

Expand Down
4 changes: 2 additions & 2 deletions crates/fhe-params/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ pub mod search;

pub use builder::{
build_bfv_params, build_bfv_params_arc, build_bfv_params_from_set,
build_bfv_params_from_set_arc,
build_bfv_params_from_set_arc, build_pair_for_preset,
};
#[cfg(feature = "abi-encoding")]
pub use encoding::{decode_bfv_params, decode_bfv_params_arc, encode_bfv_params, EncodingError};
pub use presets::{
default_param_set, BfvParamSet, BfvPreset, ParameterType, PresetError, PresetMetadata,
PresetSearchDefaults, DEFAULT_BFV_PRESET,
PresetSearchDefaults, SecurityTier, DEFAULT_BFV_PRESET,
};
63 changes: 63 additions & 0 deletions crates/fhe-params/src/presets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,37 @@ pub enum ParameterType {
DKG,
}

/// Security tier for BFV presets
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SecurityTier {
/// Insecure security tier
INSECURE,
/// Secure security tier
SECURE,
}

impl SecurityTier {
/// Config path segment for Noir (e.g. `configs::{}::threshold`).
pub fn as_config_str(self) -> &'static str {
match self {
SecurityTier::INSECURE => "insecure",
SecurityTier::SECURE => "secure",
}
}
}

impl core::str::FromStr for SecurityTier {
type Err = PresetError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.trim().to_lowercase().as_str() {
"insecure" => Ok(Self::INSECURE),
"secure" => Ok(Self::SECURE),
_ => Err(PresetError::UnknownPreset(s.to_string())),
}
}
}

/// Metadata describing a BFV preset configuration
///
/// This struct contains high-level information about a preset, including
Expand All @@ -94,6 +125,10 @@ pub struct PresetMetadata {
/// 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 moduli (l) - the number of moduli used in the ciphertext space
///
/// This determines the size of the ciphertext space.
pub num_moduli: usize,
/// Number of parties (n) - the number of ciphernodes in the system supported by
/// the preset.
///
Expand All @@ -106,6 +141,8 @@ pub struct PresetMetadata {
pub lambda: usize,
/// Parameter type (DKG (BFV) / Threshold (trBFV)).
pub parameter_type: ParameterType,
/// Security tier (e.g. for Noir `configs::{}::threshold`). Use [`SecurityTier::as_config_str`] for the path segment.
pub security: SecurityTier,
}

/// Default search parameters for BFV parameter generation
Expand Down Expand Up @@ -230,6 +267,24 @@ impl BfvPreset {
}
}

/// Parses "insecure"|"secure" or λ (e.g. 2|80) into the threshold preset. Uses [`PAIR_PRESETS`] and [`PresetMetadata`].
pub fn from_security_config_name(name: &str) -> Result<Self, PresetError> {
let s = name.trim();
if let Ok(lambda) = s.parse::<usize>() {
return Self::PAIR_PRESETS
.iter()
.copied()
.find(|p| p.metadata().lambda == lambda)
.ok_or_else(|| PresetError::UnknownPreset(format!("lambda {lambda}")));
}
let tier: SecurityTier = s.parse()?;
Self::PAIR_PRESETS
.iter()
.copied()
.find(|p| p.metadata().security == tier)
.ok_or_else(|| PresetError::UnknownPreset(name.to_string()))
}

pub fn list() -> Vec<&'static str> {
Self::ALL.iter().map(BfvPreset::name).collect()
}
Expand Down Expand Up @@ -260,30 +315,38 @@ impl BfvPreset {
BfvPreset::InsecureThreshold512 => PresetMetadata {
name: self.name(),
degree: insecure_512::DEGREE,
num_moduli: insecure_512::threshold::MODULI.len(),
num_parties: insecure_512::NUM_PARTIES,
lambda: DEFAULT_INSECURE_LAMBDA,
parameter_type: ParameterType::THRESHOLD,
security: SecurityTier::INSECURE,
},
BfvPreset::InsecureDkg512 => PresetMetadata {
name: self.name(),
degree: insecure_512::DEGREE,
num_moduli: insecure_512::dkg::MODULI.len(),
num_parties: insecure_512::NUM_PARTIES,
lambda: DEFAULT_INSECURE_LAMBDA,
parameter_type: ParameterType::DKG,
security: SecurityTier::INSECURE,
},
BfvPreset::SecureThreshold8192 => PresetMetadata {
name: self.name(),
degree: secure_8192::DEGREE,
num_moduli: secure_8192::threshold::MODULI.len(),
num_parties: secure_8192::NUM_PARTIES,
lambda: DEFAULT_SECURE_LAMBDA,
parameter_type: ParameterType::THRESHOLD,
security: SecurityTier::SECURE,
},
BfvPreset::SecureDkg8192 => PresetMetadata {
name: self.name(),
degree: secure_8192::DEGREE,
num_moduli: secure_8192::dkg::MODULI.len(),
num_parties: secure_8192::NUM_PARTIES,
lambda: DEFAULT_SECURE_LAMBDA,
parameter_type: ParameterType::DKG,
security: SecurityTier::SECURE,
},
}
}
Expand Down
10 changes: 9 additions & 1 deletion crates/parity-matrix/src/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use crate::errors::{ConstraintError, MathError, ParityMatrixError, ParityMatrixResult};
use crate::math::mod_inverse;
use crate::math::mod_pow;
use num_bigint::BigUint;
use num_bigint::{BigInt, BigUint};
use num_traits::{One, Zero};
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -105,6 +105,14 @@ impl ParityMatrix {
pub fn get(&self, row: usize, col: usize) -> &BigUint {
&self.data[row][col]
}

/// Converts the matrix to rows of [`BigInt`] (non-negative; elements are in `[0, q)`).
pub fn to_bigint_rows(&self) -> Vec<Vec<BigInt>> {
self.data
.iter()
.map(|row| row.iter().map(|c| BigInt::from(c.clone())).collect())
.collect()
}
}

impl From<ParityMatrix> for Vec<Vec<BigUint>> {
Expand Down
18 changes: 18 additions & 0 deletions crates/polynomial/src/crt_polynomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//! CRT (Chinese Remainder Theorem) polynomial representation.

use crate::polynomial::Polynomial;
use crate::utils::reduce;
use fhe_math::rq::{Poly, Representation};
use num_bigint::BigInt;
#[cfg(feature = "serde")]
Expand Down Expand Up @@ -52,6 +53,23 @@ impl CrtPolynomial {
Self { limbs }
}

/// Builds a CRT polynomial from a polynomial mod Q (Q>>128) and moduli.
///
/// # Arguments
///
/// * `coeffs` - Polynomial coefficients mod Q (Q>>128).
/// * `moduli` - One modulus per limb.
pub fn from_mod_q_polynomial(poly: &Vec<BigInt>, moduli: &[u64]) -> Self {
let limbs: Vec<Vec<BigInt>> = moduli
.iter()
.map(|&qi| {
let qi_big = BigInt::from(qi);
poly.iter().map(|c| reduce(c, &qi_big)).collect()
})
.collect();
Self::from_bigint_vectors(limbs)
}

/// Builds a `CrtPolynomial` from an fhe-math `Poly` in PowerBasis representation.
///
/// Used to prepare inputs for ZK circuits by converting FHE BFV ciphertext polynomials
Expand Down
2 changes: 2 additions & 0 deletions crates/zk-helpers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ serde = { workspace = true }
serde_json = { workspace = true }
toml = "0.8.23"
itertools = "0.14.0"
ndarray = { workspace = true }
e3-parity-matrix = { workspace = true }

[dev-dependencies]
tempfile = { workspace = true }
Expand Down
31 changes: 18 additions & 13 deletions crates/zk-helpers/README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
# zk-helpers

ZK circuit artifact generation for the Noir prover.
ZK circuit artifact generation for the Noir prover. Produces `configs.nr` and optionally
`Prover.toml` for the Enclave circuits.

## zk-cli

Generate `Prover.toml` and `configs.nr` for a circuit.
Generate `configs.nr` for a circuit; use `--toml` to also generate `Prover.toml`.

```bash
# List circuits
cargo run -p e3-zk-helpers --bin zk_cli -- --list_circuits

# Generate artifacts (default: output/)
cargo run -p e3-zk-helpers --bin zk_cli -- --circuit pk-bfv --preset default
# Generate configs.nr only (default)
cargo run -p e3-zk-helpers --bin zk_cli -- --circuit pk --preset insecure
cargo run -p e3-zk-helpers --bin zk_cli -- --circuit share-computation --preset insecure

# Custom output dir; skip Prover.toml (only configs.nr)
cargo run -p e3-zk-helpers --bin zk_cli -- --circuit pk-bfv --preset default --output ./artifacts --toml
# Generate configs.nr and Prover.toml (--witness required for share-computation)
cargo run -p e3-zk-helpers --bin zk_cli -- --circuit pk --preset insecure --toml
cargo run -p e3-zk-helpers --bin zk_cli -- --circuit share-computation --preset insecure --witness secret-key --toml
cargo run -p e3-zk-helpers --bin zk_cli -- --circuit share-computation --preset secure --witness smudging-noise --toml
```

| Flag | Description |
| ------------------ | -------------------------------------------------- |
| `--list_circuits` | List circuits and exit |
| `--circuit <name>` | Circuit (e.g. `pk-bfv`) |
| `--preset <name>` | BFV preset (must match circuit) |
| `--output <path>` | Output dir (default: `output`) |
| `--toml` | Skip writing Prover.toml; always writes configs.nr |
| Flag | Description |
| ------------------ | ----------------------------------------------------------------------------- |
| `--list_circuits` | List circuits and exit |
| `--circuit <name>` | Circuit: `pk` or `share-computation` |
| `--preset <name>` | Security preset: `insecure` (512) or `secure` (8192) |
| `--witness <type>` | For `share-computation` when using `--toml`: `secret-key` or `smudging-noise` |
| `--output <path>` | Output dir (default: `output`) |
| `--toml` | Also write Prover.toml (default: configs.nr only) |
Loading
Loading