Skip to content

feat: add pk_commitment for greco#1083

Merged
0xjei merged 8 commits into
mainfrom
feat/greco-commit
Dec 11, 2025
Merged

feat: add pk_commitment for greco#1083
0xjei merged 8 commits into
mainfrom
feat/greco-commit

Conversation

@0xjei

@0xjei 0xjei commented Dec 5, 2025

Copy link
Copy Markdown
Contributor

This PR adds a pk_commitment to the Greco circuit.

PLEASE NOTE THAT: we are defaulting to dummy parameters branches in fhe.rs and zkfhe-generator. We need to understand what to do and how to progress before merging this.

cc @ryardley @cedoor @ctrlc03 @hmzakhalid

Summary by CodeRabbit

  • New Features

    • Added public key commitment validation to zero-knowledge circuits for enhanced security verification
    • Introduced configurable security parameter for error-size calculations in verification workflows
    • Extended circuit inputs to support commitment data handling
  • Chores

    • Updated verification key constants and data structures for contract deployment

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

@vercel

vercel Bot commented Dec 5, 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 11, 2025 4:14pm
enclave-docs Ready Ready Preview Comment Dec 11, 2025 4:14pm

@0xjei 0xjei linked an issue Dec 5, 2025 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Dec 5, 2025

Copy link
Copy Markdown
Contributor

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This PR adds public key commitment validation to the Greco protocol by introducing a pk_commitment field to the Greco struct, refactoring payload generation into separate gammas_payload and commitment_payload methods, and threading a bit-width parameter through helper functions. Verification keys are updated to reflect the new commitment scheme.

Changes

Cohort / File(s) Summary
Greco Circuit Core
circuits/crates/libs/greco/src/lib.nr
Added pk_commitment: Field to Greco struct and constructor. Renamed payload() to gammas_payload(). Introduced commitment_payload() helper. Updated generate_challenge() to use commitment_payload() for initial absorption and assert the result against pk_commitment.
Rust Helpers - Vectors & Client
crates/bfv-helpers/src/client.rs, crates/bfv-helpers/src/utils/greco.rs
Updated GrecoVectors::compute() signature to accept bit_pk: u64 parameter. Client now computes GrecoBounds and derives bit width before passing to vector computation.
Noir Example Circuit
examples/CRISP/circuits/src/main.nr
Added pk_commitment: Field parameter to main function and threaded it into Greco::new() constructor call.
Rust Example ZK Inputs
examples/CRISP/crates/zk-inputs/src/lib.rs, examples/CRISP/crates/zk-inputs/src/serialization.rs
Compute GrecoBounds and extract bit_pk for GrecoVectors call. Added pk_commitment: String field to ZKInputs struct and populate from vectors.
TypeScript SDK Types
examples/CRISP/packages/crisp-sdk/src/types.ts
Added pk_commitment: string field to CircuitInputs type definition.
Solidity Verifier
examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol
Updated VK_HASH constant and all G1Point coordinates in verification key data (no logic changes).
Test Integration
crates/tests/tests/integration.rs, crates/trbfv/tests/integration.rs, crates/trbfv/src/helpers.rs
Added lambda: usize parameter to calculate_error_size() function and propagated through test calls. Updated TrBFVConfig constructor to accept threshold_n and threshold_m as u64. Extended generate_shares_hash_map() signature to include cipher reference.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Noir circuit changes: Review the commitment validation logic in generate_challenge() and ensure payload methods are correctly renamed across all call sites.
  • Parameter propagation: Verify bit_pk flows correctly through client → helpers → vector computation pipeline.
  • Verification key constants: Confirm VK_HASH and G1Point values are correct and match expected proof scheme.
  • Test signature updates: Ensure lambda parameter usage in error-size calculation and new TrBFVConfig u64 casts are semantically sound.
  • Type consistency: Validate pk_commitment field propagates consistently from Noir circuits through serialization to TypeScript types.

Possibly related PRs

Suggested labels

noir

Suggested reviewers

  • zahrajavar
  • cedoor

Poem

