Skip to content

feat: zk-helpers crate [skip-line-limit]#1212

Merged
0xjei merged 13 commits into
mainfrom
feat/1205
Jan 27, 2026
Merged

feat: zk-helpers crate [skip-line-limit]#1212
0xjei merged 13 commits into
mainfrom
feat/1205

Conversation

@0xjei

@0xjei 0xjei commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

This PR adds the zk-helpers crate in order to get rid of most of the utilities for zkp from zkfhe-shared.

Summary by CodeRabbit

  • New Features

    • New ZK helpers crate providing commitments, packing, and utility APIs (including bit-width helpers).
  • Refactor

    • Renamed and consolidated packages to e3-* and migrated many deps into workspace crates.
    • Replaced local commitment logic with the shared helpers across examples and inputs.
    • Simplified preset metadata (removed security classification; added default lambda constants).
  • Chores

    • Updated manifests, build contexts, examples, tests, and a verifier artifact.

✏️ 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.

2 Skipped Deployments
Project Deployment Review Updated (UTC)
crisp Skipped Skipped Jan 27, 2026 3:29pm
enclave-docs Skipped Skipped Jan 27, 2026 3:29pm

Request Review

@coderabbitai

coderabbitai Bot commented Jan 27, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a new workspace crate e3-zk-helpers (packing, utils, commitments), renames several crates to e3- prefixes, replaces git-based zkfhe-shared usages with the workspace crate, adds a ciphertext domain separator and compute_ciphertext_commitment in Noir, and updates Cargo manifests, imports, and CRISP example wiring. (50 words)

Changes

