Skip to content

Abort extracting vk when there are no phase 2 contributions#620

Open
StefanosChaliasos wants to merge 2 commits intoiden3:masterfrom
StefanosChaliasos:master
Open

Abort extracting vk when there are no phase 2 contributions#620
StefanosChaliasos wants to merge 2 commits intoiden3:masterfrom
StefanosChaliasos:master

Conversation

@StefanosChaliasos
Copy link
Copy Markdown

@StefanosChaliasos StefanosChaliasos commented Feb 26, 2026

Following recent exploits in which users didn't contribute in phase 2 before extracting their verification key, I suggest adding a check and printing an error message in such cases.

Context:

https://x.com/PashovAuditGrp/status/2025598503255167195?s=20
https://x.com/blockaid_/status/2026937160079970737
https://blog.zksecurity.xyz/posts/groth16-setup-exploit/

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a soundness guard to prevent exporting/using Groth16 verification keys when the zkey appears to have no Phase 2 contribution (heuristic: vk_gamma_2 === vk_delta_2), addressing a known setup exploit class.

Changes:

  • Abort Groth16 VK export if vk_gamma_2 equals vk_delta_2.
  • Add the same guard to Solidity verifier export.
  • Make Groth16 verification return false (with an error log) when the VK is detected as insecure.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/zkey_export_verificationkey.js Adds a hard failure during Groth16 VK export when vk_gamma_2 === vk_delta_2.
src/zkey_export_solidityverifier.js Adds a Groth16 VK sanity check before rendering the Solidity verifier.
src/groth16_verify.js Rejects verification keys with vk_gamma_2 === vk_delta_2 during Groth16 verification.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/groth16_verify.js
Comment on lines +72 to +75
if (curve.G2.eq(vk_gamma_2, vk_delta_2)) {
if (logger) logger.error("SOUNDNESS ERROR: vk_gamma_2 and vk_delta_2 are equal. This verification key is insecure, the zkey likely has no phase 2 contribution. Proofs can be forged. Aborting verification.");
return false;
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New behavior returns false when vk_gamma_2 equals vk_delta_2, but there doesn’t appear to be a test exercising this soundness guard. Adding a unit/integration test that verifies groth16.verify rejects an insecure verification key (e.g., by crafting a VK with vk_delta_2 copied from vk_gamma_2, or by exporting from an un-contributed zkey if that produces equality) would prevent regressions.

Copilot uses AI. Check for mistakes.
Comment on lines +59 to +61
if (curve.G2.eq(zkey.vk_gamma_2, zkey.vk_delta_2)) {
throw new Error("SOUNDNESS ERROR: vk_gamma_2 and vk_delta_2 are equal. This zkey is insecure, it likely has no phase 2 contribution. Proofs can be forged. Run 'snarkjs zkey contribute' before exporting.");
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing here will skip the fd.close() in zkeyExportVerificationKey (it’s only reached on the success path), which can leak the underlying file handle when exporting a Groth16 VK from an insecure zkey. Consider wrapping the readBinFile/protocol switch in a try/finally so the descriptor is always closed, even when groth16Vk throws.

Copilot uses AI. Check for mistakes.
Comment thread src/zkey_export_solidityverifier.js Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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.

3 participants