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
32 changes: 32 additions & 0 deletions Cargo.lock

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

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ members = [
"crates/wasm",
"crates/parity-matrix",
"crates/polynomial",
"crates/zk-helpers"
"crates/zk-helpers",
"crates/pvss",
"crates/pvss-cli"
]
exclude = [
"examples/CRISP",
Expand Down Expand Up @@ -102,6 +104,7 @@ e3-trbfv = { version = "0.1.7", path = "./crates/trbfv" }
e3-utils = { version = "0.1.7", path = "./crates/utils" }
e3-safe = { version = "0.1.7", path = "./crates/safe" }
e3-zk-helpers = { version = "0.1.7", path = "./crates/zk-helpers" }
e3-pvss = { version = "0.1.7", path = "./crates/pvss" }

actix = "=0.13.5"
actix-web = "=4.11.0"
Expand Down
2 changes: 1 addition & 1 deletion circuits/lib/src/configs/insecure/bfv.nr
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pk_bfv (CIRCUIT 0 - PUBLIC KEY BFV)
************************************/

// pk_bfv - bit parameters
pub global PK_BFV_BIT_PK: u32 = 51;
pub global PK_BFV_BIT_PK: u32 = 50;

/************************************
-------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion circuits/lib/src/configs/production/bfv.nr
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pk_bfv (CIRCUIT 0 - PUBLIC KEY BFV)

// pk_bfv - bit parameters

pub global PK_BFV_BIT_PK: u32 = 57;
pub global PK_BFV_BIT_PK: u32 = 58;

/************************************
-------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions crates/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ COPY crates/trbfv/Cargo.toml ./trbfv/Cargo.toml
COPY crates/utils/Cargo.toml ./utils/Cargo.toml
COPY crates/wasm/Cargo.toml ./wasm/Cargo.toml
COPY crates/zk-helpers/Cargo.toml ./zk-helpers/Cargo.toml
COPY crates/pvss/Cargo.toml ./pvss/Cargo.toml
COPY crates/pvss-cli/Cargo.toml ./pvss-cli/Cargo.toml

RUN echo 'fn main() { println!("cargo:warning=dependency cache build"); }' > ./entrypoint/build.rs
RUN echo 'fn main() { println!("cargo:warning=dependency cache build"); }' > ./cli/build.rs
Expand Down
4 changes: 3 additions & 1 deletion crates/fhe-params/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ pub use builder::{
};
#[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};
pub use presets::{
BfvParamSet, BfvPreset, ParameterType, PresetError, PresetMetadata, PresetSearchDefaults,
};
31 changes: 29 additions & 2 deletions crates/fhe-params/src/presets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ pub enum BfvPreset {
SecureDkg8192,
}

/// Parameter type for BFV presets
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ParameterType {
/// Threshold BFV (TRBFV) parameters
THRESHOLD,
/// DKG parameters (BFV)
DKG,
}

/// Metadata describing a BFV preset configuration
///
/// This struct contains high-level information about a preset, including
Expand All @@ -80,6 +89,8 @@ pub struct PresetMetadata {
/// Higher values provide stronger security guarantees but may require
/// larger parameters. Typically 80 for secure presets, 2 for insecure.
pub lambda: usize,
/// Parameter type (BFV / trBFV).
pub parameter_type: ParameterType,
}

/// Default search parameters for BFV parameter generation
Expand Down Expand Up @@ -218,17 +229,33 @@ impl BfvPreset {

pub fn metadata(&self) -> PresetMetadata {
match self {
BfvPreset::InsecureThresholdBfv512 | BfvPreset::InsecureDkg512 => PresetMetadata {
BfvPreset::InsecureThresholdBfv512 => PresetMetadata {
name: self.name(),
degree: insecure_512::DEGREE,
num_parties: insecure_512::NUM_PARTIES,
lambda: DEFAULT_INSECURE_LAMBDA,
parameter_type: ParameterType::THRESHOLD,
},
BfvPreset::InsecureDkg512 => PresetMetadata {
name: self.name(),
degree: insecure_512::DEGREE,
num_parties: insecure_512::NUM_PARTIES,
lambda: DEFAULT_INSECURE_LAMBDA,
parameter_type: ParameterType::DKG,
},
BfvPreset::SecureThresholdBfv8192 => PresetMetadata {
name: self.name(),
degree: secure_8192::DEGREE,
num_parties: secure_8192::NUM_PARTIES,
lambda: DEFAULT_SECURE_LAMBDA,
parameter_type: ParameterType::THRESHOLD,
},
BfvPreset::SecureThresholdBfv8192 | BfvPreset::SecureDkg8192 => PresetMetadata {
BfvPreset::SecureDkg8192 => PresetMetadata {
name: self.name(),
degree: secure_8192::DEGREE,
num_parties: secure_8192::NUM_PARTIES,
lambda: DEFAULT_SECURE_LAMBDA,
parameter_type: ParameterType::DKG,
},
}
}
Expand Down
13 changes: 13 additions & 0 deletions crates/pvss-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "e3-pvss-cli"
version.workspace = true
edition.workspace = true
license.workspace = true
description = "PVSS CLI for artifact generation"
repository = "https://github.com/gnosisguild/enclave/crates/pvss-cli"
Comment thread
0xjei marked this conversation as resolved.
Comment thread
0xjei marked this conversation as resolved.

[dependencies]
e3-pvss = { workspace = true }
e3-fhe-params = { workspace = true }
clap = { workspace = true }
anyhow = { workspace = true }
120 changes: 120 additions & 0 deletions crates/pvss-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// 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 anyhow::{anyhow, Context, Result};
use clap::Parser;
use e3_fhe_params::{BfvParamSet, BfvPreset};
use e3_pvss::circuits::pk_bfv::circuit::{PkBfvCircuit, PkBfvCodegenInput};
use e3_pvss::circuits::pk_bfv::codegen::write_artifacts;
use e3_pvss::registry::CircuitRegistry;
use e3_pvss::sample;
use e3_pvss::traits::Circuit;
use e3_pvss::traits::CircuitCodegen;
use std::path::PathBuf;
use std::sync::Arc;

/// Minimal PVSS CLI for generating circuit artifacts.
#[derive(Debug, Parser)]
#[command(name = "pvss-cli")]
struct Cli {
/// List all available circuits and exit.
#[arg(long)]
list_circuits: bool,
/// Circuit name to generate artifacts for (e.g. pk-bfv).
#[arg(long, required_unless_present = "list_circuits")]
circuit: Option<String>,
/// BFV preset name (must match circuit's parameter type).
#[arg(long, required_unless_present = "list_circuits")]
preset: Option<String>,
/// Output directory for generated artifacts.
#[arg(long, default_value = "output")]
output: PathBuf,
}

/// Parse a preset name into a BFV preset.
fn parse_preset(name: &str) -> Result<BfvPreset> {
BfvPreset::from_name(name).map_err(|_| {
let available = BfvPreset::list().join(", ");
anyhow!("unknown preset: {name}. Available: {available}")
})
}

fn main() -> Result<()> {
let args = Cli::parse();

// Register all circuits in the registry (metadata only).
let mut registry = CircuitRegistry::new();
registry.register(Arc::new(PkBfvCircuit));

// Handle list circuits flag.
if args.list_circuits {
let circuits = registry.list_circuits();
println!("Available circuits:");
for circuit_name in circuits {
if let Ok(circuit_meta) = registry.get(&circuit_name) {
println!(
" {} - params_type: {:?}, n_recursive_proofs: {}, pub_inputs: {}",
circuit_name,
circuit_meta.supported_parameter(),
circuit_meta.n_recursive_proofs(),
circuit_meta.n_public_inputs()
);
}
}
return Ok(());
}

// Unwrap required arguments (clap ensures they're present when list_circuits is false).
let circuit = args.circuit.unwrap();
let preset = parse_preset(&args.preset.unwrap())?;

std::fs::create_dir_all(&args.output)
.with_context(|| format!("failed to create output dir {}", args.output.display()))?;

// Validate circuit exists in registry.
let circuit_meta = registry.get(&circuit).map_err(|_| {
let available = registry.list_circuits().join(", ");
anyhow!("unknown circuit: {}. Available: {}", circuit, available)
})?;

// Validate preset parameter type matches circuit's supported parameter type.
let preset_param_type = preset.metadata().parameter_type;
let circuit_param_type = circuit_meta.supported_parameter();
if preset_param_type != circuit_param_type {
return Err(anyhow!(
"preset has parameter type {:?}, but circuit {} requires {:?}",
preset_param_type,
circuit,
circuit_param_type
));
}

// Generate artifacts based on circuit name from registry.
let params = BfvParamSet::from(preset).build_arc();
let sample = sample::generate_sample(&params);
let circuit_name = circuit_meta.name();
let artifacts = match circuit_name {
name if name == <PkBfvCircuit as Circuit>::NAME => {
let circuit = PkBfvCircuit;
circuit.codegen(PkBfvCodegenInput {
preset,
public_key: sample.public_key,
})?
}
name => return Err(anyhow!("circuit {} not yet implemented", name)),
};

write_artifacts(
&artifacts.toml,
&artifacts.template,
&artifacts.configs,
&artifacts.wrapper,
Some(args.output.as_path()),
)?;

println!("Artifacts written to {}", args.output.display());
Ok(())
}
25 changes: 25 additions & 0 deletions crates/pvss/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "e3-pvss"
version.workspace = true
edition.workspace = true
license.workspace = true
description = "PVSS core codegen and computation crate"
repository = "https://github.com/gnosisguild/enclave/crates/pvss"
Comment thread
0xjei marked this conversation as resolved.
Comment thread
0xjei marked this conversation as resolved.

[dependencies]
e3-polynomial = { workspace = true }
fhe = { workspace = true }
fhe-math = { workspace = true }
e3-fhe-params = { workspace = true }
e3-zk-helpers = { workspace = true }
num-bigint = { workspace = true }
num-traits = { workspace = true }
rand = { workspace = true }
rayon = { workspace = true }
itertools = "0.14.0"
serde = { workspace = true }
serde_json = { workspace = true }
toml = "0.8.23"
anyhow = { workspace = true }
tempfile = { workspace = true }
thiserror = { workspace = true }
7 changes: 7 additions & 0 deletions crates/pvss/src/circuits/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// 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.

pub mod pk_bfv;
70 changes: 70 additions & 0 deletions crates/pvss/src/circuits/pk_bfv/circuit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// 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::circuits::pk_bfv::codegen;
use crate::circuits::pk_bfv::computation::{Bits, Bounds, Witness};
use crate::errors::CodegenError;
use crate::traits::{Circuit, CircuitCodegen, CircuitComputation, Computation};
use crate::types::{Artifacts, DkgInputType};
use e3_fhe_params::{BfvPreset, ParameterType};
use fhe::bfv::{BfvParameters, PublicKey};

#[derive(Debug)]
pub struct PkBfvCircuit;

#[derive(Debug)]
pub struct PkBfvComputationOutput {
pub bounds: Bounds,
pub bits: Bits,
pub witness: Witness,
}

#[derive(Debug, Clone)]
pub struct PkBfvCodegenInput {
pub preset: BfvPreset,
pub public_key: PublicKey,
}

impl Circuit for PkBfvCircuit {
const NAME: &'static str = "pk-bfv";
const PREFIX: &'static str = "PK_BFV";
const SUPPORTED_PARAMETER: ParameterType = ParameterType::DKG;
const DKG_INPUT_TYPE: Option<DkgInputType> = None;
const N_PROOFS: usize = 1;
const N_PUBLIC_INPUTS: usize = 1;
}

impl CircuitCodegen for PkBfvCircuit {
type Input = PkBfvCodegenInput;
type Error = CodegenError;

fn codegen(&self, input: Self::Input) -> Result<Artifacts, Self::Error> {
codegen::codegen(input.preset, input.public_key)
}
}

impl CircuitComputation for PkBfvCircuit {
type Params = BfvParameters;
type Input = PublicKey;
type Output = PkBfvComputationOutput;
type Error = CodegenError;

fn compute(
&self,
params: &Self::Params,
input: &Self::Input,
) -> Result<Self::Output, Self::Error> {
let bounds = Bounds::compute(params, &())?;
let bits = Bits::compute(params, &bounds)?;
let witness = Witness::compute(params, input)?;

Ok(PkBfvComputationOutput {
bounds,
bits,
witness,
})
}
}
Loading