🐰 A commitment most grand, now woven through code,
With payloads split clean—gammas and rows,
The Greco stands taller, pk-checked with care,
From circuits to solvers, the proof binds the air!

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 'feat: add pk_commitment for greco' accurately and concisely describes the main change—adding a pk_commitment field to the Greco struct across multiple files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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 force-pushed the feat/greco-commit branch from c9cced8 to 30e53e5 Compare December 5, 2025 17:43
@vercel vercel Bot temporarily deployed to Preview – crisp December 5, 2025 17:43 Inactive
@vercel vercel Bot temporarily deployed to Preview – enclave-docs December 5, 2025 17:43 Inactive
@0xjei

0xjei commented Dec 11, 2025

Copy link
Copy Markdown
Contributor Author

I am currently working on aligning fhe.rs gnosisguild/fhe.rs#58.

Since this might introduce some minor breaking change in generator / enclave, I am doing some tests before hand. I will expect this PR to be key to unlock all the errors we might have once we merge the PR above to the main branch of fhe.rs

ctrlc03
ctrlc03 previously approved these changes Dec 11, 2025
Comment thread circuits/crates/libs/greco/src/lib.nr 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: 0

🧹 Nitpick comments (2)
examples/CRISP/circuits/src/main.nr (1)

29-29: Consider making pk_commitment public.

The pk_commitment field has a TODO comment suggesting it should be public. Since this is a commitment value that likely needs to be verified externally, making it public would allow the verifier to check it.

Apply this diff if pk_commitment should be public for verification:

-    pk_commitment: Field, // todo: make this pub
+    pk_commitment: pub Field,

Alternatively, if this TODO is tracked elsewhere and will be addressed later, this can be deferred.

examples/CRISP/crates/zk-inputs/src/lib.rs (1)

94-112: Redundant GrecoBounds::compute call.

GrecoBounds::compute is called twice with identical arguments (lines 94 and 111). The first call extracts only bit_pk, discarding crypto_params, while the second call uses both return values. Consider computing bounds once and reusing the result.

-        let (_, bounds) = GrecoBounds::compute(&self.bfv_params, 0)?;
-
-        let bit_pk = shared::template::calculate_bit_width(&bounds.pk_bounds[0].to_string())?;
+        let (crypto_params, bounds) = GrecoBounds::compute(&self.bfv_params, 0)
+            .with_context(|| "Failed to compute bounds")?;
+
+        let bit_pk = shared::template::calculate_bit_width(&bounds.pk_bounds[0].to_string())?;

         // Compute the vectors of the GRECO inputs.
         let greco_vectors = GrecoVectors::compute(
             &pt,
             &u_rns,
             &e0_rns,
             &e1_rns,
             &ct,
             &pk,
             &self.bfv_params,
             bit_pk,
         )
         .with_context(|| "Failed to compute vectors")?;

-        let (crypto_params, bounds) = GrecoBounds::compute(&self.bfv_params, 0)
-            .with_context(|| "Failed to compute bounds")?;
+        // crypto_params and bounds already computed above
📜 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 c9b72d1 and 6ae1790.

