Skip to content

refactor: update crisp vk hashes#1506

Merged
cedoor merged 1 commit into
mainfrom
refactor/crisp-vk-hash-3
Apr 3, 2026
Merged

refactor: update crisp vk hashes#1506
cedoor merged 1 commit into
mainfrom
refactor/crisp-vk-hash-3

Conversation

@cedoor

@cedoor cedoor commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • Bug Fixes

    • Field element witness output now canonicalized to non-negative values; avoids negative numeric/string emissions and adds a unit test to enforce this.
  • New Features

    • Fold verification now accepts either of two expected key-hash values to allow flexible verification paths.
  • Updates

    • Updated CRISP HONK verification key constants.
  • Chores

    • Public API signatures unchanged.

@cedoor cedoor requested review from 0xjei and ctrlc03 April 2, 2026 14:05
@cedoor cedoor linked an issue Apr 2, 2026 that may be closed by this pull request
@vercel

vercel Bot commented Apr 2, 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 Apr 3, 2026 9:01am
enclave-docs Ready Ready Preview, Comment Apr 3, 2026 9:01am

Request Review

@coderabbitai

coderabbitai Bot commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 419263ec-8c57-49a7-812f-48c5423838d0

📥 Commits

Reviewing files that changed from the base of the PR and between 045cb11 and bdfba25.

📒 Files selected for processing (3)
  • crates/zk-helpers/src/utils.rs
  • examples/CRISP/circuits/bin/fold/src/main.nr
  • examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol
🚧 Files skipped from review as they are similar to previous changes (3)
  • examples/CRISP/circuits/bin/fold/src/main.nr
  • crates/zk-helpers/src/utils.rs
  • examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol

📝 Walkthrough

Walkthrough

Canonicalizes BigInt JSON output to BN254 field representatives for Noir witnesses; replaces a single fold expected key-hash with insecure/secure constants and OR-based check in the Noir circuit; updates the CRISP Solidity verifier VK_HASH and many G1Point coordinate literals.

Changes

Cohort / File(s) Summary
BigInt JSON Serialization
crates/zk-helpers/src/utils.rs
bigint_to_json_value now reduces inputs via bigint_to_field, builds the canonical non-negative representative in [0, p), and serializes that value (JSON number if fits i64, otherwise decimal string). Fallback stringification uses the canonical value. Added unit test preventing negative JSON output.
Noir verification constants
examples/CRISP/circuits/bin/fold/src/main.nr
Removed single CRISP_FOLD_EXPECTED_KEY_HASH; added CRISP_FOLD_EXPECTED_KEY_HASH_INSECURE and CRISP_FOLD_EXPECTED_KEY_HASH_SECURE. VK-hash check computes chain_key_hash and asserts equality against either constant (logical OR) instead of a single equality.
Solidity verification keys
examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol
Updated VK_HASH constant and replaced many hardcoded Honk.G1Point coordinate literals for verification-key fields (ql, qr, qo, q4, qm, qc, qArith, qDeltaRange, qElliptic, qMemory, qNnf, qPoseidon2External, qPoseidon2Internal, s1s4, id1id4, lagrangeLast) with new numeric values; verification logic unchanged.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

noir

Suggested reviewers

  • 0xjei
  • ctrlc03

Poem

🐰 I hop through fields and tidy signs,

No minus shadows in my lines.
Two keys now guard the folding gate,
Solidity sings the new VK fate.
A joyful hop — the proofs look great!

🚥 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 'refactor: update crisp vk hashes' directly and accurately describes the main changes across all modified files: updating VK hash constants and related logic in CRISP components.
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
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/crisp-vk-hash-3

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

🧹 Nitpick comments (1)
crates/zk-helpers/src/utils.rs (1)

309-319: Consider adding edge-case coverage.

The test correctly verifies the no-negative invariant, but could be strengthened with additional boundary cases:

