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
8 changes: 4 additions & 4 deletions crates/bfv-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use anyhow::{anyhow, Result};
use e3_fhe_params::{build_bfv_params_arc, DEFAULT_BFV_PRESET};
use e3_zk_helpers::circuits::threshold::user_data_encryption::circuit::UserDataEncryptionCircuitInput;
use e3_zk_helpers::circuits::threshold::user_data_encryption::Witness as UserDataEncryptionWitness;
use e3_zk_helpers::circuits::threshold::user_data_encryption::Inputs as UserDataEncryptionInputs;
use e3_zk_helpers::circuits::Computation;
use fhe::bfv::{Ciphertext, Encoding, Plaintext, PublicKey, SecretKey};
use fhe::Error as FheError;
Expand Down Expand Up @@ -101,16 +101,16 @@ where
let plaintext = Plaintext::try_encode(&data, Encoding::poly(), &params)
.map_err(|e: FheError| anyhow!("Error encoding plaintext: {}", e))?;

let witness = UserDataEncryptionWitness::compute(
let inputs = UserDataEncryptionInputs::compute(
DEFAULT_BFV_PRESET,
&UserDataEncryptionCircuitInput {
public_key: pk,
plaintext: plaintext,
},
)?;

let encrypted_data = witness.ciphertext.clone();
let circuit_inputs = witness.to_json()?.to_string();
let encrypted_data = inputs.ciphertext.clone();
let circuit_inputs = inputs.to_json()?.to_string();

Ok(VerifiableEncryptionResult {
encrypted_data,
Expand Down
25 changes: 13 additions & 12 deletions crates/zk-helpers/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# zk-helpers

ZK circuit artifact generation for the Noir prover. Produces `configs.nr` and optionally
`Prover.toml` for the Enclave circuits.
`Prover.toml` for the Enclave circuits. The Prover.toml contains circuit inputs for Nargo,
which executes them to produce witnesses for proof generation.

## zk-cli

Expand All @@ -15,20 +16,20 @@ cargo run -p e3-zk-helpers --bin zk_cli -- --list_circuits
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

# Generate configs.nr and Prover.toml (--witness required for share-computation)
# Generate configs.nr and Prover.toml (--inputs 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 insecure --inputs secret-key --toml

# Generate only Prover.toml (no configs.nr), e.g. for benchmarks where circuits use lib configs
cargo run -p e3-zk-helpers --bin zk_cli -- --circuit pk --preset insecure --toml --no-configs
```

| Flag | Description |
| ------------------ | ------------------------------------------------------------------------------ |
| `--list_circuits` | List circuits and exit |
| `--circuit <name>` | Circuit name (e.g. `pk`, `share-computation`, `threshold-share-decryption`) |
| `--preset <name>` | Security preset: `insecure` (512) or `secure` (8192) |
| `--witness <type>` | For DKG witness circuits when using `--toml`: `secret-key` or `smudging-noise` |
| `--output <path>` | Output dir (default: `output`) |
| `--toml` | Also write Prover.toml (default: configs.nr only) |
| `--no-configs` | With `--toml`: do not write configs.nr (e.g. for circuit benchmarks) |
| Flag | Description |
| ------------------ | ---------------------------------------------------------------------------- |
| `--list_circuits` | List circuits and exit |
| `--circuit <name>` | Circuit name (e.g. `pk`, `share-computation`, `threshold-share-decryption`) |
| `--preset <name>` | Security preset: `insecure` (512) or `secure` (8192) |
| `--inputs <type>` | For DKG circuit inputs when using `--toml`: `secret-key` or `smudging-noise` |
| `--output <path>` | Output dir (default: `output`) |
| `--toml` | Also write Prover.toml (default: configs.nr only) |
| `--no-configs` | With `--toml`: do not write configs.nr (e.g. for circuit benchmarks) |
32 changes: 16 additions & 16 deletions crates/zk-helpers/src/bin/zk_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ fn clear_terminal() {
let _ = std::io::stdout().flush();
}

/// Print a summary of what will be generated (circuit, preset, witness, output, artifacts).
/// Print a summary of what will be generated (circuit, preset, inputs, output, artifacts).
fn print_generation_info(
circuit: &str,
preset: BfvPreset,
has_witness: bool,
has_inputs: bool,
dkg_input_type: DkgInputType,
output: &std::path::Path,
write_prover_toml: bool,
Expand All @@ -87,9 +87,9 @@ fn print_generation_info(
meta.degree,
meta.num_moduli
);
if has_witness {
if has_inputs {
println!(
" Witness: {}",
" Inputs: {}",
match dkg_input_type {
DkgInputType::SecretKey => "secret-key",
DkgInputType::SmudgingNoise => "smudging-noise",
Expand Down Expand Up @@ -151,9 +151,9 @@ struct Cli {
/// Preset: "insecure"|"secure" or λ (2|80). Drives both threshold and DKG params.
#[arg(long, required_unless_present = "list_circuits")]
preset: Option<String>,
/// For share-computation only: witness type "secret-key" or "smudging-noise". Required when writing Prover.toml for share-computation. Ignored for pk (always secret key).
/// For share-computation only: inputs type "secret-key" or "smudging-noise". Required when writing Prover.toml for share-computation. Ignored for pk (always secret key).
#[arg(long)]
witness: Option<String>,
inputs: Option<String>,
/// Output directory for generated artifacts.
#[arg(long, default_value = "output")]
output: PathBuf,
Expand Down Expand Up @@ -227,24 +227,24 @@ fn main() -> Result<()> {

let write_prover_toml = args.toml;
let no_configs = args.no_configs && args.toml;
// DKG circuits have a witness-type choice (secret-key vs smudging-noise) excluding `pk` or C0 circuit.
let has_witness_type = circuit_meta.name() == ShareComputationCircuit::NAME
// DKG circuits have a inputs-type choice (secret-key vs smudging-noise) excluding `pk` or C0 circuit.
let has_inputs_type = circuit_meta.name() == ShareComputationCircuit::NAME
|| circuit_meta.name() == ShareEncryptionCircuit::NAME
|| circuit_meta.name() == DkgShareDecryptionCircuit::NAME;

let dkg_input_type = if has_witness_type {
// Share-computation: require --witness when generating Prover.toml; default secret-key for configs-only.
let witness_str = if !args.toml {
args.witness.as_deref().unwrap_or("secret-key")
let dkg_input_type = if has_inputs_type {
// Share-computation: require --inputs when generating Prover.toml; default secret-key for configs-only.
let inputs_str = if !args.toml {
args.inputs.as_deref().unwrap_or("secret-key")
} else {
args.witness.as_deref().ok_or_else(|| {
args.inputs.as_deref().ok_or_else(|| {
anyhow!(
"circuit {} requires --witness (secret-key or smudging-noise) when writing Prover.toml",
"circuit {} requires --inputs (secret-key or smudging-noise) when writing Prover.toml",
circuit
)
})?
};
let arg = parse_input_type(witness_str)?;
let arg = parse_input_type(inputs_str)?;
match arg {
DkgInputTypeArg::SecretKey => DkgInputType::SecretKey,
DkgInputTypeArg::SmudgingNoise => DkgInputType::SmudgingNoise,
Expand All @@ -258,7 +258,7 @@ fn main() -> Result<()> {
print_generation_info(
&circuit,
preset,
has_witness_type,
has_inputs_type,
dkg_input_type.clone(),
&args.output,
write_prover_toml,
Expand Down
4 changes: 2 additions & 2 deletions crates/zk-helpers/src/circuits/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
use crate::errors::CircuitsErrors;
use std::path::Path;

/// Prover TOML file content (witness and circuit inputs).
/// Prover TOML file content (circuit inputs).
pub type CodegenToml = String;
/// Noir configs file content (global constants for the prover).
pub type CodegenConfigs = String;

/// Generated files for a circuit: Prover TOML and Noir configs.
#[derive(Debug, Clone)]
pub struct Artifacts {
/// Prover.toml content (witness and circuit inputs).
/// Prover.toml content (circuit inputs).
pub toml: CodegenToml,
/// configs.nr content (constants for the Noir prover).
pub configs: CodegenConfigs,
Expand Down
6 changes: 3 additions & 3 deletions crates/zk-helpers/src/circuits/computation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! Computation traits and artifact types.
//!
//! [`Computation`] is a generic trait for computing values from parameters and input.
//! [`CircuitComputation`] extends it for circuits that produce witness/bounds/bits.
//! [`CircuitComputation`] extends it for circuits that produce inputs/bounds/bits.
//! [`Toml`] and [`Configs`] are the string types used for Prover.toml and configs.nr.

/// Variant for input types for DKG.
Expand Down Expand Up @@ -38,13 +38,13 @@ pub trait Computation: Sized {
}
}

/// Circuit-specific computation: parameters and input produce bounds, bits, witness, etc.
/// Circuit-specific computation: parameters and input produce bounds, bits, circuit inputs, etc.
pub trait CircuitComputation: crate::registry::Circuit {
type Preset;
type Input;
type Output;
type Error;

/// Computes circuit-specific data (bounds, bits, witness) from parameters and input.
/// Computes circuit-specific data (bounds, bits, inputs) from parameters and input.
fn compute(preset: Self::Preset, input: &Self::Input) -> Result<Self::Output, Self::Error>;
}
14 changes: 6 additions & 8 deletions crates/zk-helpers/src/circuits/dkg/pk/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

use crate::circuits::dkg::pk::circuit::PkCircuit;
use crate::circuits::dkg::pk::circuit::PkCircuitInput;
use crate::circuits::dkg::pk::computation::{Bits, PkComputationOutput, Witness};
use crate::circuits::dkg::pk::computation::{Bits, Inputs, PkComputationOutput};
use crate::Artifacts;
use crate::Circuit;
use crate::CircuitCodegen;
Expand All @@ -27,20 +27,18 @@ impl CircuitCodegen for PkCircuit {
type Error = CircuitsErrors;

fn codegen(&self, preset: Self::Preset, input: &Self::Input) -> Result<Artifacts, Self::Error> {
let PkComputationOutput { witness, bits, .. } = PkCircuit::compute(preset, input)?;
let PkComputationOutput { inputs, bits, .. } = PkCircuit::compute(preset, input)?;

let toml = generate_toml(witness)?;
let toml = generate_toml(inputs)?;
let configs = generate_configs(preset, &bits);

Ok(Artifacts { toml, configs })
}
}

/// Builds the Prover TOML string from the pk witness (pk0is, pk1is).
pub fn generate_toml(witness: Witness) -> Result<CodegenToml, CircuitsErrors> {
let json = witness
.to_json()
.map_err(|e| CircuitsErrors::SerdeJson(e))?;
/// Builds the Prover TOML string from the pk input (pk0is, pk1is).
pub fn generate_toml(inputs: Inputs) -> Result<CodegenToml, CircuitsErrors> {
let json = inputs.to_json().map_err(|e| CircuitsErrors::SerdeJson(e))?;

Ok(toml::to_string(&json)?)
}
Expand Down
24 changes: 12 additions & 12 deletions crates/zk-helpers/src/circuits/dkg/pk/computation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
// without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.

//! Computation types for the pk circuit: constants, bounds, bit widths, and witness.
//! Computation types for the pk circuit: constants, bounds, bit widths, and input.
//!
//! [`Constants`], [`Bounds`], [`Bits`], and [`Witness`] are produced from BFV parameters
//! and (for witness) a public key. They implement [`Computation`] and are used by codegen.
//! [`Constants`], [`Bounds`], [`Bits`], and [`Inputs`] are produced from BFV parameters
//! and (for input) a public key. They implement [`Computation`] and are used by codegen.

use crate::circuits::dkg::pk::circuit::PkCircuit;
use crate::circuits::dkg::pk::circuit::PkCircuitInput;
Expand All @@ -23,12 +23,12 @@ use e3_polynomial::CrtPolynomial;
use num_bigint::BigUint;
use serde::{Deserialize, Serialize};

/// Output of [`CircuitComputation::compute`] for [`PkCircuit`]: bounds, bit widths, and witness.
/// Output of [`CircuitComputation::compute`] for [`PkCircuit`]: bounds, bit widths, and input.
#[derive(Debug)]
pub struct PkComputationOutput {
pub bounds: Bounds,
pub bits: Bits,
pub witness: Witness,
pub inputs: Inputs,
}

/// Implementation of [`CircuitComputation`] for [`PkCircuit`].
Expand All @@ -41,12 +41,12 @@ impl CircuitComputation for PkCircuit {
fn compute(preset: Self::Preset, input: &Self::Input) -> Result<Self::Output, Self::Error> {
let bounds = Bounds::compute(preset, &())?;
let bits = Bits::compute(preset, &())?;
let witness = Witness::compute(preset, input)?;
let inputs = Inputs::compute(preset, input)?;

Ok(PkComputationOutput {
bounds,
bits,
witness,
inputs,
})
}
}
Expand All @@ -73,9 +73,9 @@ pub struct Bounds {
pub pk_bound: BigUint,
}

/// Witness data for the pk circuit: public key polynomials in CRT form for the prover.
/// Input for the pk circuit: public key polynomials in CRT form for the prover.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Witness {
pub struct Inputs {
/// Public key polynomials (pk0, pk1) for each CRT basis.
pub pk0is: CrtPolynomial,
pub pk1is: CrtPolynomial,
Expand Down Expand Up @@ -137,7 +137,7 @@ impl Computation for Bounds {
}
}

impl Computation for Witness {
impl Computation for Inputs {
type Preset = BfvPreset;
type Input = PkCircuitInput;
type Error = CircuitsErrors;
Expand All @@ -155,10 +155,10 @@ impl Computation for Witness {
pk0is.reduce_uniform(zkp_modulus);
pk1is.reduce_uniform(zkp_modulus);

Ok(Witness { pk0is, pk1is })
Ok(Inputs { pk0is, pk1is })
}

// Used as witness for Nargo execution.
// Used as inputs for Nargo execution.
fn to_json(&self) -> serde_json::Result<serde_json::Value> {
let pk0is = crt_polynomial_to_toml_json(&self.pk0is);
let pk1is = crt_polynomial_to_toml_json(&self.pk1is);
Expand Down
2 changes: 1 addition & 1 deletion crates/zk-helpers/src/circuits/dkg/pk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ pub mod sample;

pub use circuit::{PkCircuit, PkCircuitInput};
pub use codegen::{generate_configs, generate_toml};
pub use computation::{Bits, Bounds, Configs, PkComputationOutput, Witness};
pub use computation::{Bits, Bounds, Configs, Inputs, PkComputationOutput};
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl Circuit for ShareComputationCircuit {
}

pub struct ShareComputationCircuitInput {
/// Which secret type this input is for (determines which branch to use in witness).
/// Which secret type this input is for (determines which branch to use in input).
pub dkg_input_type: DkgInputType,
pub secret: CrtPolynomial,
pub secret_sss: Vec<Array2<BigInt>>,
Expand Down
22 changes: 10 additions & 12 deletions crates/zk-helpers/src/circuits/dkg/share_computation/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
use crate::circuits::computation::CircuitComputation;
use crate::circuits::computation::Computation;
use crate::circuits::dkg::share_computation::{
utils::parity_matrix_constant_string, Bits, ShareComputationCircuit,
ShareComputationCircuitInput, ShareComputationOutput, Witness,
utils::parity_matrix_constant_string, Bits, Inputs, ShareComputationCircuit,
ShareComputationCircuitInput, ShareComputationOutput,
};
use crate::circuits::{Artifacts, CircuitCodegen, CircuitsErrors, CodegenToml};
use crate::codegen::CodegenConfigs;
Expand All @@ -29,10 +29,10 @@ impl CircuitCodegen for ShareComputationCircuit {
type Error = CircuitsErrors;

fn codegen(&self, preset: Self::Preset, input: &Self::Input) -> Result<Artifacts, Self::Error> {
let ShareComputationOutput { witness, bits, .. } =
let ShareComputationOutput { inputs, bits, .. } =
ShareComputationCircuit::compute(preset, input)?;

let toml = generate_toml(&witness, input.dkg_input_type.clone())?;
let toml = generate_toml(&inputs, input.dkg_input_type.clone())?;
let configs = generate_configs(
preset,
&bits,
Expand All @@ -45,27 +45,25 @@ impl CircuitCodegen for ShareComputationCircuit {
}

pub fn generate_toml(
witness: &Witness,
inputs: &Inputs,
dkg_input_type: DkgInputType,
) -> Result<CodegenToml, CircuitsErrors> {
let mut json = witness
.to_json()
.map_err(|e| CircuitsErrors::SerdeJson(e))?;
let mut json = inputs.to_json().map_err(|e| CircuitsErrors::SerdeJson(e))?;

let obj = json.as_object_mut().ok_or(CircuitsErrors::Other(
"witness json is not an object".to_string(),
"input json is not an object".to_string(),
))?;

obj.remove("secret_crt");

let (key, value) = match dkg_input_type {
DkgInputType::SecretKey => (
"sk_secret",
poly_coefficients_to_toml_json(witness.secret_crt.limb(0).coefficients()),
poly_coefficients_to_toml_json(inputs.secret_crt.limb(0).coefficients()),
),
DkgInputType::SmudgingNoise => (
"e_sm_secret",
serde_json::Value::Array(crt_polynomial_to_toml_json(&witness.secret_crt)),
serde_json::Value::Array(crt_polynomial_to_toml_json(&inputs.secret_crt)),
),
};

Expand All @@ -77,7 +75,7 @@ pub fn generate_toml(
/// Builds the configs.nr string (N, L, parity matrix, bit parameters, configs) for the Noir prover.
///
/// `n_parties` and `threshold` are used to build the parity matrix (Reed–Solomon generator null space)
/// and must match the committee size used for the witness/sample.
/// and must match the committee size used for the input/sample.
pub fn generate_configs(
preset: BfvPreset,
bits: &Bits,
Expand Down
Loading
Loading