Skip to content

feat: add pvss and pvss-cli rust crates with C0 [skip-line-limit]#1217

Merged
0xjei merged 14 commits into
mainfrom
feat/codegen-compute
Jan 28, 2026
Merged

feat: add pvss and pvss-cli rust crates with C0 [skip-line-limit]#1217
0xjei merged 14 commits into
mainfrom
feat/codegen-compute

Conversation

@0xjei

@0xjei 0xjei commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

This PR will include all the necessary changes & refactoring for PVSS rust (codegen & compute = old zkfhe-generator).

Summary by CodeRabbit

Release Notes

  • New Features

    • Added PVSS (Proactive Verifiable Secret Sharing) core crate with computation and codegen support.
    • Introduced PVSS CLI tool for circuit management and artifact generation.
    • Added parameter type support (THRESHOLD and DKG modes).
    • Implemented PK-BFV circuit with configuration management.
    • Added circuit registry for tracking available circuits and their metadata.
  • Chores

    • Updated BFV configuration parameters for improved performance.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel

vercel Bot commented Jan 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
crisp Ready Ready Preview, Comment Jan 28, 2026 5:09pm
enclave-docs Ready Ready Preview, Comment Jan 28, 2026 5:09pm

Request Review

@coderabbitai

coderabbitai Bot commented Jan 27, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR introduces a new PVSS (Publicly Verifiable Secret Sharing) crate and CLI tool with BFV circuit integration. It adds parameter type classification (THRESHOLD vs DKG) to fhe-params, implements a PK-BFV circuit with codegen and computation workflows, and provides a CLI for circuit discovery and artifact generation.

Changes

Cohort / File(s) Summary
Workspace Configuration
Cargo.toml, crates/Dockerfile
Added new workspace members crates/pvss and crates/pvss-cli with workspace dependency for e3-pvss; updated Docker build to include pvss Cargo manifests.
FHE Parameters Enhancement
crates/fhe-params/src/lib.rs, crates/fhe-params/src/presets.rs
Introduced ParameterType enum (THRESHOLD, DKG); added parameter_type field to PresetMetadata; updated BfvPreset::metadata to assign distinct parameter types per variant.
PVSS Core Library Structure
crates/pvss/Cargo.toml, crates/pvss/src/lib.rs
Created new e3-pvss crate with workspace-managed dependencies; exposed modules: circuits, errors, registry, sample, traits, types, utils.
PVSS Error Handling & Types
crates/pvss/src/errors.rs, crates/pvss/src/types.rs
Added CodegenError enum with io/toml/fhe/zkhelpers/generic variants; introduced type aliases (Toml, Template, Configs, Wrapper), enums (DkgInputType, CiphernodesCommitteeSize, SecurityLevel), and structs (CiphernodesCommittee, Sample, Artifacts).
PVSS Traits & Registry
crates/pvss/src/traits.rs, crates/pvss/src/registry.rs
Implemented trait hierarchy: Computation, ConvertToJson, ReduceToZkpModulus, Circuit, CircuitMetadata, CircuitCodegen, CircuitComputation; built CircuitRegistry with lookup, validation, and metadata accessors for registered circuits.
PVSS Utilities & Sample Generation
crates/pvss/src/sample.rs, crates/pvss/src/utils.rs
Added generate_sample for BFV key generation; utilities for JSON conversion, security level derivation, wrapper code generation, and artifact file writes (toml/template/configs/wrapper).
PK-BFV Circuit Core
crates/pvss/src/circuits/mod.rs, crates/pvss/src/circuits/pk_bfv/mod.rs, crates/pvss/src/circuits/pk_bfv/circuit.rs
Defined PkBfvCircuit implementing Circuit, CircuitCodegen, and CircuitComputation; introduced PkBfvComputationOutput and PkBfvCodegenInput types.
PK-BFV Computation
crates/pvss/src/circuits/pk_bfv/computation.rs
Implemented Constants, Bits, Bounds, Witness structs with Computation trait; added JSON conversion and ZKP modulus reduction; derives per-modulus coefficient vectors from BFV public keys.
PK-BFV Codegen
crates/pvss/src/circuits/pk_bfv/codegen.rs
Orchestrates artifact generation: builds BFV parameters, computes cryptographic primitives, generates TOML/template/configs, and writes outputs; includes TomlJson struct and file-writing utilities.
PVSS CLI Tool
crates/pvss-cli/Cargo.toml, crates/pvss-cli/src/main.rs
Created e3-pvss-cli package; implements CLI with circuit listing and artifact generation workflows; validates parameter type matching and orchestrates registry lookups, parameter building, and file writes.
Noir Circuit Configuration
circuits/lib/src/configs/insecure/bfv.nr, circuits/lib/src/configs/production/bfv.nr
Updated PK_BFV_BIT_PK constants: insecure (51→50), production (57→58).

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI as pvss-cli
    participant Reg as Registry
    participant Circuit as PkBfvCircuit
    participant Comp as Computation
    participant FS as FileSystem

    User->>CLI: Run with circuit name & preset
    CLI->>Reg: Initialize & register PkBfvCircuit
    CLI->>Reg: Lookup circuit, validate parameter type
    Reg-->>CLI: Return circuit metadata
    CLI->>Circuit: Build BFV params from preset
    Circuit->>Comp: Generate sample (public key)
    Comp-->>Circuit: Return PublicKey
    CLI->>Circuit: Call codegen(preset, public_key)
    Circuit->>Comp: Compute Constants, Bounds
    Comp-->>Circuit: Return derived values
    Circuit->>Comp: Compute Bits from Bounds
    Comp-->>Circuit: Return pk_bit
    Circuit->>Comp: Compute Witness from PublicKey
    Comp-->>Circuit: Return pk0is, pk1is
    Circuit->>Comp: Reduce Witness to ZKP modulus
    Comp-->>Circuit: Return reduced coefficients
    Circuit->>Circuit: Generate TOML, template, configs, wrapper
    Circuit-->>CLI: Return Artifacts
    CLI->>FS: Write artifacts (toml, template, configs, wrapper)
    FS-->>CLI: Confirmed
    CLI-->>User: Success message
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

