Skip to content

fix: bit width inconsistencies in circuits#1504

Merged
cedoor merged 5 commits into
mainfrom
fix/bit-inconsistencies
Apr 1, 2026
Merged

fix: bit width inconsistencies in circuits#1504
cedoor merged 5 commits into
mainfrom
fix/bit-inconsistencies

Conversation

@cedoor

@cedoor cedoor commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

Aligns Noir DKG/threshold commitment bit widths with e3-zk-helpers so C1/C5 (pk generation vs pk aggregation) and C2/C4/C6 (share encryption vs per-share vs aggregate share decryption) hash the same coefficient ranges the prover expects. Fixes the secure preset where share-decryption msg bits disagreed with share encryption, and threads explicit per-share vs aggregate parameters through share decryption as needed.

Adds CrtPolynomial::to_fhe_polynomial on e3-polynomial (inverse of from_fhe_polynomial) and updates local_e2e_tests to use it instead of duplicating CRT→fhe_math::Poly logic; drops redundant test-only dependencies.

Testing

  • cargo test -p e3-polynomial
  • cargo test -p e3-zk-prover --test local_e2e_tests (with bb and built circuit artifacts)

Summary by CodeRabbit

  • Chores

    • Updated cryptographic configuration parameters across security presets, adjusting bit-width values for aggregation and encryption operations
    • Refactored internal polynomial conversion utilities to support enhanced cryptographic format handling
    • Expanded development dependencies
  • Tests

    • Extended test coverage with new scenarios validating interactions between cryptographic circuit components

@cedoor cedoor requested review from 0xjei and ctrlc03 March 31, 2026 16:43
@coderabbitai

coderabbitai Bot commented Mar 31, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The changes introduce a new generic parameter BIT_AGG to the ShareDecryption circuit type, establishing separate bit-width parameters for per-share plaintext hashing (BIT_MSG) and CRT aggregate commitment computation (BIT_AGG). Configuration constants across insecure and secure presets are adjusted accordingly. A new CrtPolynomial::to_fhe_polynomial method enables FHE polynomial conversion, and cross-circuit E2E tests validate alignment between C4 (DKG share decryption) and C6 (threshold share decryption) circuit commitments.

Changes

Cohort / File(s) Summary
ShareDecryption Circuit Type
circuits/lib/src/core/dkg/share_decryption.nr
Added new const generic parameter BIT_AGG to ShareDecryption struct and its impl block. Updated execute() method to use BIT_AGG when computing aggregated shares commitment instead of BIT_MSG. Documentation clarifies BIT_MSG for per-share plaintext hashing and BIT_AGG for CRT aggregate commitment hashing.
Insecure Configuration Preset
circuits/lib/src/configs/insecure/dkg.nr, circuits/lib/src/configs/insecure/threshold.nr
Added public re-export alias SHARE_DECRYPTION_BIT_AGG from THRESHOLD_SHARE_DECRYPTION_BIT_SK in dkg.nr. Reduced PK_AGGREGATION_BIT_PK, USER_DATA_ENCRYPTION_BIT_PK, and USER_DATA_ENCRYPTION_BIT_CT from 36 to 35 in threshold.nr.
Secure Configuration Preset
circuits/lib/src/configs/secure/dkg.nr, circuits/lib/src/configs/secure/threshold.nr
Added public re-export alias SHARE_DECRYPTION_BIT_AGG from THRESHOLD_SHARE_DECRYPTION_BIT_SK in dkg.nr and reduced SHARE_DECRYPTION_BIT_MSG from 55 to 54. Reduced PK_AGGREGATION_BIT_PK, USER_DATA_ENCRYPTION_BIT_PK, and USER_DATA_ENCRYPTION_BIT_CT from 53 to 52 in threshold.nr.
Circuit Instantiation
circuits/bin/dkg/share_decryption/src/main.nr
Updated ShareDecryption type instantiation to include SHARE_DECRYPTION_BIT_AGG as an additional generic type argument alongside existing parameters N, L_THRESHOLD, H, and SHARE_DECRYPTION_BIT_MSG.
CRT Polynomial Conversion
crates/polynomial/src/crt_polynomial.rs
Added new public method to_fhe_polynomial() that converts CRT limb polynomials to FHE Poly in PowerBasis form. Includes validation of limb/moduli/context consistency and per-coefficient reduction logic via new helper bigint_to_u64_mod() for modulo normalization.
Code Generation & Computation
crates/zk-helpers/src/circuits/dkg/share_decryption/codegen.rs, crates/zk-helpers/src/circuits/dkg/share_decryption/computation.rs
Extended generated Noir configs to export BIT_AGG global parameter. Refactored Bits struct to add agg_bit field and changed msg_bit computation to use dedicated compute_msg_bit() helper. Updated unit tests to validate both aggregation and message bit widths.
Cargo & E2E Tests
crates/zk-prover/Cargo.toml, crates/zk-prover/tests/local_e2e_tests.rs
Added num-traits to dev-dependencies. Introduced comprehensive cross-circuit E2E tests validating C4–C6 alignment: helper function aggregate_dkg_decrypted_shares_to_crt() reconstructs CRT polynomial from decrypted shares, and two new tests assert C4 commitment hash matches C6 expected SK commitment and validates bit-width alignment.

