Skip to content

chore: use different signature per round#1094

Merged
ctrlc03 merged 2 commits into
mainfrom
chore/change-signature
Dec 10, 2025
Merged

chore: use different signature per round#1094
ctrlc03 merged 2 commits into
mainfrom
chore/change-signature

Conversation

@ctrlc03

@ctrlc03 ctrlc03 commented Dec 9, 2025

Copy link
Copy Markdown
Collaborator

fix #1090

Summary by CodeRabbit

  • Updates
    • Improved message handling in voting proof generation workflows
    • Enhanced signature processing for voting operations
    • Better integration of voting round parameters in the voting process
    • Refined proof verification with enhanced message authentication mechanisms

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

@ctrlc03 ctrlc03 requested a review from hmzakhalid December 9, 2025 09:29
@vercel

vercel Bot commented Dec 9, 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 10, 2025 4:47pm
1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
enclave-docs Skipped Skipped Dec 10, 2025 4:47pm

@coderabbitai

coderabbitai Bot commented Dec 9, 2025

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@ctrlc03 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 3 minutes and 5 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.

📥 Commits

Reviewing files that changed from the base of the PR and between a06265d and c0479b3.

📒 Files selected for processing (10)
  • examples/CRISP/client/libs/crispWorker.js (2 hunks)
  • examples/CRISP/client/src/context/voteManagement/VoteManagement.types.ts (1 hunks)
  • examples/CRISP/client/src/hooks/voting/useVoteCasting.ts (5 hunks)
  • examples/CRISP/client/src/hooks/wasm/useWebAssembly.tsx (2 hunks)
  • examples/CRISP/packages/crisp-contracts/tests/crisp.contracts.test.ts (5 hunks)
  • examples/CRISP/packages/crisp-sdk/src/index.ts (1 hunks)
  • examples/CRISP/packages/crisp-sdk/src/types.ts (2 hunks)
  • examples/CRISP/packages/crisp-sdk/src/utils.ts (2 hunks)
  • examples/CRISP/packages/crisp-sdk/src/vote.ts (2 hunks)
  • examples/CRISP/packages/crisp-sdk/tests/vote.test.ts (1 hunks)

Walkthrough

The PR introduces support for per-round message hashes throughout the CRISP voting system. Each voting round now uses a unique message hash (computed from the round ID) instead of a constant signature message, preventing signature re-use across different voting rounds. The messageHash parameter is threaded from the UI through voting hooks, down to SDK utilities and worker processes.

Changes

Cohort / File(s) Summary
Type Definitions
examples/CRISP/client/src/context/voteManagement/VoteManagement.types.ts, examples/CRISP/packages/crisp-sdk/src/types.ts
Added messageHash: 0x${string} parameter to generateProof method signature and to ProofInputs / VoteProofInputs types.
Signing & Message Hashing
examples/CRISP/client/src/hooks/voting/useVoteCasting.ts
Replaced static SIGNATURE_MESSAGE import with dynamic message computation ("Vote for round {roundId}"). Added hashMessage from viem, updated signing flow to compute and pass messageHash through proof generation chain. Added customVotingRound parameter to hook.
WASM/Worker Integration
examples/CRISP/client/src/hooks/wasm/useWebAssembly.tsx, examples/CRISP/client/libs/crispWorker.js
Updated generateProof signature and worker message payload to include messageHash parameter passed to generateVoteProof.
SDK Utilities & Vote Proof
examples/CRISP/packages/crisp-sdk/src/utils.ts, examples/CRISP/packages/crisp-sdk/src/vote.ts
Updated extractSignatureComponents and getAddressFromSignature to accept optional/required messageHash parameter (defaulting to SIGNATURE_MESSAGE_HASH). Threaded messageHash through signature component extraction and address derivation in proof generation.
Tests
examples/CRISP/packages/crisp-sdk/tests/vote.test.ts
Updated test call to generateVoteProof to include messageHash in input payload.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Hook as useVoteCasting
    participant Sign as Signing
    participant Proof as Proof Generation
    participant Worker as crispWorker
    participant SDK as CRISP SDK

    User->>Hook: Cast vote with votingRound
    activate Hook
    Note over Hook: Compute message from round ID
    Hook->>Hook: message = "Vote for round {roundId}"
    Hook->>Hook: messageHash = hashMessage(message)
    
    Hook->>Sign: signMessageAsync({ message })
    activate Sign
    Sign-->>Hook: signature
    deactivate Sign
    
    Note over Hook: Extract vote data
    Hook->>Proof: handleProofGeneration(vote, address, signature, messageHash)
    activate Proof
    
    Proof->>Worker: postMessage({ voteId, publicKey, address, signature, messageHash, previousCiphertext })
    activate Worker
    
    Worker->>SDK: generateVoteProof({ vote, publicKey, signature, merkleLeaves, balance, messageHash, previousCiphertext })
    activate SDK
    Note over SDK: Use messageHash for<br/>signature component extraction
    SDK->>SDK: extractSignatureComponents(signature, messageHash)
    Note over SDK: Use messageHash for<br/>address derivation
    SDK->>SDK: getAddressFromSignature(signature, messageHash)
    SDK-->>Worker: proof
    deactivate SDK
    
    Worker-->>Proof: proof result
    deactivate Worker
    Proof-->>Hook: encoded proof
    deactivate Proof
    
    Hook-->>User: Proof generated & submitted
    deactivate Hook
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

  • useVoteCasting.ts: Verify new signing flow, message computation from round ID, and messageHash threading through callbacks. Ensure votingRound dependency addition doesn't cause unintended re-renders or side effects.
  • Signature utilities (utils.ts, vote.ts): Confirm messageHash parameter propagation maintains backward compatibility with default SIGNATURE_MESSAGE_HASH and verify correctness of signature component extraction and address derivation logic.
  • Type consistency: Ensure all call sites are updated to match the new generateProof signature across hooks, worker, and SDK layers.

