Skip to content

feat: add pk_trfv_generation_circuit to zk-prover#1281

Merged
cedoor merged 6 commits into
mainfrom
feat/proof-1
Feb 10, 2026
Merged

feat: add pk_trfv_generation_circuit to zk-prover#1281
cedoor merged 6 commits into
mainfrom
feat/proof-1

Conversation

@ctrlc03

@ctrlc03 ctrlc03 commented Feb 9, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added threshold public key generation circuit with proof generation, verification, and commitment validation capabilities
    • Integrated comprehensive end-to-end testing for threshold key generation workflows
  • Refactor

    • Reorganized circuit module structure to improve maintainability
    • Consolidated utility functions for polynomial conversions
    • Clarified circuit naming conventions
  • Chores

    • Updated threshold generation configuration parameters

@vercel

vercel Bot commented Feb 9, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
crisp Ready Ready Preview, Comment Feb 10, 2026 3:28pm
enclave-docs Ready Ready Preview, Comment Feb 10, 2026 3:28pm

Request Review

@coderabbitai

coderabbitai Bot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR refactors the threshold PK generation circuit infrastructure by: updating security parameters for insecure preset (increasing bit bounds for E_SM), reorganizing module structure (removing pkbfv, introducing dkg and threshold modules), extracting polynomial conversion utilities, implementing the Provable trait for PkGenerationCircuit, and adding comprehensive end-to-end tests for the threshold PK workflow. The CircuitName enum variant is renamed from PkTrbfv to PkGeneration.

Changes

Cohort / File(s) Summary
Configuration Parameters
circuits/lib/src/configs/insecure/threshold.nr
Updated threshold preset constants: PK_GENERATION_BIT_E_SM increased from 17 to 24, and PK_GENERATION_E_SM_BOUND increased from 123072 to 12307200.
Module Structure Refactoring
crates/zk-prover/src/circuits/mod.rs
Removed mod pkbfv; declaration and added three new module declarations: mod dkg;, mod threshold;, and mod utils;
Utility Functions
crates/zk-prover/src/circuits/utils.rs
Added two public utility functions for polynomial conversion: crt_polynomial_to_array() converts CrtPolynomial to nested InputValue structure, and polynomial_to_input_value() converts Polynomial to InputValue::Struct; both handle field element parsing and serialization errors.
Threshold Circuit Implementation
crates/zk-prover/src/circuits/threshold/mod.rs, crates/zk-prover/src/circuits/threshold/pk_generation.rs
New threshold module structure with pk_generation.rs implementing Provable trait for PkGenerationCircuit, including circuit() method returning CircuitName::PkGeneration and build_witness() that constructs witness from input and maps components to InputMap using polynomial conversion utilities.
DKG Module Setup
crates/zk-prover/src/circuits/dkg/mod.rs
New DKG module with license header and internal mod pk; declaration.
DKG Polynomial Refactoring
crates/zk-prover/src/circuits/dkg/pk.rs
Removed local crt_polynomial_to_array() function and consolidated polynomial conversion logic, now importing crt_polynomial_to_array from circuit utils.
Event Type Updates
crates/events/src/enclave_event/proof.rs
Renamed CircuitName enum variant from PkTrbfv to PkGeneration; updated mappings: string representation "pk_trbfv" → "pk_generation" and group mapping to "threshold".
End-to-End Tests
crates/zk-prover/tests/local_e2e_tests.rs
Added comprehensive threshold PK generation tests: test_pk_generation_proof_generation(), test_pk_generation_proof_verification(), and test_pk_generation_commitment_consistency() with fixture setup for InsecureThreshold512 preset and commitment validation logic; removed debug println statements from existing BFV tests.
Minor Formatting
crates/zk-prover/src/traits.rs
Added blank line for code organization between circuit path construction and circuit loading logic.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #1268: Both PRs modify the same threshold preset constants (PK_GENERATION_BIT_E_SM and PK_GENERATION_E_SM_BOUND) in the insecure configuration.
  • PR #1254: Both PRs refactor polynomial and CRT handling infrastructure, adding and consuming crt_polynomial_to_array conversion utilities across circuit modules.
  • PR #1261: Both PRs modify threshold/DKG PK generation surfaces and adjust insecure-configuration bit parameters for E_SM calculations across threshold circuit infrastructure.

Suggested reviewers

  • cedoor
  • 0xjei

Poem

🐰 Circuits shuffle, modules dance,
Constants grow with measured stance,
Polynomials find their place,
Thresholds tested face-to-face,
Proofs compile—let's celebrate! ✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title mentions 'pk_trfv_generation_circuit' but the actual changes implement 'PkGenerationCircuit' and rename the circuit from 'PkTrbfv' to 'PkGeneration', with module organization under threshold, not a trfv-specific circuit. Update the title to accurately reflect the actual implementation, such as 'feat: add threshold PK generation circuit to zk-prover' or 'feat: rename and reorganize PK generation circuit as threshold module'.
Docstring Coverage ⚠️ Warning Docstring coverage is 27.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/proof-1

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.

@github-actions

github-actions Bot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