Sequence Diagram(s)

sequenceDiagram
    participant Test as E2E Test
    participant C4 as DKG Circuit (C4)
    participant Agg as Aggregation Helper
    participant C6 as Threshold Circuit (C6)
    participant Val as Validator

    Test->>C4: Generate & prove C4 with DKG shares
    C4-->>Test: Commitment output
    Test->>Agg: Aggregate DKG decrypted shares → CRT polynomial
    Agg->>Agg: Convert decrypted shares to BigInt
    Agg->>Agg: Reduce & pack into CRT form
    Agg-->>Test: Aggregated CRT polynomial + agg_sk
    Test->>C6: Generate & prove C6 with aligned SK
    C6-->>Test: expected_sk_commitment output
    Test->>Val: Recompute C4 commitment from agg_sk
    Val-->>Test: Computed commitment
    Test->>Val: Assert C4 commitment == C6 expected_sk_commitment
    Val-->>Test: Validation result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • 0xjei
  • ctrlc03

🐰 A new bit parameter hops through configs neat,
C4 and C6 circuits now meet,
CRT polynomials dance with care,
Aggregated commitments everywhere!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: bit width inconsistencies in circuits' directly and clearly summarizes the main change—correcting bit width configuration values across DKG and threshold circuits.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/bit-inconsistencies

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.

@vercel

vercel Bot commented Mar 31, 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 Mar 31, 2026 4:44pm
enclave-docs Ready Ready Preview, Comment Mar 31, 2026 4:44pm

Request Review

@cedoor cedoor linked an issue Mar 31, 2026 that may be closed by this pull request
@cedoor cedoor enabled auto-merge (squash) March 31, 2026 16:44

@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

🧹 Nitpick comments (1)
circuits/lib/src/configs/secure/threshold.nr (1)

32857-32858: Consider centralizing the shared 52 bit-width constant.

USER_DATA_ENCRYPTION_BIT_PK and USER_DATA_ENCRYPTION_BIT_CT now share the same literal value (and match PK_AGGREGATION_BIT_PK). A single source-of-truth constant here would reduce future drift risk.

♻️ Small refactor proposal
+pub global THRESHOLD_COMMITMENT_BIT_WIDTH: u32 = 52;
-pub global PK_AGGREGATION_BIT_PK: u32 = 52;
+pub global PK_AGGREGATION_BIT_PK: u32 = THRESHOLD_COMMITMENT_BIT_WIDTH;