💡 Optional: Add edge cases for more robust coverage
 #[test]
 fn bigint_to_json_value_never_emits_negative_for_field_witness() {
-    let neg = BigInt::from(-13449214110323435_i64);
-    let v = bigint_to_json_value(&neg);
-    let as_text = match v {
+    let test_cases = vec![
+        BigInt::from(-1),
+        BigInt::from(-13449214110323435_i64),
+        -get_zkp_modulus() + BigInt::from(1), // near modulus boundary
+    ];
+    for neg in test_cases {
+        let v = bigint_to_json_value(&neg);
+        let as_text = match v {
-        serde_json::Value::Number(n) => n.to_string(),
-        serde_json::Value::String(s) => s,
-        _ => panic!("expected number or string"),
-    };
-    assert!(!as_text.starts_with('-'));
+            serde_json::Value::Number(n) => n.to_string(),
+            serde_json::Value::String(s) => s,
+            _ => panic!("expected number or string"),
+        };
+        assert!(!as_text.starts_with('-'), "negative output for input: {}", neg);
+    }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/zk-helpers/src/utils.rs` around lines 309 - 319, The test
bigint_to_json_value_never_emits_negative_for_field_witness should be extended
to cover edge cases: add assertions for BigInt values 0 and -1, a small negative
(e.g., -123), a very large negative number beyond i64 (construct via string to
test arbitrary precision), and a large positive value to ensure formatting stays
non-negative; use the same extraction logic (match on
serde_json::Value::Number/String) and assert the resulting string does not start
with '-' for all these BigInt inputs when calling bigint_to_json_value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@examples/CRISP/circuits/bin/fold/src/main.nr`:
- Around line 71-75: The current OR-based assertion in main.nr (compute_vk_hash
-> chain_key_hash compared against CRISP_FOLD_EXPECTED_KEY_HASH_INSECURE |
CRISP_FOLD_EXPECTED_KEY_HASH_SECURE) allows insecure keys to be accepted; change
this to enforce a single expected hash selected at build/deploy time: introduce
a compile-time or configuration-driven selector (e.g., a feature flag or
lib::configs::default) that resolves to either
CRISP_FOLD_EXPECTED_KEY_HASH_SECURE or the insecure constant, and replace the OR
assertion with a strict equality check (chain_key_hash ==
SELECTED_EXPECTED_KEY_HASH) in the compute_vk_hash/assert block so production
builds use the secure-only hash by default.

---

Nitpick comments:
In `@crates/zk-helpers/src/utils.rs`:
- Around line 309-319: The test
bigint_to_json_value_never_emits_negative_for_field_witness should be extended
to cover edge cases: add assertions for BigInt values 0 and -1, a small negative
(e.g., -123), a very large negative number beyond i64 (construct via string to
test arbitrary precision), and a large positive value to ensure formatting stays
non-negative; use the same extraction logic (match on
serde_json::Value::Number/String) and assert the resulting string does not start
with '-' for all these BigInt inputs when calling bigint_to_json_value.
🪄 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: 65d31f58-05cf-43fb-84b9-97a7496adb2a

📥 Commits

Reviewing files that changed from the base of the PR and between b5b9601 and 793237e.

📒 Files selected for processing (3)
  • crates/zk-helpers/src/utils.rs
  • examples/CRISP/circuits/bin/fold/src/main.nr
  • examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol

Comment thread examples/CRISP/circuits/bin/fold/src/main.nr
@cedoor cedoor enabled auto-merge (squash) April 2, 2026 15:23

@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

@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

🧹 Nitpick comments (1)
crates/zk-helpers/src/utils.rs (1)

309-319: Test validates the key invariant correctly.

The test appropriately verifies that negative inputs produce non-negative JSON output.

Consider adding a few more edge cases for completeness (optional):

🧪 Suggested additional test cases
     #[test]
     fn bigint_to_json_value_never_emits_negative_for_field_witness() {
-        let neg = BigInt::from(-13449214110323435_i64);
-        let v = bigint_to_json_value(&neg);
-        let as_text = match v {
+        let test_cases = vec![
+            BigInt::from(-1),
+            BigInt::from(-13449214110323435_i64),
+            -get_zkp_modulus() + BigInt::from(1), // near -p
+        ];
+        for neg in test_cases {
+            let v = bigint_to_json_value(&neg);
+            let as_text = match v {
-            serde_json::Value::Number(n) => n.to_string(),
-            serde_json::Value::String(s) => s,
-            _ => panic!("expected number or string"),
-        };
-        assert!(!as_text.starts_with('-'));
+                serde_json::Value::Number(n) => n.to_string(),
+                serde_json::Value::String(s) => s,
+                _ => panic!("expected number or string"),
+            };
+            assert!(!as_text.starts_with('-'), "negative output for {:?}", neg);
+        }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/zk-helpers/src/utils.rs` around lines 309 - 319, Add additional
edge-case tests for bigint_to_json_value to strengthen coverage: include BigInt
values such as zero (0), -1, the smallest/ largest values you expect (e.g.,
i64::MIN and i64::MAX or equivalent BigInt extremes used in your codebase), and
a very large magnitude negative and positive BigInt to ensure the output never
starts with '-' and is represented as expected; add these as new #[test]
functions (or table-driven cases) alongside
bigint_to_json_value_never_emits_negative_for_field_witness so failures
reference bigint_to_json_value directly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol`:
- Line 11: VK_HASH in CRISPVerifier.sol (symbol VK_HASH) doesn't match the two
allowed fold-circuit constants (CRISP_FOLD_EXPECTED_KEY_HASH_INSECURE /
CRISP_FOLD_EXPECTED_KEY_HASH_SECURE) and so verify() will feed an unexpected
$VK_HASH into the Fiat–Shamir transcript causing the fold circuit's
chain_key_hash assertion to fail; fix by either regenerating the fold circuit
constants (CRISP_FOLD_EXPECTED_KEY_HASH_INSECURE and
CRISP_FOLD_EXPECTED_KEY_HASH_SECURE in
examples/CRISP/circuits/bin/fold/src/main.nr) from the same build/artifact that
produced this verifier so they match VK_HASH, or revert VK_HASH to one of the
permitted hashes the fold circuit currently accepts, and ensure verify()'s
VK_HASH and the fold circuit's chain_key_hash assertion use the identical
artifact-derived value.

---

Nitpick comments:
In `@crates/zk-helpers/src/utils.rs`:
- Around line 309-319: Add additional edge-case tests for bigint_to_json_value
to strengthen coverage: include BigInt values such as zero (0), -1, the
smallest/ largest values you expect (e.g., i64::MIN and i64::MAX or equivalent
BigInt extremes used in your codebase), and a very large magnitude negative and
positive BigInt to ensure the output never starts with '-' and is represented as
expected; add these as new #[test] functions (or table-driven cases) alongside
bigint_to_json_value_never_emits_negative_for_field_witness so failures
reference bigint_to_json_value directly.
🪄 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: 7dafdaed-5bf1-434b-9045-132ac6fcf1ec

📥 Commits

Reviewing files that changed from the base of the PR and between 793237e and 045cb11.

📒 Files selected for processing (3)
  • crates/zk-helpers/src/utils.rs
  • examples/CRISP/circuits/bin/fold/src/main.nr
  • examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/CRISP/circuits/bin/fold/src/main.nr

Comment thread examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol
@cedoor cedoor force-pushed the refactor/crisp-vk-hash-3 branch from 045cb11 to bdfba25 Compare April 3, 2026 08:59
@cedoor cedoor merged commit 7d4489d into main Apr 3, 2026
33 checks passed
@github-actions github-actions Bot deleted the refactor/crisp-vk-hash-3 branch April 11, 2026 03:17
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.

Compute hardcoded vk hashes for circuits with secure parameters

2 participants