License Header Check Failed

Some files are missing the required SPDX license header. Please add the following header to the beginning of all .js, .jsx, .nr, .rs, .sol, .ts, and .tsx files:

// 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.

You can run ./scripts/check-license-headers.sh --fix locally to automatically add missing headers, then commit the changes.

Or run ./scripts/check-license-headers.sh to see which files need headers.

@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: 2

🤖 Fix all issues with AI agents
In `@crates/zk-prover/src/circuits/utils.rs`:
- Around line 1-6: This file is missing the SPDX license header; add the
standard header comment "// SPDX-License-Identifier: LGPL-3.0-only" as the very
first line of the file (above the existing imports such as use
std::collections::BTreeMap; and the referenced symbols ZkError, FieldElement,
CrtPolynomial, Polynomial, InputValue) so the CI license-header check passes.

In `@crates/zk-prover/tests/local_e2e_tests.rs`:
- Line 186: Rename the test function to fix the typo in its name: change
test_pk_trbfv_committment_consistency to test_pk_trbfv_commitment_consistency
wherever it is declared and referenced (e.g., the async fn
test_pk_trbfv_committment_consistency declaration and any modulary/test harness
references); ensure tests still compile by updating any mentions in attributes,
mod maps, or test invocations that reference the old symbol.
🧹 Nitpick comments (4)
crates/zk-prover/src/circuits/utils.rs (1)

8-45: Utility functions look correct; minor DRY opportunity.

Both crt_polynomial_to_array and polynomial_to_input_value share near-identical inner loops for converting coefficients to InputValue::Field via a string round-trip. Consider extracting a small helper (e.g., coefficients_to_fields) to reduce duplication. Not blocking.

Sketch
+fn coefficients_to_fields(coeffs: &[impl ToString]) -> Result<Vec<InputValue>, ZkError> {
+    coeffs
+        .iter()
+        .map(|b| {
+            let s = b.to_string();
+            FieldElement::try_from_str(&s)
+                .map(InputValue::Field)
+                .ok_or_else(|| ZkError::SerializationError(format!("invalid field element: {}", s)))
+        })
+        .collect()
+}
crates/zk-prover/src/circuits/pk_generation.rs (2)

18-18: Use InputMap::new() instead of BTreeMap::new() for consistency.

InputMap is already imported (line 17) and is used in pkbfv.rs via InputMap::new(). Using BTreeMap::new() here works (since InputMap is a BTreeMap alias) but is inconsistent and makes the BTreeMap import unnecessary.

Proposed fix
 use noirc_abi::InputMap;