⛔ Files ignored due to path filters (4)
  • Cargo.lock is excluded by !**/*.lock
  • examples/CRISP/Cargo.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • templates/default/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • circuits/crates/libs/greco/src/lib.nr (8 hunks)
  • crates/bfv-helpers/src/client.rs (3 hunks)
  • crates/bfv-helpers/src/utils/greco.rs (2 hunks)
  • crates/tests/tests/integration.rs (2 hunks)
  • crates/trbfv/src/helpers.rs (1 hunks)
  • crates/trbfv/tests/integration.rs (2 hunks)
  • examples/CRISP/circuits/src/main.nr (2 hunks)
  • examples/CRISP/crates/zk-inputs/src/lib.rs (1 hunks)
  • examples/CRISP/crates/zk-inputs/src/serialization.rs (5 hunks)
  • examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol (2 hunks)
  • examples/CRISP/packages/crisp-sdk/src/types.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2024-10-22T02:10:34.864Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:82-83
Timestamp: 2024-10-22T02:10:34.864Z
Learning: In the file `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, when reviewing test functions like `generate_pk_share`, minor performance optimizations (e.g., minimizing mutex locks) are not a priority.

Applied to files:

  • crates/tests/tests/integration.rs
  • crates/trbfv/tests/integration.rs
📚 Learning: 2024-10-23T02:03:02.008Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/encryption.rs:45-45
Timestamp: 2024-10-23T02:03:02.008Z
Learning: In the `packages/ciphernode/keyshare/src/encryption.rs` file, the environment variable `CIPHERNODE_SECRET` is used for the encryption password. A secure secret management solution is not currently available, but may be considered in future iterations.

Applied to files:

  • crates/tests/tests/integration.rs
  • crates/trbfv/tests/integration.rs
📚 Learning: 2024-10-23T01:59:42.967Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:274-274
Timestamp: 2024-10-23T01:59:42.967Z
Learning: In the `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs` file and other test files within this project, hardcoding `CIPHERNODE_SECRET` is acceptable for testing purposes.

Applied to files:

  • crates/tests/tests/integration.rs
  • crates/trbfv/tests/integration.rs
📚 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:

  • examples/CRISP/crates/zk-inputs/src/lib.rs
  • circuits/crates/libs/greco/src/lib.nr
  • crates/bfv-helpers/src/client.rs
  • crates/bfv-helpers/src/utils/greco.rs
  • examples/CRISP/circuits/src/main.nr
📚 Learning: 2024-10-08T19:45:18.209Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 107
File: packages/ciphernode/sortition/src/distance.rs:1-1
Timestamp: 2024-10-08T19:45:18.209Z
Learning: In `packages/ciphernode/core/src/events.rs`, the import statements use the correct and updated `alloy::primitives` module.

Applied to files:

  • crates/bfv-helpers/src/client.rs
📚 Learning: 2025-11-08T01:31:47.505Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.

Applied to files:

  • crates/trbfv/tests/integration.rs
📚 Learning: 2025-05-07T15:18:20.056Z
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 388
File: packages/commons/src/bfv/mod.rs:38-48
Timestamp: 2025-05-07T15:18:20.056Z
Learning: The `build_bfv_params` and related functions in the commons BFV utilities intentionally use panic for error handling as a temporary solution. The team plans to refactor these to use proper Result-based error handling in the future.

Applied to files:

  • crates/trbfv/tests/integration.rs
🧬 Code graph analysis (3)
crates/tests/tests/integration.rs (1)
crates/trbfv/src/helpers.rs (1)
  • calculate_error_size (47-56)
crates/trbfv/src/helpers.rs (1)
crates/trbfv/src/trbfv_config.rs (1)
  • params (34-36)
crates/trbfv/tests/integration.rs (3)
crates/test-helpers/src/lib.rs (2)
  • create_seed_from_u64 (40-42)
  • new (168-174)
crates/crypto/src/cipher.rs (1)
  • from_password (123-125)
crates/trbfv/src/helpers.rs (1)
  • calculate_error_size (47-56)
⏰ 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). (5)
  • GitHub Check: crisp_unit
  • GitHub Check: build_e3_support_dev
  • GitHub Check: build_sdk
  • GitHub Check: build_ciphernode_image
  • GitHub Check: test_contracts
🔇 Additional comments (21)
crates/trbfv/src/helpers.rs (1)

47-56: LGTM! Breaking API change for security parameter.

The addition of the lambda parameter (security parameter for smudging bound calculation) is well-documented and properly threaded through to SmudgingBoundCalculatorConfig::new. The change is intentional per the PR objectives.

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

134-134: LGTM! Consistent type addition.

The pk_commitment: string field is correctly added to the CircuitInputs type in the Greco section, aligning with the serialization and circuit changes.

examples/CRISP/crates/zk-inputs/src/serialization.rs (5)

42-42: LGTM! Field addition to ZKInputs.

The pk_commitment: String field is correctly added to the ZKInputs struct.


259-259: LGTM! Field population.

The pk_commitment field is correctly populated by converting vectors_standard.pk_commitment to a string, following the same pattern as other fields.


344-353: LGTM! Test data updated with pk_commitment.

The mock test data correctly includes pk_commitment: BigInt::from(45) in the GrecoVectors struct, aligning with the serialization changes.


397-397: LGTM! Test assertion for pk_commitment.

The test correctly verifies that pk_commitment is populated by checking its length is greater than 0.


436-436: LGTM! Test assertion for JSON serialization.

The test correctly verifies that the pk_commitment field is present in the serialized JSON output.

crates/tests/tests/integration.rs (2)

150-154: LGTM! Insecure test parameter clearly documented.

The warning comment clearly states that lambda = 2 is an INSECURE parameter for testing purposes only. Production use requires lambda = 80 for adequate security.


157-162: LGTM! Lambda parameter correctly threaded.

The lambda parameter is correctly passed to calculate_error_size, aligning with the updated function signature in crates/trbfv/src/helpers.rs.

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

77-94: LGTM! pk_commitment correctly threaded to Greco::new.

The pk_commitment parameter is correctly passed to the Greco::new constructor as the first argument after params, aligning with the updated Greco implementation.

crates/bfv-helpers/src/utils/greco.rs (1)

224-231: LGTM! Test helper correctly updated for bit width parameter.

The test setup properly computes Greco bounds, derives the bit width, and passes it to GrecoVectors::compute. The pattern of passing 0 as the second parameter to GrecoBounds::compute is consistent across all production usages in client.rs and example code, confirming it is the intended value.

examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol (1)

11-129: Verification keys updated for circuit changes.

The VK_HASH and G1Point coordinates have been regenerated to reflect the circuit modifications, including the addition of pk_commitment to the Greco section. These values are circuit-specific artifacts derived from the compiled Noir circuit and must match the updated circuit structure. The changes appear correct based on the circuit dependencies and structure.

crates/bfv-helpers/src/client.rs (1)

107-121: LGTM! Bit width derivation for pk bounds is correct.

The code properly computes Greco bounds and derives the bit width from bounds.pk_bounds[0], following the established pattern across the codebase. Error handling is properly maintained. The first return value from GrecoBounds::compute is intentionally discarded since GrecoVectors::compute requires only the bounds, not the cryptographic parameters.

crates/trbfv/tests/integration.rs (3)

64-77: Security warning comment is appropriate; lambda=2 is suitable for tests only.

The explicit warning about the insecure lambda parameter is well documented. The comment correctly notes that production should use lambda=80. This approach aligns with standard practice of using reduced security parameters to speed up test execution.


71-79: LGTM!

The Cipher::from_password usage with a hardcoded password is acceptable for test purposes. The TrBFVConfig::new call correctly casts threshold parameters to u64, and calculate_error_size properly includes the new lambda parameter matching the updated function signature.


86-93: LGTM!

The generate_shares_hash_map call correctly passes esi_per_ct as u64 and includes the new cipher parameter, aligning with the updated function signature.

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

183-201: LGTM! pk_commitment field addition is well integrated.

The pk_commitment: Field field is correctly added to the Greco struct, and the documentation at line 175 appropriately describes its purpose as a public key commitment.


229-265: LGTM!

The constructor correctly accepts pk_commitment as a parameter and initializes the field. The parameter ordering (after params) and documentation are consistent.


276-298: LGTM!

The gammas_payload function correctly includes pk_commitment as the first element in the payload before flattening ciphertext polynomials. This ensures the Fiat-Shamir challenge is bound to the public key commitment, maintaining the cryptographic integrity of the proof.


300-315: LGTM!

The commitment_payload function correctly serializes pk0is and pk1is using the BIT_PK bit-width parameter, consistent with the range checks applied to these polynomials in check_range_bounds. The documentation clearly describes its purpose.


440-473: Commitment verification logic is correctly implemented.

The generate_challenge function now performs two-phase sponge operations:

  1. First sponge absorbs public key polynomials via commitment_payload() and verifies the squeezed commitment matches pk_commitment (line 460)
  2. Second sponge generates gammas from gammas_payload() for the Schwartz-Zippel polynomial identity testing

This ensures the prover is bound to the committed public key, preventing substitution attacks.

ctrlc03
ctrlc03 previously approved these changes Dec 11, 2025
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.

Update circuits to compute on-chain pk commitment hash

2 participants