noir

Suggested reviewers

  • cedoor
  • ryardley

Poem

🐰 A new circuit blooms in code so clean,
With PVSS magic never seen,
PK-BFV dances with traits galore,
Artifacts crafted at CLI's door,
Parameters typed, the future's here! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.47% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding two new Rust crates (pvss and pvss-cli) to the project.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@0xjei 0xjei changed the title feat: add pvss rust crate feat: add pvss rust crate [skip-line-limit] Jan 28, 2026
@0xjei 0xjei requested a review from ctrlc03 January 28, 2026 15:20
@0xjei 0xjei changed the title feat: add pvss rust crate [skip-line-limit] feat: add pvss and pvss-cli rust crates with C0 [skip-line-limit] Jan 28, 2026
@0xjei 0xjei marked this pull request as ready for review January 28, 2026 15:20
@0xjei 0xjei requested a review from cedoor January 28, 2026 15:21
@0xjei 0xjei changed the title feat: add pvss and pvss-cli rust crates with C0 [skip-line-limit] feat: add pvss and pvss-cli rust crates [skip-line-limit] Jan 28, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@crates/pvss/src/registry.rs`:
- Around line 19-23: The RegistryError::InvalidInput enum variant is defined but
unused; either remove the InvalidInput variant from the RegistryError definition
or annotate it with #[allow(dead_code)] and add a concise comment explaining its
intended future use (e.g., reserved for validation errors when registering
circuits) so linters/maintainers understand why it remains; update the
RegistryError enum accordingly and ensure no other code references InvalidInput
before deleting it.
🧹 Nitpick comments (2)
crates/pvss/src/registry.rs (2)

31-37: Consider implementing Default trait.

Since new() returns an empty registry with no arguments, implementing Default would be idiomatic and allow usage with ..Default::default() patterns.

♻️ Suggested implementation
+impl Default for CircuitRegistry {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl CircuitRegistry {
     /// Build an empty registry.
     pub fn new() -> Self {

76-79: Note: list_circuits() returns names in arbitrary order.

HashMap::keys() iteration order is not guaranteed. If deterministic ordering is needed (e.g., for CLI output), consider sorting the result or using BTreeMap.

♻️ Optional: Return sorted names
     /// List all registered circuit names.
     pub fn list_circuits(&self) -> Vec<String> {
-        self.circuits.keys().cloned().collect()
+        let mut names: Vec<String> = self.circuits.keys().cloned().collect();
+        names.sort();
+        names
     }

Comment thread crates/pvss/src/registry.rs Outdated
@0xjei 0xjei changed the title feat: add pvss and pvss-cli rust crates [skip-line-limit] feat: add pvss and pvss-cli rust crates with C0 [skip-line-limit] Jan 28, 2026
Comment thread crates/pvss/src/utils.rs Outdated
@ctrlc03 ctrlc03 self-requested a review January 28, 2026 16:41
ctrlc03
ctrlc03 previously approved these changes Jan 28, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@crates/pvss/src/pk_bfv/codegen.rs`:
- Around line 68-82: The template currently defines the Noir main inputs pk0is
and pk1is as private; update the generated template in generate_template so the
function signature exposes these commitment parameters as public inputs (make
pk0is and pk1is pub) so the verifier can enforce them; locate generate_template
in pk_bfv/codegen.rs and change the main signature that declares pk0is and pk1is
(types [Polynomial<N>; L]) to mark both as pub, leaving the rest (BfvPkCommit
usage and PkBfvCircuit::PREFIX references) unchanged.
🧹 Nitpick comments (3)
crates/fhe-params/src/presets.rs (1)

