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
29 changes: 27 additions & 2 deletions crates/events/src/enclave_event/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
use derivative::Derivative;
use e3_utils::utility_types::ArcBytes;
use e3_zk_helpers::{
CircuitOutputLayout, DKG_SHARE_DECRYPTION_OUTPUTS, PK_AGGREGATION_OUTPUTS, PK_BFV_OUTPUTS,
PK_GENERATION_OUTPUTS, SHARE_COMPUTATION_CHUNK_BATCH_OUTPUTS, SHARE_COMPUTATION_OUTPUTS,
CircuitInputLayout, CircuitOutputLayout, DKG_SHARE_DECRYPTION_OUTPUTS, PK_AGGREGATION_OUTPUTS,
PK_BFV_OUTPUTS, PK_GENERATION_OUTPUTS, SHARE_COMPUTATION_CHUNK_BATCH_OUTPUTS,
SHARE_COMPUTATION_OUTPUTS, SHARE_ENCRYPTION_INPUTS, THRESHOLD_SHARE_DECRYPTION_INPUTS,
THRESHOLD_SHARE_DECRYPTION_OUTPUTS,
};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -48,6 +49,17 @@ impl Proof {
.extract_field(&self.public_signals, field_name)
.map(ArcBytes::from_bytes)
}

/// Extract a named public input field from this proof's public signals.
///
/// Public inputs sit at the **start** of `public_signals`, before any
/// return values.
pub fn extract_input(&self, field_name: &str) -> Option<ArcBytes> {
let layout = self.circuit.input_layout();
layout
.extract_field(&self.public_signals, field_name)
.map(ArcBytes::from_bytes)
}
}

/// Circuit variants determine the hash oracle used for VK generation and proving.
Expand Down Expand Up @@ -202,6 +214,19 @@ impl CircuitName {
CircuitName::Fold => CircuitOutputLayout::None,
}
}

/// Public input layout for C3 and C6 circuits (fields at the start of public_signals).
pub fn input_layout(&self) -> CircuitInputLayout {
match self {
CircuitName::ShareEncryption => CircuitInputLayout::Fixed {
fields: SHARE_ENCRYPTION_INPUTS,
},
CircuitName::ThresholdShareDecryption => CircuitInputLayout::Fixed {
fields: THRESHOLD_SHARE_DECRYPTION_INPUTS,
},
_ => CircuitInputLayout::None,
}
}
}

impl fmt::Display for CircuitName {
Expand Down
27 changes: 18 additions & 9 deletions crates/events/src/enclave_event/signed_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,16 @@ pub enum ProofType {
C3aSkShareEncryption = 4,
/// C3b — Smudging noise share encryption proof (Proof 3b).
C3bESmShareEncryption = 5,
/// C4 — DKG share decryption proof (Proof 4).
C4DkgShareDecryption = 6,
/// C4a — SK share decryption proof (Proof 4a).
C4aSkShareDecryption = 6,
/// C4b — Smudging noise share decryption proof (Proof 4b).
C4bESmShareDecryption = 7,
/// C5 — Public key aggregation proof (Proof 5).
C5PkAggregation = 8,
/// C6 — Threshold share decryption proof (Proof 6).
C6ThresholdShareDecryption = 7,
C6ThresholdShareDecryption = 9,
/// C7 — Decrypted shares aggregation proof (Proof 7).
C7DecryptedSharesAggregation = 8,
/// C5 — Public key aggregation proof (Proof 5).
C5PkAggregation = 9,
C7DecryptedSharesAggregation = 10,
}

impl ProofType {
Expand All @@ -59,7 +61,9 @@ impl ProofType {
ProofType::C2bESmShareComputation => vec![CircuitName::ShareComputation],
ProofType::C3aSkShareEncryption => vec![CircuitName::ShareEncryption],
ProofType::C3bESmShareEncryption => vec![CircuitName::ShareEncryption],
ProofType::C4DkgShareDecryption => vec![CircuitName::DkgShareDecryption],
ProofType::C4aSkShareDecryption | ProofType::C4bESmShareDecryption => {
vec![CircuitName::DkgShareDecryption]
}
ProofType::C6ThresholdShareDecryption => vec![CircuitName::ThresholdShareDecryption],
ProofType::C7DecryptedSharesAggregation => {
vec![CircuitName::DecryptedSharesAggregation]
Expand All @@ -77,7 +81,8 @@ impl ProofType {
| ProofType::C2bESmShareComputation
| ProofType::C3aSkShareEncryption
| ProofType::C3bESmShareEncryption
| ProofType::C4DkgShareDecryption => "E3_BAD_DKG_PROOF",
| ProofType::C4aSkShareDecryption
| ProofType::C4bESmShareDecryption => "E3_BAD_DKG_PROOF",
ProofType::C6ThresholdShareDecryption => "E3_BAD_DECRYPTION_PROOF",
ProofType::C7DecryptedSharesAggregation => "E3_BAD_AGGREGATION_PROOF",
ProofType::C5PkAggregation => "E3_BAD_PK_AGGREGATION_PROOF",
Expand Down Expand Up @@ -391,7 +396,11 @@ mod tests {
vec![CircuitName::ShareEncryption]
);
assert_eq!(
ProofType::C4DkgShareDecryption.circuit_names(),
ProofType::C4aSkShareDecryption.circuit_names(),
vec![CircuitName::DkgShareDecryption]
);
assert_eq!(
ProofType::C4bESmShareDecryption.circuit_names(),
vec![CircuitName::DkgShareDecryption]
);
assert_eq!(
Expand Down
40 changes: 40 additions & 0 deletions crates/zk-helpers/src/circuits/output_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,46 @@ impl CircuitOutputLayout {
}
}

// ── Public input layout (fields at the HEAD of public_signals) ──────────────

/// Describes the public input fields of a circuit.
/// Inputs sit at the **start** of `public_signals`, before any return values.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum CircuitInputLayout {
/// Fixed number of named `Field`-sized inputs, known at compile time.
Fixed { fields: &'static [OutputField] },
/// No known public input layout.
None,
}

impl CircuitInputLayout {
/// Extract a named public input field from raw `public_signals` bytes.
/// Inputs sit at the **start** of `public_signals`.
pub fn extract_field<'a>(&self, public_signals: &'a [u8], name: &str) -> Option<&'a [u8]> {
let fields = match self {
CircuitInputLayout::Fixed { fields } => fields,
_ => return None,
};
let idx = fields.iter().position(|f| f.name == name)?;
let offset = idx * FIELD_BYTE_LEN;
let end = offset + FIELD_BYTE_LEN;
if public_signals.len() < end {
return None;
}
Some(&public_signals[offset..end])
}
}

/// C3 — Share encryption public inputs.
pub const SHARE_ENCRYPTION_INPUTS: &[OutputField] = &[
f("expected_pk_commitment"),
f("expected_message_commitment"),
];

/// C6 — Threshold share decryption public inputs.
pub const THRESHOLD_SHARE_DECRYPTION_INPUTS: &[OutputField] =
&[f("expected_sk_commitment"), f("expected_e_sm_commitment")];

// ── Per-circuit output field constants ──────────────────────────────────────

const fn f(name: &'static str) -> OutputField {
Expand Down
Loading
Loading