Skip to content

refactor: optimize circuit inputs computation [skip-line-limit]#1310

Merged
0xjei merged 6 commits into
mainfrom
refactor/input-computation
Feb 12, 2026
Merged

refactor: optimize circuit inputs computation [skip-line-limit]#1310
0xjei merged 6 commits into
mainfrom
refactor/input-computation

Conversation

@cedoor

@cedoor cedoor commented Feb 12, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added importing of external polynomial representations into the library's internal format.
  • Refactor

    • Reworked cryptographic flows to a CRT-centric, per-modulus parallel processing pipeline for more consistent polynomial handling.
  • Breaking Changes

    • Removed the public standard_form API and made JSON export for inputs internal.
    • Inputs now carry e0 in a centralized modular form (mod‑Q), affecting input semantics.
  • Documentation

    • Updated docs to reference the new compute-based flow.

@vercel

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

Request Review

@coderabbitai

coderabbitai Bot commented Feb 12, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@cedoor has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 40 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

Added a public Polynomial::from_fhe_polynomial constructor to convert fhe-math Poly into the internal Polynomial. Refactored multiple zk-helpers circuit computations to a CRT-centric reconstruction and parallel per-modulus processing; moved coefficient normalization into Inputs::compute and removed Inputs::standard_form.

Changes

Cohort / File(s) Summary
Polynomial Conversion
crates/polynomial/src/polynomial.rs
Added pub fn from_fhe_polynomial(p: &Poly) -> Self converting an fhe-math Poly (NTT → PowerBasis) into internal Polynomial with BigInt coefficients; added fhe_math::rq::{Poly, Representation} and num_bigint::{BigInt, BigUint, ToBigInt} imports.
CRT-Centric Circuit Refactor
crates/zk-helpers/src/circuits/threshold/user_data_encryption/computation.rs, crates/zk-helpers/src/circuits/dkg/share_encryption/computation.rs
Rewrote per-coefficient RNS logic into CRT-first processing: build CrtPolynomials for ct/pk/e0/u, center/reduce against full modulus set, run parallel per-modulus izip computations (compute e0 quotients, ki, ct_hat, residues), assemble per-modulus results into flat vectors and reconstruct CrtPolynomials; updated final Inputs assembly to use CRT-aligned e0_mod_q and compute modulus bits for commitments. Signature tweak: compute(preset, data)compute(_preset, data) in DKG computation.
Decrypted Shares Aggregation (compute & API)
crates/zk-helpers/src/circuits/threshold/decrypted_shares_aggregation/computation.rs
Moved all reductions into Inputs::compute, removed pub fn standard_form, made to_json private, and ensured Inputs fields (decryption_shares, party_ids, message, u_global, crt_quotients) are reduced/truncated before return.
Docs Only
crates/zk-helpers/src/circuits/threshold/decrypted_shares_aggregation/utils.rs
Updated module docs reference from standard_form to Inputs::compute (no behavioral changes).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • 0xjei
  • hmzakhalid

Poem

🐰 I hop through limbs of modulus and ring,
NTT unwound, BigInts take wing,
CRT limbs march in parallel rows,
Coefficients centered where moonlight glows,
A rabbit claps — behold the new flow!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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 accurately describes the main objective of the pull request - refactoring circuit inputs computation with optimizations across multiple modules.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/input-computation

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.

@cedoor cedoor changed the title refactor: optimize user data encryption computation refactor: optimize circuit inputs computation Feb 12, 2026
@cedoor cedoor requested a review from 0xjei February 12, 2026 16:03
@0xjei 0xjei changed the title refactor: optimize circuit inputs computation refactor: optimize circuit inputs computation [skip-line-limit] Feb 12, 2026
@0xjei 0xjei added this to the PHASE 2: PROVE & VERIFY milestone Feb 12, 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/zk-helpers/src/circuits/threshold/user_data_encryption/computation.rs`:
- Around line 402-433: The code centers ct0/ct1/pk0/pk1 after calling
reduce(&moduli) but calls e0.center(&moduli) without reduce, which confuses
readers because center() requires coefficients in [0, qi); update the code by
adding a concise clarifying comment immediately above the e0 =
CrtPolynomial::from_fhe_polynomial(&e0) / e0.center(&moduli) sequence stating
that error polynomials produced by from_fhe_polynomial() are guaranteed by the
FHE extraction routine to already have coefficients in the canonical [0,qi)
range (or reference the exact guarantee in utils.rs), or alternatively call
e0.reduce(&moduli)? before centering if no such guarantee exists; mention the
involved symbols (e0, from_fhe_polynomial, reduce, center, utils.rs) in the
comment for traceability.
🧹 Nitpick comments (5)
crates/zk-helpers/src/circuits/threshold/user_data_encryption/computation.rs (2)

455-465: expect and assert! will panic in non-test code — acceptable here as CRT invariant guards, but consider returning errors for resilience.

The expect("CRT requires exact division") on line 460 and the assert! on line 462 enforce mathematical invariants that must hold for correct CRT reconstruction. In ZK/crypto code, a violated invariant means the computation is fundamentally broken, so panicking is a defensible choice. That said, if this code ever runs in a context where graceful error propagation is preferred (e.g., a service), converting these to Result-based errors would be more resilient.


586-593: Nit: k1: k1 can be shortened to k1.

Rust allows field shorthand when the field name matches the variable name.

Proposed fix
-            k1: k1,
+            k1,
crates/zk-helpers/src/circuits/dkg/share_encryption/computation.rs (3)

349-351: _preset is actually used — drop the underscore prefix.

The leading underscore conventionally signals an intentionally unused binding. Since _preset is passed to build_pair_for_preset on line 351, the prefix is misleading. Rename to preset.

Proposed fix
-    fn compute(_preset: Self::Preset, data: &Self::Data) -> Result<Self, Self::Error> {
+    fn compute(preset: Self::Preset, data: &Self::Data) -> Result<Self, Self::Error> {
         let (_, dkg_params) =
-            build_pair_for_preset(_preset).map_err(|e| CircuitsErrors::Sample(e.to_string()))?;
+            build_pair_for_preset(preset).map_err(|e| CircuitsErrors::Sample(e.to_string()))?;

385-386: message is not reduced to zkp_modulus, unlike every other polynomial stored in Inputs.

All other polynomials (e1, u, e0_mod_q, and all CRT polynomials) are reduced mod zkp_modulus before being stored. message is skipped. While its coefficients are small enough that reduction is a no-op, the inconsistency may cause confusion or become a latent bug if plaintext encoding changes.

Proposed fix — add reduce for consistency
  e0_mod_q.reduce(&zkp_modulus);
+ message.reduce(&zkp_modulus);

Also applies to: 541-543, 561-561


426-490: Per-modulus parallel block is nearly identical to the threshold/user_data_encryption counterpart.

The izip + par_bridge + map + sort_by_key pattern, including the e0_quotient computation, ct0i_hat/ct1i_hat assembly, and decompose_residue calls, is duplicated almost verbatim across both files. Consider extracting the shared CRT decomposition logic into a reusable helper (e.g., in crate::math or a new crate::crt module) to reduce maintenance burden. This can be deferred to a follow-up.

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