Skip to content

feat: greco, e0 == e0is[i] check#1049

Merged
cedoor merged 11 commits into
mainfrom
feat/greco-e0-e0is-check
Dec 2, 2025
Merged

feat: greco, e0 == e0is[i] check#1049
cedoor merged 11 commits into
mainfrom
feat/greco-e0-e0is-check

Conversation

@ozgurarmanc

@ozgurarmanc ozgurarmanc commented Nov 25, 2025

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added CRT decomposition support with per-modulus components and quotient data, plus a pre-challenge CRT consistency check in verification.
  • Documentation

    • Verification flow updated to show CRT consistency as a distinct pre-challenge step and public data layout clarified.
  • Refactor

    • Public constructors and input layouts reordered to accommodate the new CRT data.
  • Chores

    • Example input serialization and SDK types extended to include CRT quotient data; on-chain verifier key data updated.

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

@ozgurarmanc ozgurarmanc self-assigned this Nov 25, 2025
@ozgurarmanc ozgurarmanc added the noir Task related to the noir fork or noir focussed code label Nov 25, 2025
@vercel

vercel Bot commented Nov 25, 2025

Copy link
Copy Markdown

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

Project Deployment Preview Comments Updated (UTC)
crisp Ready Ready Preview Comment Dec 2, 2025 2:35pm
enclave-docs Ready Ready Preview Comment Dec 2, 2025 2:35pm

@coderabbitai

coderabbitai Bot commented Nov 25, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Added CRT decomposition fields for e0 (per-base residues and quotient polynomials), updated Greco struct/constructor and call sites to accept/reorder them, implemented a private coefficient-wise CRT consistency check invoked in verify() before Fiat–Shamir challenge generation, and propagated changes through serialization and SDK types.

Changes

Cohort / File(s) Summary
Greco circuit CRT enhancements
circuits/crates/libs/greco/src/lib.nr
Added e0is: [Polynomial<N>; L] and e0_quotients: [Polynomial<N>; L] fields and moved e1 after them; updated Greco::new signature/initialization; added private check_e0_crt_consistency(self) performing coefficient-wise CRT checks using qi; invoked this check in verify() before Fiat‑Shamir challenge generation; updated docs/comments and expected public layout.
Example call-site update (NR)
examples/CRISP/circuits/src/main.nr
Added e0_quotients: [Polynomial<512>; 2] parameter and reordered parameters so e1 follows e0is/e0_quotients; updated Greco::new(...) call to pass e0_quotients in the new position.
ZK inputs serialization (Rust)
examples/CRISP/crates/zk-inputs/src/serialization.rs
Added e0_quotients: Vec<serde_json::Value> to ZKInputs; compute per-base quotients in construct_inputs by (e0[j] - e0is[i][j]) / qis[i] per coefficient and serialize them; moved e1 to follow e0_quotients.
SDK types update (TS)
examples/CRISP/packages/crisp-sdk/src/types.ts
Added e0_quotients: Polynomial[] to CRISPCircuitInputs and moved e1 to follow e0_quotients/e0is, changing the public input interface shape.
Verifier key update (Solidity)
examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol
Replaced VK_HASH constant and updated many verification-key G1 point constants and arrays with new coordinates/values; no API/signature changes.

Sequence Diagram(s)

sequenceDiagram
    participant Verifier as verify()
    participant CRT as check_e0_crt_consistency()
    participant FS as Fiat‑Shamir (challenge gen)
    participant VerifRest as remaining verification

    Verifier->>CRT: Validate e0 CRT decomposition (coeff-wise using qis)
    rect rgb(235,245,255)
        Note over CRT: NEW — verify residues + quotients reconstruct e0 across bases
    end
    CRT-->>Verifier: OK / Error
    alt OK
        Verifier->>FS: Generate Fiat‑Shamir challenges
        FS-->>Verifier: Challenges
        Verifier->>VerifRest: Continue verification using challenges and inputs (including e0is/e0_quotients)
        VerifRest-->>Verifier: Verification result
    else Error
        Verifier-->>Verifier: Abort / Reject proof
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Focus areas:
    • Correctness of coefficient-wise CRT reconstruction and modulus handling (qi) in check_e0_crt_consistency.
    • All Greco::new call sites and parameter ordering across examples.
    • Serialization correctness and JSON shape for e0_quotients in ZKInputs.
    • Consistency between TypeScript interface and serialized input shape.
    • Large data changes in CRISPVerifier.sol (VK constants) — verify values were copied correctly.