60-67: Consider using PascalCase for enum variants.

Rust convention uses PascalCase for enum variants (Threshold, Dkg) rather than SCREAMING_CASE, which is typically reserved for constants. This would be more consistent with the rest of the codebase (e.g., BfvPreset::InsecureThresholdBfv512).

♻️ Suggested change
 pub enum ParameterType {
     /// Threshold BFV (TRBFV) parameters
-    THRESHOLD,
+    Threshold,
     /// DKG parameters (BFV)
-    DKG,
+    Dkg,
 }

Note: This would require updating usages in metadata() and any consumers.

crates/pvss-cli/src/main.rs (1)

95-108: Redundant parameter building and manual dispatch pattern.

Two observations:

  1. Duplicate work: params is built on line 96, but codegen() internally calls BfvParamSet::from(preset).build_arc() again (see crates/pvss/src/pk_bfv/codegen.rs:44). The sample generated here uses the first params, but codegen builds its own.

  2. Manual dispatch: The match on circuit_name will require updates for every new circuit. Consider having circuits implement a trait that enables dynamic dispatch for codegen, or use a different pattern.

♻️ Suggested fix for duplicate params

Either remove the redundant params build here and pass only the preset to the sample generation, or refactor codegen() to accept pre-built params:

     // 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 params = BfvParamSet::from(preset).build_arc();
+            let sample = sample::generate_sample(&params);
             let circuit = PkBfvCircuit;
             circuit.codegen(PkBfvCodegenInput {
                 preset,
                 public_key: sample.public_key,
             })?
         }
         name => return Err(anyhow!("circuit {} not yet implemented", name)),
     };

This moves sample generation inside the match, ensuring params are built only once per circuit path.

crates/pvss/src/pk_bfv/circuit.rs (1)

55-69: Computation logic duplicated with codegen().

CircuitComputation::compute() performs the same Bounds::compute(), Bits::compute(), and Witness::compute() calls as codegen::codegen() (see crates/pvss/src/pk_bfv/codegen.rs:46-48). Consider having codegen() internally call compute() to centralize the computation logic.

♻️ Suggested refactor in codegen.rs
pub fn codegen(preset: BfvPreset, public_key: PublicKey) -> Result<Artifacts, CodegenError> {
    let params = BfvParamSet::from(preset).build_arc();
    
    // Reuse CircuitComputation
    let circuit = PkBfvCircuit;
    let output = circuit.compute(&params, &public_key)?;
    let zkp_witness = output.witness.reduce_to_zkp_modulus();

    let toml = generate_toml(zkp_witness)?;
    let configs = generate_configs(&params, &output.bits);
    // ... rest of artifact generation
}

Comment thread crates/pvss/src/circuits/pk_bfv/codegen.rs

@cedoor cedoor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked the code together, LGTM now!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/Dockerfile (1)

88-98: Add pvss-cli to the binary crate condition in the stub file generation.

The Dockerfile script on line 90 only creates main.rs for ./cli/ and ./enclaveup/, but pvss-cli is also a binary crate with src/main.rs. The script will instead create src/lib.rs for it, breaking the dependency-caching build on line 100.

Add pvss-cli to the condition:

-          if [ "$d" = "./cli/" ] || [ "$d" = "./enclaveup/" ]; then \
+          if [ "$d" = "./cli/" ] || [ "$d" = "./enclaveup/" ] || [ "$d" = "./pvss-cli/" ]; then \
🧹 Nitpick comments (7)
crates/fhe-params/src/presets.rs (1)