Cohort / File(s) Summary
Workspace / Manifests
Cargo.toml, crates/support/Cargo.toml, crates/support/program/Cargo.toml, crates/Dockerfile, examples/CRISP/server/Dockerfile
Added crates/zk-helpers workspace member; added/updated workspace dependencies (e3-fhe-params rev bump); included crates/zk-helpers/Cargo.toml in Docker build contexts.
New crate: e3-zk-helpers
crates/zk-helpers/Cargo.toml, crates/zk-helpers/src/lib.rs, crates/zk-helpers/src/commitments.rs, crates/zk-helpers/src/packing.rs, crates/zk-helpers/src/utils.rs
New crate exposing packing, utils, and commitments: domain separators, SAFE sponge wrapper, bigint↔field conversion, nibble-aligned packing/flattening, and many compute_* commitment/challenge functions (public API additions).
Crate renames / dependency rewires
crates/polynomial/Cargo.toml, crates/safe/Cargo.toml, crates/polynomial/*, examples/CRISP/Cargo.toml, examples/CRISP/crates/zk-inputs/Cargo.toml
Renamed packages to e3-polynomial / e3-safe; converted ark deps and others to workspace = true; updated example manifests to use e3- crates.
Replace external shared crate usages
crates/greco-helpers/Cargo.toml, crates/greco-helpers/src/lib.rs, crates/bfv-client/Cargo.toml, crates/bfv-client/src/client.rs, examples/CRISP/crates/zk-inputs/src/*
Removed git zkfhe-shared deps; switched imports to e3-zk-helpers APIs (commitments, calculate_bit_width, get_zkp_modulus); removed local CRISP commitments module and updated callers.
Noir circuits
circuits/lib/src/math/commitments.nr, examples/CRISP/circuits/src/main.nr, examples/CRISP/circuits/src/commitments.nr
Added DS_CIPHERTEXT and compute_ciphertext_commitment in Noir; corrected several DS constants; replaced calls to removed local compute_ct_commitment; deleted obsolete CRISP commitments.nr.
FHE params / presets
crates/fhe-params/src/constants.rs, crates/fhe-params/src/presets.rs, crates/fhe-params/Cargo.toml
Added DEFAULT_INSECURE_LAMBDA and DEFAULT_SECURE_LAMBDA; removed PresetMetadata.security_level; switched imports to local defaults and removed external shared dep.
Benchmarks / docs updates
crates/polynomial/benches/polynomial.rs, crates/polynomial/src/polynomial.rs
Updated imports and doc examples to e3_polynomial.
CRISP example updates
examples/CRISP/*, examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol, templates/default/program/src/lib.rs
Wired CRISP to use e3-zk-helpers commitments and utils; removed local compute_commitment implementation; updated verifier constants/licensing and adjusted test vectors.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Caller (CRISP / callers)
    participant Packer as Packer (e3-zk-helpers::packing)
    participant Conv as Converter (e3-zk-helpers::utils::bigint_to_field)
    participant Safe as SAFE (e3-safe / compute_safe)

    Caller->>Packer: flatten(polynomial arrays, bit) -> Vec<Field>
    Packer-->>Caller: flattened payload (Vec<Field))
    Caller->>Safe: compute_safe(DS_CIPHERTEXT, payload, io_pattern)
    Safe-->>Caller: squeezed fields (Vec<Field))
    Caller->>Conv: convert first Field -> BigInt (commitment)
    Conv-->>Caller: commitment BigInt
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

noir, crisp

Suggested reviewers

  • cedoor
  • ryardley
  • hmzakhalid

Poem

🐰 I hopped through crates both near and far,
Packed polynomials beneath a tiny star,
SAFE sponge hummed and bits aligned just right,
Commitments stitched by day and through the night,
A cheerful rabbit cheers: code takes flight!

🚥 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 clearly and specifically describes the primary change: introducing a new 'zk-helpers' crate to consolidate zero-knowledge proof utilities.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ 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: zk-helpers crate feat: zk-helpers crate [skip-line-limit] Jan 27, 2026
@0xjei 0xjei changed the title feat: zk-helpers crate [skip-line-limit] feat: zk-helpers crate [skip-line-limit] Jan 27, 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: 3

🤖 Fix all issues with AI agents
In `@crates/zk-helpers/src/commitments.rs`:
- Around line 296-300: Before indexing coeff_y[mod_idx][party_idx + 1], add
explicit bounds validation: verify mod_idx < coeff_y.len() and party_idx + 1 <
coeff_y[mod_idx].len(); if the check fails, return a descriptive error
(propagate Result) from the surrounding function or, if you cannot change the
signature, early-return or panic with a clear message indicating invalid
mod_idx/party_idx and the offending values; after the guards, continue pushing
crate::utils::bigint_to_field(share_value) into payload as before.

In `@crates/zk-helpers/src/utils.rs`:
- Around line 125-138: The calculate_bit_width function currently overcounts
bits by adding an extra +1 to bound.bits(); fix it so bit_width is computed from
(bound - 1).bits() + 1 for positive bounds: for calculate_bit_width, after
parsing bound and handling bound <= 0, compute a new BigInt bound_minus_one =
&bound - BigInt::from(1) and set bit_width = (bound_minus_one.bits() as u32) + 1
(instead of using bound.bits() and the extra +1); this aligns packing logic used
by compute_ciphertext_commitment/flatten and fixes off-by-one for powers of two.

In `@templates/default/program/src/lib.rs`:
- Around line 51-55: The inline comment "// 10" is stale relative to the
encrypted value [3u64]; update the code so the comment and variable name match
the value—either change the comment to "// 3" or rename the variable ten to
three and update all subsequent uses (e.g., the variable declared at let ten =
public_key.try_encrypt(...) and any later reference on line 66) to keep
identifiers and comments consistent with Plaintext::try_encode(&[3u64], ...).

Comment thread crates/zk-helpers/src/commitments.rs
Comment thread crates/zk-helpers/src/utils.rs Outdated
Comment thread templates/default/program/src/lib.rs Outdated

@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 `@templates/default/program/src/lib.rs`:
- Around line 51-55: The test vector is mislabeled: the variable ten is
encrypting the plaintext [3] via
public_key.try_encrypt(Plaintext::try_encode(&[3u64], Encoding::poly(),
&params)...) while the inline comment "// 10" is incorrect (and the expected sum
is 5). Fix by either renaming the variable ten to three (or a more descriptive
name like encrypted_three) wherever it's declared/used, or update the comment to
reflect the actual value (e.g., "// 3"); ensure the same fix is applied to the
second occurrence around the other instance (line ~75) so
Plaintext::try_encode(&[3u64], ...) and any uses of ten are consistent.
🧹 Nitpick comments (7)
crates/polynomial/Cargo.toml (1)

2-7: Repository URL may need updating for consistency.

The package was renamed to e3-polynomial, but the repository URL still references the old path crates/polynomial. Consider updating to reflect the new naming convention if the directory will be renamed, or verify this is intentional.

examples/CRISP/circuits/src/main.nr (1)

173-175: Use config constants for commitment generics.
Hard‑coding 512, 2, 36 risks drift if GRECO configs change; using N, L, and GRECO_BIT_CT keeps commitments aligned.

♻️ Suggested update
-    let ct_commitment = compute_ciphertext_commitment::<512, 2, 36>(ct0is, ct1is);
+    let ct_commitment = compute_ciphertext_commitment::<N, L, GRECO_BIT_CT>(ct0is, ct1is);
...
-            let _prev_ct_commitment =
-                compute_ciphertext_commitment::<512, 2, 36>(prev_ct0is, prev_ct1is);
-            let sum_ct_commitment =
-                compute_ciphertext_commitment::<512, 2, 36>(sum_ct0is, sum_ct1is);
+            let _prev_ct_commitment =
+                compute_ciphertext_commitment::<N, L, GRECO_BIT_CT>(prev_ct0is, prev_ct1is);
+            let sum_ct_commitment =
+                compute_ciphertext_commitment::<N, L, GRECO_BIT_CT>(sum_ct0is, sum_ct1is);

Also applies to: 190-193

Cargo.toml (1)

117-118: Pin arkworks versions to match workspace pinning policy.
External dependencies in the workspace use exact-pinned versions (e.g., actix = "=0.13.5"), but ark-ff and ark-bn254 use semver ranges ("0.5"). For consistency and reproducibility, consider pinning both to specific patch versions.

crates/zk-helpers/src/utils.rs (3)

16-17: Consider consolidating the redundant type aliases.

Both Field and FieldElement alias the same type ark_bn254::Fr. If both names are intentionally used for semantic distinction in different contexts, consider adding a brief comment explaining their purpose. Otherwise, consolidate to a single alias.

♻️ Suggested simplification
-use ark_bn254::Fr as Field;
-use ark_bn254::Fr as FieldElement;
+use ark_bn254::Fr as Field;
+
+// Re-export for compatibility if needed elsewhere
+pub type FieldElement = Field;

101-113: The negative value handling in bigint_to_field has redundant fallback logic.

Line 104 computes (value % zkp_modulus) + &zkp_modulus for negative values, which should always produce a value in [0, modulus). The unwrap_or_else fallback at lines 108-110 handles the case where to_biguint() fails, but after the modular reduction this should never happen.

Consider simplifying:

♻️ Suggested simplification
 pub fn bigint_to_field(value: &BigInt) -> FieldElement {
     let zkp_modulus = get_zkp_modulus();
-    let reduced = if value < &BigInt::zero() {
-        (value % &zkp_modulus) + &zkp_modulus
-    } else {
-        value % &zkp_modulus
-    };
-    let biguint = reduced
-        .to_biguint()
-        .unwrap_or_else(|| (&zkp_modulus + reduced).to_biguint().unwrap());
+    let reduced = ((value % &zkp_modulus) + &zkp_modulus) % &zkp_modulus;
+    let biguint = reduced
+        .to_biguint()
+        .expect("reduced value should be non-negative after modular reduction");
     let bytes = biguint.to_bytes_le();
     FieldElement::from_le_bytes_mod_order(&bytes)
 }

131-139: Clarify the bit-width calculation formula in the docstring.

The docstring states the formula is ceil(log₂(bound)) + 1, but BigInt::bits() already returns floor(log₂(n)) + 1 for positive n. The actual computation is therefore approximately ceil(floor(log₂(bound)) + 1) + 1, which may yield more bits than expected for exact powers of 2.

If this extra margin is intentional for the ZK circuit requirements, a clarifying comment would help future maintainers understand the rationale.

crates/zk-helpers/src/commitments.rs (1)

472-487: Refactor to return Result instead of panicking on PK commitment mismatch.
This is a public API function that should gracefully handle invalid inputs through error types rather than panic. The function currently panics when pk_commitment doesn't match the computed commitment; returning Result<Vec<BigInt>, E> would allow callers to decide how to handle this validation failure. The crate already uses thiserror for error handling, supporting this pattern.

Comment thread templates/default/program/src/lib.rs Outdated
cedoor
cedoor previously approved these changes Jan 27, 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 `@Cargo.toml`:
- Around line 118-119: Update the ark-* crate entries in Cargo.toml to use exact
patch pins like the rest of the workspace: change the ark-ff and ark-bn254
dependency specifications to use the exact version string (e.g., "=0.5.0") so
they follow the same pinning pattern as other crates; update the entries named
ark-ff and ark-bn254 accordingly.

Comment thread Cargo.toml Outdated
@cedoor cedoor self-requested a review January 27, 2026 15:13
cedoor
cedoor previously approved these changes Jan 27, 2026
cedoor
cedoor previously approved these changes Jan 27, 2026
@vercel vercel Bot temporarily deployed to Preview – enclave-docs January 27, 2026 15:29 Inactive
@vercel vercel Bot temporarily deployed to Preview – crisp January 27, 2026 15:29 Inactive
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.

extract utilities from shared

2 participants