-use std::collections::BTreeMap;
 
 impl Provable for PkGenerationCircuit {
-        let mut inputs = BTreeMap::new();
+        let mut inputs = InputMap::new();

Also applies to: 36-36


33-33: Needless double-borrow on input.

input is already &Self::Input (i.e., &PkGenerationCircuitInput), so &input creates &&PkGenerationCircuitInput. Rust auto-derefs this, but it's a minor lint. Compare with pkbfv.rs which avoids this.

Proposed fix
-        let witness = Witness::compute(preset.clone(), &input)
+        let witness = Witness::compute(preset.clone(), input)
crates/zk-prover/tests/local_e2e_tests.rs (1)

81-130: Consider using descriptive e3_id values to match existing test conventions.

All three new tests use e3_id = "0", while the existing BFV tests use descriptive IDs like "test-pk-bfv-001", "test-verify-001", "test-commitment-001". If these tests ever run in parallel sharing state, collisions on "0" could cause interference.

Also applies to: 132-183, 185-266

Comment thread crates/zk-prover/src/circuits/utils.rs
Comment thread crates/zk-prover/tests/local_e2e_tests.rs Outdated
Comment thread crates/zk-prover/tests/fixtures/pk_generation.json
Comment thread crates/zk-prover/src/circuits/dkg/pk.rs

@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: 3

🤖 Fix all issues with AI agents
In `@crates/events/src/enclave_event/proof.rs`:
- Around line 41-42: Update the stale doc comment for the enum variant
PkGeneration to match the renamed variant; replace "TrBFV public key share proof
(T1)" with a comment that describes PkGeneration (e.g., "Public key generation
proof (T1)" or similar clear wording) so the documentation aligns with the
PkGeneration variant name in enclave_event::proof.rs.

In `@crates/zk-prover/tests/local_e2e_tests.rs`:
- Around line 110-112: The tests call CiphernodesCommitteeSize::Small.values()
but the type isn't imported into the test module; add a use statement to bring
CiphernodesCommitteeSize into scope (so the three uses in
PkGenerationCircuitInput::generate_sample(...) compile), e.g. add a `use` for
CiphernodesCommitteeSize at the top of the file or test module so the symbol is
available to the calls in the tests.
- Around line 14-21: Remove the duplicate PkCircuit import and correct the
module path for PkGenerationCircuit imports: replace the current use of
e3_zk_helpers::threshold::pk_generation with
e3_zk_helpers::circuits::threshold::pk_generation so PkGenerationCircuit and
PkGenerationCircuitInput are imported from the proper module; ensure you still
import PkCircuitInput and compute_* helpers (compute_dkg_pk_commitment,
compute_share_computation_e_sm_commitment,
compute_share_computation_sk_commitment, compute_threshold_pk_commitment) from
their correct modules, and add a new import use
e3_zk_helpers::CiphernodesCommitteeSize so the references to
CiphernodesCommitteeSize at lines 111, 162, and 215 resolve.
🧹 Nitpick comments (4)
crates/zk-prover/src/circuits/threshold/pk_generation.rs (2)

17-18: Unnecessary BTreeMap import; prefer InputMap::new() for consistency.

InputMap is already imported on line 17 and is a type alias for BTreeMap<String, InputValue>. Using InputMap::new() on line 36 (as done in pkbfv.rs) would be consistent and let you drop the explicit std::collections::BTreeMap import.

Proposed fix
 use noirc_abi::InputMap;
-use std::collections::BTreeMap;
-        let mut inputs = BTreeMap::new();
+        let mut inputs = InputMap::new();

33-33: Redundant double reference &input.

input is already &Self::Input, so &input creates &&PkGenerationCircuitInput. While Rust auto-deref handles this, it's cleaner to pass input directly (matching the pattern in pkbfv.rs).

Proposed fix
-        let witness = Witness::compute(preset.clone(), &input)
+        let witness = Witness::compute(preset.clone(), input)
crates/zk-prover/tests/local_e2e_tests.rs (2)

80-129: Significant test setup duplication across the three new tests.

All three test_pk_generation_* tests repeat identical setup code (~30 lines each): finding bb, setting up the prover, copying fixtures, creating the sample, etc. Consider extracting a shared helper (similar to how BFV tests could also benefit) to reduce duplication and maintenance burden.

Also applies to: 131-182, 184-277


230-232: Magic number 1027 for total fields assertion.

The hardcoded 1027 (1024 pk fields + 3 commitments) is brittle and will silently break if circuit parameters change. Consider deriving this from the preset or documenting the formula explicitly with named constants.

Comment thread crates/events/src/enclave_event/proof.rs
Comment thread crates/zk-prover/tests/local_e2e_tests.rs
Comment thread crates/zk-prover/tests/local_e2e_tests.rs
Comment thread crates/zk-prover/src/circuits/dkg/pk.rs
@github-actions

Copy link
Copy Markdown
Contributor

License Header Check Failed

Some files are missing the required SPDX license header. Please add the following header to the beginning of all .js, .jsx, .nr, .rs, .sol, .ts, and .tsx files:

// 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.

You can run ./scripts/check-license-headers.sh --fix locally to automatically add missing headers, then commit the changes.

Or run ./scripts/check-license-headers.sh to see which files need headers.

@ctrlc03 ctrlc03 requested a review from cedoor February 10, 2026 15:24
@cedoor cedoor enabled auto-merge (squash) February 10, 2026 15:28

@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/zk-prover/tests/local_e2e_tests.rs`:
- Line 236: The inline comment on the calculation for offset is incorrect;
update the comment next to the expression that computes offset (the line using
variables offset, total_fields, and field_size) so it reflects the actual
arithmetic and result for (total_fields - 3) * field_size — e.g. compute (1027 -
3) * 32 = 32768 — or remove the stale multiplication example entirely to avoid
confusion.
🧹 Nitpick comments (3)
crates/zk-prover/src/circuits/utils.rs (1)

14-51: Consider extracting the shared coefficient-conversion loop.

Lines 21–27 and 41–45 contain identical logic converting polynomial coefficients into Vec<InputValue::Field> via string serialization. A small helper like coefficients_to_field_values(coeffs: &[BigUint]) -> Result<Vec<InputValue>, ZkError> would eliminate the duplication and make both public functions one-liners around the shared core.

♻️ Sketch
+fn coefficients_to_field_values(
+    coeffs: &[impl std::fmt::Display],
+) -> Result<Vec<InputValue>, ZkError> {
+    coeffs
+        .iter()
+        .map(|b| {
+            let s = b.to_string();
+            FieldElement::try_from_str(&s)
+                .map(InputValue::Field)
+                .ok_or_else(|| ZkError::SerializationError(format!("invalid field element: {}", s)))
+        })
+        .collect()
+}
crates/zk-prover/tests/local_e2e_tests.rs (2)

81-130: Consider extracting the repeated test setup into a shared helper.

All three new tests (and the existing BFV tests below) duplicate the same ~25 lines of boilerplate: finding bb, setting up the prover backend, creating the circuit directory, and copying fixture files. A helper like setup_pk_generation_test() -> (ZkProver, ...) would reduce noise and make the test intent clearer.

Also applies to: 132-183, 185-278


231-233: Add context for the magic number 1027.

assert_eq!(total_fields, 1027) is opaque — briefly document the expected structure (e.g., 1024 polynomial coefficients + 3 commitment fields, or however it breaks down) so future readers understand what this assertion guards.

Comment thread crates/zk-prover/tests/local_e2e_tests.rs
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.

2 participants