-pub global USER_DATA_ENCRYPTION_BIT_PK: u32 = 52;
-pub global USER_DATA_ENCRYPTION_BIT_CT: u32 = 52;
+pub global USER_DATA_ENCRYPTION_BIT_PK: u32 = THRESHOLD_COMMITMENT_BIT_WIDTH;
+pub global USER_DATA_ENCRYPTION_BIT_CT: u32 = THRESHOLD_COMMITMENT_BIT_WIDTH;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@circuits/lib/src/configs/secure/threshold.nr` around lines 32857 - 32858,
Both USER_DATA_ENCRYPTION_BIT_PK and USER_DATA_ENCRYPTION_BIT_CT are hardcoded
to 52; create a single shared constant (e.g., USER_DATA_ENCRYPTION_BITS: u32 =
52) and replace references to USER_DATA_ENCRYPTION_BIT_PK and
USER_DATA_ENCRYPTION_BIT_CT with that constant to avoid drift; also check and
consolidate any other matching literals such as PK_AGGREGATION_BIT_PK to reuse
the same new constant and update all use-sites (declarations and any modules
that import these symbols) accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/polynomial/src/crt_polynomial.rs`:
- Around line 265-268: In bigint_to_u64_mod, guard against a zero modulus before
performing the modulo: check if m == 0 at the start of the function and
immediately return an Err(fhe_math::Error) appropriate for a zero-divisor
instead of computing c % bm; this prevents the panic ("attempt to divide by
zero") when creating bm/using % and keeps the Result contract intact—place the
check before BigInt::from(m) and the r = c % &bm calculation in
bigint_to_u64_mod.

In `@crates/zk-prover/tests/local_e2e_tests.rs`:
- Around line 942-958: Add a direct cross-circuit equality check between the C4
and C6 commitments: after computing c4_big (via
compute_aggregated_shares_commitment) and c6_big (the C6 commitment) and after
the existing ThresholdShareDecryptionCircuit::compute/c6_out assertions, insert
an assert that c4_big == c6_big with a descriptive message so we fail if C4 and
C6 use different commitment formulas or layouts; reference c4_big, c6_big,
compute_aggregated_shares_commitment, ThresholdShareDecryptionCircuit::compute,
c6_out.inputs.expected_sk_commitment, dkg_out.bits.agg_bit and
c6_out.bits.sk_bit to locate the correct spot.

---

Nitpick comments:
In `@circuits/lib/src/configs/secure/threshold.nr`:
- Around line 32857-32858: Both USER_DATA_ENCRYPTION_BIT_PK and
USER_DATA_ENCRYPTION_BIT_CT are hardcoded to 52; create a single shared constant
(e.g., USER_DATA_ENCRYPTION_BITS: u32 = 52) and replace references to
USER_DATA_ENCRYPTION_BIT_PK and USER_DATA_ENCRYPTION_BIT_CT with that constant
to avoid drift; also check and consolidate any other matching literals such as
PK_AGGREGATION_BIT_PK to reuse the same new constant and update all use-sites
(declarations and any modules that import these symbols) accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 31062749-892b-410e-9158-912c4c4a429f

📥 Commits

Reviewing files that changed from the base of the PR and between 90bb5fe and 83d99e1.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • circuits/bin/dkg/share_decryption/src/main.nr
  • circuits/lib/src/configs/insecure/dkg.nr
  • circuits/lib/src/configs/insecure/threshold.nr
  • circuits/lib/src/configs/secure/dkg.nr
  • circuits/lib/src/configs/secure/threshold.nr
  • circuits/lib/src/core/dkg/share_decryption.nr
  • crates/polynomial/src/crt_polynomial.rs
  • crates/zk-helpers/src/circuits/dkg/share_decryption/codegen.rs
  • crates/zk-helpers/src/circuits/dkg/share_decryption/computation.rs
  • crates/zk-prover/Cargo.toml
  • crates/zk-prover/tests/local_e2e_tests.rs

Comment thread crates/polynomial/src/crt_polynomial.rs
Comment thread crates/zk-prover/tests/local_e2e_tests.rs

@ctrlc03 ctrlc03 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

utACK

@cedoor cedoor merged commit 329fe0e into main Apr 1, 2026
34 checks passed
@ctrlc03 ctrlc03 deleted the fix/bit-inconsistencies branch April 1, 2026 09:11
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.

Align bit widths used by Noir circuits

2 participants