Possibly related PRs

Suggested reviewers

  • zahrajavar

Poem

🐇 I nibble coefficients by moonlit byte,
I split e0 into residues neat and bright,
Quotients hop in rows to stitch each part,
I check the CRT stitch with a careful heart,
Then thump—proof holds, and I bound with delight.

Pre-merge checks and finishing touches

✅ 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 identifies the main change: adding an e0 == e0is[i] consistency check to the Greco verification flow, which is the core objective described in the PR summary.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/greco-e0-e0is-check

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3638bb4 and ec7ae95.

📒 Files selected for processing (1)
  • examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 972
File: circuits/crates/libs/greco/src/lib.nr:192-192
Timestamp: 2025-11-07T16:17:58.988Z
Learning: In the Greco library (circuits/crates/libs/greco/src/lib.nr), the e1is array should satisfy the constraint `e1 mod qi == e1is[i]` for each CRT basis i, where qi are the CRT moduli. This constraint ensures the relationship between the global error polynomial e1 and its per-basis representations e1is[i].
Learnt from: ozgurarmanc
Repo: gnosisguild/enclave PR: 734
File: packages/circuits/crates/libs/polynomial/src/lib.nr:140-155
Timestamp: 2025-09-22T15:08:29.814Z
Learning: Greco (packages/circuits/crates/libs/greco/src/lib.nr) performs range_check_1bound/2bounds on all polynomials (u, e0/e1, k1, pk*, r*, p*) before serialization; packer/flatten rely on these bounds, so per-limb asserts inside packer are unnecessary in this crate’s flow.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: integration_prebuild
  • GitHub Check: test_contracts
  • GitHub Check: build_e3_support_risc0
  • GitHub Check: rust_integration
  • GitHub Check: build_e3_support_dev
  • GitHub Check: build_sdk
  • GitHub Check: test_net
  • GitHub Check: crisp_rust_unit
  • GitHub Check: rust_unit
  • GitHub Check: build_enclave_cli
🔇 Additional comments (2)
examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol (2)

14-132: Verification key G1Points updated for modified circuit selectors and permutations.

The G1Point coordinates for the verification key have been regenerated. The updated points (selectors ql-qPoseidon2Internal, sigma polynomials s1-s4, identity polynomials id1-id4, and lagrangeLast) reflect the new constraint structure after adding the e0 CRT consistency check.

Note that qLookup, t1-t4, and lagrangeFirst remain unchanged, which is expected as these typically represent lookup tables and fixed Lagrange basis points that are independent of the specific constraint additions.


11-11: Verify VK_HASH constant matches circuit compilation output.

The VK_HASH has been updated to reflect the new verification key after modifying circuit constraints (adding e0 CRT consistency check to Greco). This constant must match the output from circuit compilation and is used in Fiat-Shamir transcript generation.

Before merging, verify that:

  1. The VK_HASH value matches your circuit compilation output
  2. End-to-end proof verification passes with the updated verification key

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.

@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

Caution

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

⚠️ Outside diff range comments (1)
circuits/crates/libs/greco/src/lib.nr (1)

227-259: Update Greco::new call sites to match constructor signature with e0_quotients parameter