60-67: Consider using PascalCase for enum variants.

Rust convention for enum variants is PascalCase rather than SCREAMING_CASE (which is typically reserved for constants). Consider renaming to Threshold and Dkg for idiomatic Rust.

♻️ Suggested change
 /// Parameter type for BFV presets
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub enum ParameterType {
     /// Threshold BFV (TRBFV) parameters
-    THRESHOLD,
+    Threshold,
     /// DKG parameters (BFV)
-    DKG,
+    Dkg,
 }
crates/Dockerfile (1)

83-84: Consider maintaining alphabetical order for consistency.

The existing Cargo.toml COPY instructions appear to be ordered alphabetically. These new entries would fit better after polynomial and before program-server.

♻️ Suggested reordering

Move lines 83-84 to after line 70 (polynomial/benches):

 COPY crates/polynomial/Cargo.toml ./polynomial/Cargo.toml
 COPY crates/polynomial/benches ./polynomial/benches
+COPY crates/pvss/Cargo.toml ./pvss/Cargo.toml
+COPY crates/pvss-cli/Cargo.toml ./pvss-cli/Cargo.toml
 COPY crates/program-server/Cargo.toml ./program-server/Cargo.toml

And remove from the current location at lines 83-84.

crates/pvss/src/types.rs (2)

38-46: Consider adding accessors for CiphernodesCommittee fields.

The struct fields n, h, and threshold are private, but there are no getter methods. If external code needs to read these values, accessors would be required.

♻️ Optional: Add getter methods
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct CiphernodesCommittee {
     /// Total number of parties (N_PARTIES).
     n: usize,
     /// Number of honest parties (H).
     h: usize,
     /// Threshold value (T).
     threshold: usize,
 }
+
+impl CiphernodesCommittee {
+    pub fn n(&self) -> usize { self.n }
+    pub fn h(&self) -> usize { self.h }
+    pub fn threshold(&self) -> usize { self.threshold }
+}

73-86: Consider using PascalCase for enum variants.

Rust convention uses PascalCase for enum variants (Insecure, Production) rather than SCREAMING_CASE (INSECURE, PRODUCTION).

♻️ Optional: Use idiomatic naming
 #[derive(Debug, Clone, Copy)]
 pub enum SecurityLevel {
-    INSECURE,
-    PRODUCTION,
+    Insecure,
+    Production,
 }

 impl SecurityLevel {
     pub fn as_str(self) -> &'static str {
         match self {
-            SecurityLevel::INSECURE => "insecure",
-            SecurityLevel::PRODUCTION => "production",
+            SecurityLevel::Insecure => "insecure",
+            SecurityLevel::Production => "production",
         }
     }
 }
crates/pvss/src/utils.rs (1)

14-23: Prefer slice parameter over &Vec.

Using &[Vec<BigInt>] instead of &Vec<Vec<BigInt>> is more idiomatic and allows callers to pass arrays, slices, or vectors.

♻️ More flexible parameter type
-pub fn map_witness_2d_vector_to_json(values: &Vec<Vec<BigInt>>) -> Vec<serde_json::Value> {
+pub fn map_witness_2d_vector_to_json(values: &[Vec<BigInt>]) -> Vec<serde_json::Value> {
crates/pvss/src/traits.rs (1)

13-19: Clarify the relationship between Computation and CircuitComputation.

There are two similar traits: Computation (standalone, static method) and CircuitComputation (extends Circuit, instance method). Consider documenting when each should be used, or consolidating if they serve the same purpose.

crates/pvss/src/circuits/pk_bfv/computation.rs (1)

160-167: Consider caching get_zkp_modulus() to avoid duplicate calls.

Minor optimization: get_zkp_modulus() is called twice. If this involves computation, storing the result locally would be slightly more efficient.

♻️ Optional refactor
 impl ReduceToZkpModulus for Witness {
     fn reduce_to_zkp_modulus(&self) -> Witness {
+        let zkp_mod = get_zkp_modulus();
         Witness {
-            pk0is: reduce_coefficients_2d(&self.pk0is, &get_zkp_modulus()),
-            pk1is: reduce_coefficients_2d(&self.pk1is, &get_zkp_modulus()),
+            pk0is: reduce_coefficients_2d(&self.pk0is, &zkp_mod),
+            pk1is: reduce_coefficients_2d(&self.pk1is, &zkp_mod),
         }
     }
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

implement a circuit registry with a factory pattern

3 participants