Possibly related PRs

Suggested reviewers

  • cedoor

🐰 A round-specific hash, hooray!
No more signatures led astray,
Each vote now hides its own way,
Safe from reuse, come what may,
CRISP security saves the day! 🗳️✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: use different signature per round' is partially related to the changeset and accurately describes the main objective of accepting a per-round message hash to prevent signature reuse.
Linked Issues check ✅ Passed All code changes comprehensively implement the requirement to accept and propagate messageHash through generateVoteProof, worker processes, and hook implementations to enable per-round signatures.
Out of Scope Changes check ✅ Passed All changes are directly scoped to accepting and threading messageHash through the CRISP voting pipeline, with no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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.

@ctrlc03 ctrlc03 force-pushed the chore/change-signature branch from f7646e8 to a06265d Compare December 9, 2025 09:30
@vercel vercel Bot temporarily deployed to Preview – crisp December 9, 2025 09:30 Inactive
@vercel vercel Bot temporarily deployed to Preview – enclave-docs December 9, 2025 09:30 Inactive

@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)
examples/CRISP/packages/crisp-sdk/tests/vote.test.ts (1)

238-254: LGTM! Test correctly updated to include messageHash.

The test properly provides SIGNATURE_MESSAGE_HASH which matches the message used for signing.

Consider adding a negative test case that verifies proof generation fails when messageHash doesn't match the signed message - this would validate the replay protection works correctly.

📜 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 9c5407f and a06265d.

📒 Files selected for processing (8)
  • examples/CRISP/client/libs/crispWorker.js (2 hunks)
  • examples/CRISP/client/src/context/voteManagement/VoteManagement.types.ts (1 hunks)
  • examples/CRISP/client/src/hooks/voting/useVoteCasting.ts (5 hunks)
  • examples/CRISP/client/src/hooks/wasm/useWebAssembly.tsx (2 hunks)
  • examples/CRISP/packages/crisp-sdk/src/types.ts (2 hunks)
  • examples/CRISP/packages/crisp-sdk/src/utils.ts (2 hunks)
  • examples/CRISP/packages/crisp-sdk/src/vote.ts (2 hunks)
  • examples/CRISP/packages/crisp-sdk/tests/vote.test.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
examples/CRISP/packages/crisp-sdk/tests/vote.test.ts (1)
examples/CRISP/packages/crisp-sdk/src/constants.ts (1)
  • SIGNATURE_MESSAGE_HASH (31-31)
examples/CRISP/packages/crisp-sdk/src/vote.ts (1)
examples/CRISP/packages/crisp-sdk/src/utils.ts (2)
  • extractSignatureComponents (89-118)
  • getAddressFromSignature (120-124)
examples/CRISP/client/src/hooks/voting/useVoteCasting.ts (1)
packages/enclave-sdk/src/greco.ts (1)
  • generateProof (122-159)
⏰ 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: rust_integration
  • GitHub Check: rust_unit
  • GitHub Check: build_enclave_cli
  • GitHub Check: test_net
  • GitHub Check: test_contracts
  • GitHub Check: crisp_unit
  • GitHub Check: build_sdk