Verification confirms the constructor signature includes e0_quotients, but actual call sites are misaligned:

  • ./examples/CRISP/circuits/src/main.nr (lines 75-89): Missing e0_quotients parameter; has e1 before e0is instead of after e0_quotients
  • ./packages/enclave-sdk/tests/fixtures/demo_circuit.json (line 220): Embedded source code has the same parameter order issue

Update both call sites to pass arguments in the correct order: ..., u, e0, e0is, e0_quotients, e1, k1, ...

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 17cd488 and 2d6e5da.

📒 Files selected for processing (1)
  • circuits/crates/libs/greco/src/lib.nr (5 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 972
File: circuits/crates/libs/greco/src/lib.nr:192-192
Timestamp: 2025-11-07T16:17:58.988Z
Learning: In the Greco library (circuits/crates/libs/greco/src/lib.nr), the e1is array should satisfy the constraint `e1 mod qi == e1is[i]` for each CRT basis i, where qi are the CRT moduli. This constraint ensures the relationship between the global error polynomial e1 and its per-basis representations e1is[i].
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 648
File: examples/CRISP/circuits/src/main.nr:40-44
Timestamp: 2025-08-27T13:49:48.617Z
Learning: In CRISP circuits using Greco library, the binary check `assert(0 == b * (qmt - b))` for polynomial k1 should not be applied to all coefficients - only specific coefficients require this constraint, such as `k1.coefficients[2048 - 1]`.
📚 Learning: 2025-11-07T16:17:58.988Z
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 972
File: circuits/crates/libs/greco/src/lib.nr:192-192
Timestamp: 2025-11-07T16:17:58.988Z
Learning: In the Greco library (circuits/crates/libs/greco/src/lib.nr), the e1is array should satisfy the constraint `e1 mod qi == e1is[i]` for each CRT basis i, where qi are the CRT moduli. This constraint ensures the relationship between the global error polynomial e1 and its per-basis representations e1is[i].

Applied to files:

  • circuits/crates/libs/greco/src/lib.nr
📚 Learning: 2025-09-22T15:08:29.814Z
Learnt from: ozgurarmanc
Repo: gnosisguild/enclave PR: 734
File: packages/circuits/crates/libs/polynomial/src/lib.nr:140-155
Timestamp: 2025-09-22T15:08:29.814Z
Learning: Greco (packages/circuits/crates/libs/greco/src/lib.nr) performs range_check_1bound/2bounds on all polynomials (u, e0/e1, k1, pk*, r*, p*) before serialization; packer/flatten rely on these bounds, so per-limb asserts inside packer are unnecessary in this crate’s flow.

Applied to files:

  • circuits/crates/libs/greco/src/lib.nr
📚 Learning: 2025-08-27T13:49:48.617Z
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 648
File: examples/CRISP/circuits/src/main.nr:40-44
Timestamp: 2025-08-27T13:49:48.617Z
Learning: In CRISP circuits using Greco library, the binary check `assert(0 == b * (qmt - b))` for polynomial k1 should not be applied to all coefficients - only specific coefficients require this constraint, such as `k1.coefficients[2048 - 1]`.

Applied to files:

  • circuits/crates/libs/greco/src/lib.nr
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: integration_prebuild
  • GitHub Check: test_net
  • GitHub Check: rust_integration
  • GitHub Check: build_sdk
  • GitHub Check: build_enclave_cli
  • GitHub Check: test_contracts
  • GitHub Check: crisp_rust_unit
  • GitHub Check: rust_unit
🔇 Additional comments (4)
circuits/crates/libs/greco/src/lib.nr (4)

183-199: Struct additions for e0is / e0_quotients are consistent with usage

The new e0_quotients: [Polynomial<N>; L] field is wired consistently with the rest of the struct and later method usage (check_e0_crt_consistency, verify_evaluations). Keeping e0is/e0_quotients out of the Fiat–Shamir payload is acceptable since they are only used in direct coefficient constraints rather than challenge‑based checks.


207-222: Constructor docs for e0is / e0_quotients are clear and aligned with intent

The new argument documentation correctly explains that e0is is the CRT decomposition of e0 and e0_quotients are quotient witnesses for the CRT relation, matching the semantics enforced later in check_e0_crt_consistency.


332-333: Verification step commentary matches the updated flow

The added step description for “CRT consistency for e0 polynomial” correctly reflects the new call to check_e0_crt_consistency inserted before the encryption‑equation checks.


352-363: Placement of CRT consistency check in verify is appropriate

Running check_e0_crt_consistency() right after range checks and before Fiat–Shamir challenge generation is sound: CRT consistency is enforced deterministically, and the FS challenges are then used solely for the Schwartz–Zippel‑style encryption equations. No further issues with the sequencing.

Comment thread circuits/crates/libs/greco/src/lib.nr

@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

🧹 Nitpick comments (2)
circuits/crates/libs/greco/src/lib.nr (2)

191-193: Clarify treatment of e0is/e0_quotients in bounds and payload docs

Struct and constructor wiring for e0_quotients look correct; the new field is consistently threaded through Greco::new. However:

  • check_range_bounds (Line 368 onwards) still only constrains u, e0, e1, k1, pk*, r*, p*; e0is and e0_quotients remain entirely unconstrained aside from the algebraic equalities.
  • payload/generate_challenge comments describe “flattening all polynomials / absorbing all witness values”, but the new CRT witnesses are not included in the flattened inputs.

If the intention is that e0is/e0_quotients are purely auxiliary CRT witnesses whose concrete values do not matter for Fiat–Shamir (only that they satisfy the equalities), it would be good to:

  • Explicitly state in the doc comments that these CRT witnesses are not range-checked or included in the payload, and
  • Confirm that this is acceptable for your integer/CRT soundness argument; otherwise consider adding dedicated bounds or including them in the payload with an appropriate bit-width.

Also applies to: 215-216, 234-259, 368-409


328-329: Verify ordering and documentation of the new CRT consistency step

Hooking check_e0_crt_consistency into verify immediately after check_range_bounds and before challenge generation is the right place for this kind of structural check, and the updated step numbering in the docstring matches the code.

One minor thing to double-check: comments above the encryption equations (Lines 336–338) still describe them in terms of e0(gamma), while verify_evaluations uses e0is[i] in the ct0 equation and now relies on the CRT consistency check to tie e0 and e0is. It may be worth updating the comment to mention that the enforced equation is written with e0is but is equivalent to the intended e0-based equation under the CRT constraints, just to avoid confusion for future readers.

Also applies to: 351-352, 354-354, 357-359

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d6e5da and 14c715e.

📒 Files selected for processing (1)
  • circuits/crates/libs/greco/src/lib.nr (5 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 972
File: circuits/crates/libs/greco/src/lib.nr:192-192
Timestamp: 2025-11-07T16:17:58.988Z
Learning: In the Greco library (circuits/crates/libs/greco/src/lib.nr), the e1is array should satisfy the constraint `e1 mod qi == e1is[i]` for each CRT basis i, where qi are the CRT moduli. This constraint ensures the relationship between the global error polynomial e1 and its per-basis representations e1is[i].
📚 Learning: 2025-11-07T16:17:58.988Z
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 972
File: circuits/crates/libs/greco/src/lib.nr:192-192
Timestamp: 2025-11-07T16:17:58.988Z
Learning: In the Greco library (circuits/crates/libs/greco/src/lib.nr), the e1is array should satisfy the constraint `e1 mod qi == e1is[i]` for each CRT basis i, where qi are the CRT moduli. This constraint ensures the relationship between the global error polynomial e1 and its per-basis representations e1is[i].

Applied to files:

  • circuits/crates/libs/greco/src/lib.nr
📚 Learning: 2025-09-22T15:08:29.814Z
Learnt from: ozgurarmanc
Repo: gnosisguild/enclave PR: 734
File: packages/circuits/crates/libs/polynomial/src/lib.nr:140-155
Timestamp: 2025-09-22T15:08:29.814Z
Learning: Greco (packages/circuits/crates/libs/greco/src/lib.nr) performs range_check_1bound/2bounds on all polynomials (u, e0/e1, k1, pk*, r*, p*) before serialization; packer/flatten rely on these bounds, so per-limb asserts inside packer are unnecessary in this crate’s flow.

Applied to files:

  • circuits/crates/libs/greco/src/lib.nr
📚 Learning: 2025-08-27T13:49:48.617Z
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 648
File: examples/CRISP/circuits/src/main.nr:40-44
Timestamp: 2025-08-27T13:49:48.617Z
Learning: In CRISP circuits using Greco library, the binary check `assert(0 == b * (qmt - b))` for polynomial k1 should not be applied to all coefficients - only specific coefficients require this constraint, such as `k1.coefficients[2048 - 1]`.

Applied to files:

  • circuits/crates/libs/greco/src/lib.nr
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: build_enclave_cli
  • GitHub Check: test_net
  • GitHub Check: test_contracts
  • GitHub Check: integration_prebuild
  • GitHub Check: build_e3_support_risc0
  • GitHub Check: crisp_rust_unit
  • GitHub Check: rust_integration
  • GitHub Check: build_e3_support_dev
  • GitHub Check: rust_unit
  • GitHub Check: build_sdk
🔇 Additional comments (1)
circuits/crates/libs/greco/src/lib.nr (1)

295-321: Coefficient-wise CRT check for e0 now matches the intended security property

The new check_e0_crt_consistency implementation performs a per-coefficient assertion:

  • For each i in 0..L and j in 0..N, it enforces
    e0[j] == e0is[i][j] + e0_quotients[i][j] * qis[i].

This is the right granularity: it enforces e0 ≡ e0is[i] (mod qi) coefficient-wise and avoids the earlier pitfall where summing differences into a single accumulator allowed cancellations across coefficients. This aligns with the prior design goal for CRT consistency (similar to the earlier e1/e1is constraints). Based on learnings, this is the correct shape of constraint.

@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

🧹 Nitpick comments (1)
examples/CRISP/crates/zk-inputs/src/serialization.rs (1)

234-251: Tighten invariants and tests around e0_quotients CRT decomposition

The e0_quotients computation looks correct conceptually, but it currently relies on several implicit invariants:

  • vectors_standard.e0is.len() must equal crypto_params.moduli.len(); otherwise moduli[i] can panic if e0is is longer.
  • Each e0i must have the same length as vectors_standard.e0; otherwise zip silently truncates to the shorter length and drops trailing coefficients.
  • For the intended CRT relation, you also rely on (e0_coeff - e0i_coeff) being divisible by qi so the quotient matches the witness used in the Greco check.

If these properties are guaranteed elsewhere, consider adding a short comment and/or debug_assert_eq!s to document them for future maintainers.

To make the new field harder to accidentally break, it would help to extend the tests to cover both the in‑memory and JSON shapes. For example:

@@ fn test_construct_inputs_basic() {
-        assert!(inputs.u.is_object());
-        assert!(inputs.e0.is_object());
-        assert!(inputs.e1.is_object());
-        assert!(inputs.k1.is_object());
+        assert!(inputs.u.is_object());
+        assert!(inputs.e0.is_object());
+        assert!(inputs.e1.is_object());
+        assert!(inputs.k1.is_object());
+        // e0 has one CRT slice per modulus, and quotients mirror that shape.
+        assert_eq!(inputs.e0is.len(), vectors.e0is.len());
+        assert_eq!(inputs.e0_quotients.len(), vectors.e0is.len());
@@ fn test_serialize_inputs_to_json() {
-        assert!(parsed.get("pk0is").is_some());
-        assert!(parsed.get("pk1is").is_some());
+        assert!(parsed.get("pk0is").is_some());
+        assert!(parsed.get("pk1is").is_some());
+        assert!(parsed.get("e0_quotients").is_some());

This both documents the expected shape and ensures future refactors keep e0_quotients wired up correctly. Based on learnings, this mirrors the CRT relation previously enforced for e1 and e1is.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b53adf6 and 3c81fa8.

📒 Files selected for processing (1)
  • examples/CRISP/crates/zk-inputs/src/serialization.rs (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 972
File: circuits/crates/libs/greco/src/lib.nr:192-192
Timestamp: 2025-11-07T16:17:58.988Z
Learning: In the Greco library (circuits/crates/libs/greco/src/lib.nr), the e1is array should satisfy the constraint `e1 mod qi == e1is[i]` for each CRT basis i, where qi are the CRT moduli. This constraint ensures the relationship between the global error polynomial e1 and its per-basis representations e1is[i].
Learnt from: ozgurarmanc
Repo: gnosisguild/enclave PR: 734
File: packages/circuits/crates/libs/polynomial/src/lib.nr:140-155
Timestamp: 2025-09-22T15:08:29.814Z
Learning: Greco (packages/circuits/crates/libs/greco/src/lib.nr) performs range_check_1bound/2bounds on all polynomials (u, e0/e1, k1, pk*, r*, p*) before serialization; packer/flatten rely on these bounds, so per-limb asserts inside packer are unnecessary in this crate’s flow.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: rust_integration
  • GitHub Check: build_e3_support_risc0
  • GitHub Check: build_sdk
  • GitHub Check: build_e3_support_dev
  • GitHub Check: test_contracts
  • GitHub Check: build_enclave_cli
  • GitHub Check: integration_prebuild
  • GitHub Check: test_net
  • GitHub Check: crisp_rust_unit
  • GitHub Check: rust_unit
🔇 Additional comments (1)
examples/CRISP/crates/zk-inputs/src/serialization.rs (1)

39-42: Public ZKInputs JSON contract changed; confirm all downstream consumers are updated

ZKInputs is pub and Serialize, so adding e0_quotients and moving e1 changes the serialized JSON shape (new key and key order). That’s usually fine, but any code that:

  • deserializes with a fixed schema, or
  • relies on a particular field order for hashing/transcripts

will need to tolerate/expect the new field and position. Please double‑check CRISP consumers, circuit drivers, and tooling that read these witnesses to ensure they accept the updated schema.

@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

🧹 Nitpick comments (1)
examples/CRISP/packages/crisp-sdk/src/types.ts (1)

156-157: Document CRT alignment invariants for e0is/e0_quotients.

The new e0_quotients: Polynomial[] plus reordered e1 look consistent with the Greco changes (CRT decomposition of e0 and updated constructor ordering). To make this easier to use correctly from the SDK side, consider adding a brief comment here clarifying that:

  • e0is and e0_quotients have the same length as crypto.qis, and
  • they are index‑aligned with the CRT basis (i.e., for each i, e0 is reconstructed from e0is[i] and e0_quotients[i] against qis[i]).

This mirrors the documented relationship for e1/e1is in the Greco library and will help callers avoid subtle mis-ordering bugs. Based on learnings, this keeps the CRT constraints explicit at the type boundary.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3c81fa8 and ce6ec31.

📒 Files selected for processing (1)
  • examples/CRISP/packages/crisp-sdk/src/types.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 972
File: circuits/crates/libs/greco/src/lib.nr:192-192
Timestamp: 2025-11-07T16:17:58.988Z
Learning: In the Greco library (circuits/crates/libs/greco/src/lib.nr), the e1is array should satisfy the constraint `e1 mod qi == e1is[i]` for each CRT basis i, where qi are the CRT moduli. This constraint ensures the relationship between the global error polynomial e1 and its per-basis representations e1is[i].
Learnt from: ozgurarmanc
Repo: gnosisguild/enclave PR: 734
File: packages/circuits/crates/libs/polynomial/src/lib.nr:140-155
Timestamp: 2025-09-22T15:08:29.814Z
Learning: Greco (packages/circuits/crates/libs/greco/src/lib.nr) performs range_check_1bound/2bounds on all polynomials (u, e0/e1, k1, pk*, r*, p*) before serialization; packer/flatten rely on these bounds, so per-limb asserts inside packer are unnecessary in this crate’s flow.

@zahrajavar

Copy link
Copy Markdown
Contributor

the check_e0_crt_consistency function looks good to me.

@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

🧹 Nitpick comments (1)
circuits/crates/libs/greco/src/lib.nr (1)

271-293: Optional: consider whether e0is/e0_quotients should be absorbed into the Fiat–Shamir payload

Right now payload() only flattens pk*, ct*, e0, e1, u, k1, r*, p*; the new CRT witnesses e0is and e0_quotients only affect constraints via check_e0_crt_consistency and the ct0 evaluation equation, but are not part of the sponge input. If you want the FS challenges to be bound to all independent witness polynomials, it may be worth either (a) including these arrays in payload() or (b) explicitly documenting that they are treated as derived from e0/qis (and thus not independent). This is not a correctness bug, just something to double‑check against your proof/soundness argument.

Also applies to: 295-321

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ce6ec31 and 3638bb4.

📒 Files selected for processing (4)
  • circuits/crates/libs/greco/src/lib.nr (5 hunks)
  • examples/CRISP/circuits/src/main.nr (2 hunks)
  • examples/CRISP/crates/zk-inputs/src/serialization.rs (2 hunks)
  • examples/CRISP/packages/crisp-sdk/src/types.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • examples/CRISP/crates/zk-inputs/src/serialization.rs
  • examples/CRISP/packages/crisp-sdk/src/types.ts
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 972
File: circuits/crates/libs/greco/src/lib.nr:192-192
Timestamp: 2025-11-07T16:17:58.988Z
Learning: In the Greco library (circuits/crates/libs/greco/src/lib.nr), the e1is array should satisfy the constraint `e1 mod qi == e1is[i]` for each CRT basis i, where qi are the CRT moduli. This constraint ensures the relationship between the global error polynomial e1 and its per-basis representations e1is[i].
Learnt from: ozgurarmanc
Repo: gnosisguild/enclave PR: 734
File: packages/circuits/crates/libs/polynomial/src/lib.nr:140-155
Timestamp: 2025-09-22T15:08:29.814Z
Learning: Greco (packages/circuits/crates/libs/greco/src/lib.nr) performs range_check_1bound/2bounds on all polynomials (u, e0/e1, k1, pk*, r*, p*) before serialization; packer/flatten rely on these bounds, so per-limb asserts inside packer are unnecessary in this crate’s flow.
📚 Learning: 2025-11-07T16:17:58.988Z
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 972
File: circuits/crates/libs/greco/src/lib.nr:192-192
Timestamp: 2025-11-07T16:17:58.988Z
Learning: In the Greco library (circuits/crates/libs/greco/src/lib.nr), the e1is array should satisfy the constraint `e1 mod qi == e1is[i]` for each CRT basis i, where qi are the CRT moduli. This constraint ensures the relationship between the global error polynomial e1 and its per-basis representations e1is[i].

Applied to files:

  • circuits/crates/libs/greco/src/lib.nr
  • examples/CRISP/circuits/src/main.nr
📚 Learning: 2025-09-22T15:08:29.814Z
Learnt from: ozgurarmanc
Repo: gnosisguild/enclave PR: 734
File: packages/circuits/crates/libs/polynomial/src/lib.nr:140-155
Timestamp: 2025-09-22T15:08:29.814Z
Learning: Greco (packages/circuits/crates/libs/greco/src/lib.nr) performs range_check_1bound/2bounds on all polynomials (u, e0/e1, k1, pk*, r*, p*) before serialization; packer/flatten rely on these bounds, so per-limb asserts inside packer are unnecessary in this crate’s flow.

Applied to files:

  • circuits/crates/libs/greco/src/lib.nr
  • examples/CRISP/circuits/src/main.nr
📚 Learning: 2025-08-27T13:49:48.617Z
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 648
File: examples/CRISP/circuits/src/main.nr:40-44
Timestamp: 2025-08-27T13:49:48.617Z
Learning: In CRISP circuits using Greco library, the binary check `assert(0 == b * (qmt - b))` for polynomial k1 should not be applied to all coefficients - only specific coefficients require this constraint, such as `k1.coefficients[2048 - 1]`.

Applied to files:

  • circuits/crates/libs/greco/src/lib.nr
📚 Learning: 2025-08-27T14:02:25.412Z
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 648
File: examples/CRISP/circuits/src/main.nr:40-44
Timestamp: 2025-08-27T14:02:25.412Z
Learning: In CRISP circuits using Greco library, k1 represents a binary value encoded as a polynomial where only one specific coefficient (k1.coefficients[2048 - 1]) carries the actual binary information and needs the constraint `assert(0 == b * (qmt - b))`. Other coefficients in the polynomial are not significant and don't require the binary constraint.

Applied to files:

  • examples/CRISP/circuits/src/main.nr
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: integration_prebuild
  • GitHub Check: build_sdk
  • GitHub Check: build_enclave_cli
  • GitHub Check: test_net
  • GitHub Check: test_contracts
  • GitHub Check: rust_integration
  • GitHub Check: rust_unit
  • GitHub Check: crisp_rust_unit
🔇 Additional comments (3)
examples/CRISP/circuits/src/main.nr (1)

35-38: Greco wiring for e0is/e0_quotients is consistent

The new e0_quotients: [Polynomial<512>; 2] parameter and the reordered e1 are threaded into Greco::new in the same order as the updated constructor signature (e0, e0is, e0_quotients, e1). For N=512, L=2 this wiring looks correct, and I don’t see any mismatches here.

Also applies to: 76-87

circuits/crates/libs/greco/src/lib.nr (2)

190-199: Struct and constructor changes for e0 CRT data are internally consistent

The Greco struct, constructor signature, and initializer all agree on the new ordering: e0, then e0is, then e0_quotients, then e1, followed by the existing randomness polynomials. Call sites (e.g. CRISP main) match this order, and types line up as [Polynomial<N>; L] as expected. I don’t see any wiring or type issues here.

Also applies to: 227-241, 243-259


215-222: check_e0_crt_consistency enforces the intended per‑coefficient CRT relation

The new method now checks, for every basis i and coefficient j, that

e0[j] == e0is[i][j] + e0_quotients[i][j] * qis[i]

via a direct assert inside the nested loops, which gives true coefficient‑wise CRT consistency instead of a weaker aggregated check. Integrating this as a pre‑challenge step in verify() matches the documented security goal and mirrors the earlier “per‑basis CRT correctness” style from the e1/e1is design. Based on learnings, this is the right shape for the CRT constraint.

Also applies to: 295-321, 347-359

@vercel vercel Bot temporarily deployed to Preview – enclave-docs December 2, 2025 14:10 Inactive
@vercel vercel Bot temporarily deployed to Preview – crisp December 2, 2025 14:10 Inactive
@cedoor cedoor enabled auto-merge (squash) December 2, 2025 15:04
@cedoor cedoor requested a review from YounesTal1 December 2, 2025 15:05
@cedoor cedoor merged commit 237746a into main Dec 2, 2025
24 checks passed
@github-actions github-actions Bot deleted the feat/greco-e0-e0is-check branch December 10, 2025 02:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

noir Task related to the noir fork or noir focussed code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Greco - Constraint e1 mod q == e1is[i] polynomials

4 participants