🔇 Additional comments (14)
examples/CRISP/packages/crisp-sdk/src/vote.ts (3)

106-109: LGTM! Correctly propagates messageHash for signature extraction.

The changes properly thread the messageHash from proofInputs to extractSignatureComponents, enabling per-round signature verification.


157-157: LGTM! Address derivation now uses the provided messageHash.

This ensures the recovered address matches the signer of the round-specific message.


170-181: Verify: generateMaskVoteProof uses default messageHash (constant).

generateMaskVoteProof doesn't pass a messageHash to generateCircuitInputs, so it will fall back to SIGNATURE_MESSAGE_HASH. If mask votes should also use per-round hashes, this needs updating. If mask votes intentionally use a constant signature (since MASK_SIGNATURE is used), this is correct.

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

179-179: LGTM! Optional messageHash in ProofInputs allows fallback to default.

This is appropriate for internal use where extractSignatureComponents has a default value.


197-197: LGTM! Required messageHash in VoteProofInputs enforces per-round uniqueness.

Making this required at the public API level ensures callers must provide a round-specific hash, addressing the replay protection goal from issue #1090.

examples/CRISP/client/src/hooks/wasm/useWebAssembly.tsx (1)

26-41: LGTM! Worker communication properly includes messageHash.

The messageHash parameter is correctly added to the function signature and forwarded to the worker via postMessage.

examples/CRISP/client/libs/crispWorker.js (1)

14-36: LGTM! Worker correctly propagates messageHash to proof generation.

The destructuring and forwarding to generateVoteProof is correct and aligns with the SDK's updated API.

examples/CRISP/client/src/context/voteManagement/VoteManagement.types.ts (1)

40-47: LGTM! Context type correctly updated with messageHash parameter.

The signature matches the implementation in useWebAssembly.tsx.

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

89-117: LGTM! Signature extraction correctly parameterized with messageHash.

The default value maintains backward compatibility while enabling per-round hash usage.

examples/CRISP/client/src/hooks/voting/useVoteCasting.ts (5)

9-9: LGTM! Correct import of hashMessage from viem.


70-76: LGTM! Proof generation callback correctly updated with messageHash.

The callback signature and forwarding to generateProof are consistent with the updated types.


111-116: Core fix for issue #1090: Per-round message signing.

The message "Vote for round ${roundState.id}" ensures each round uses a unique signature, preventing replay attacks. The hashMessage and signMessageAsync correctly use the same message content.


133-133: LGTM! messageHash correctly passed through proof generation flow.


220-220: LGTM! votingRound added to dependency array.

This ensures castVoteWithProof is recreated when the voting round changes, which is necessary since it's used in handleProofGeneration.

Comment thread examples/CRISP/packages/crisp-sdk/src/utils.ts
@vercel vercel Bot temporarily deployed to Preview – crisp December 9, 2025 09:47 Inactive
@vercel vercel Bot temporarily deployed to Preview – enclave-docs December 9, 2025 09:47 Inactive

@0xjei 0xjei 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.

utACK

@ctrlc03 ctrlc03 force-pushed the chore/change-signature branch from c9df76a to ccca242 Compare December 10, 2025 14:58
@vercel vercel Bot temporarily deployed to Preview – enclave-docs December 10, 2025 14:58 Inactive
@ctrlc03 ctrlc03 enabled auto-merge (squash) December 10, 2025 15:01
@ctrlc03 ctrlc03 force-pushed the chore/change-signature branch from ccca242 to f9bc042 Compare December 10, 2025 15:34
@vercel vercel Bot temporarily deployed to Preview – enclave-docs December 10, 2025 15:34 Inactive
@vercel vercel Bot temporarily deployed to Preview – crisp December 10, 2025 15:34 Inactive
@ctrlc03 ctrlc03 disabled auto-merge December 10, 2025 15:41
@ctrlc03 ctrlc03 force-pushed the chore/change-signature branch from f9bc042 to c0479b3 Compare December 10, 2025 16:45
@ctrlc03 ctrlc03 enabled auto-merge (squash) December 10, 2025 16:45
@vercel vercel Bot temporarily deployed to Preview – enclave-docs December 10, 2025 16:45 Inactive
@ctrlc03 ctrlc03 merged commit 71a1e0b into main Dec 10, 2025
23 of 24 checks passed
@github-actions github-actions Bot deleted the chore/change-signature branch December 18, 2025 02:51
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.

CRISP SDK generateVoteProof should accept the message hash too to prevent re-usal of signatures across rounds

2 participants