Every CVE Search/ Get API key

CVE-2024-45039

gnark's Groth16 commitment extension unsound for more than one commitment

6.2 MediumFix available

gnark is a fast zk-SNARK library that offers a high-level API to design circuits. Versions prior to 0.11.0 have a soundness issue - in case of multiple commitments used inside the circuit the prover is able to choose all but the last commitment. As gnark uses the commitments for optimized non-native multiplication, lookup checks etc. as random challenges, then it could impact the soundness of the whole circuit. However, using multiple commitments has been discouraged due to the additional cost to the verifier and it has not been supported in the recursive in-circuit Groth16 verifier and Solidity verifier. gnark's maintainers expect the impact of the issue be very small - only for the users who have implemented the native Groth16 verifier or are using it with multiple commitments. We do not have information of such users. The issue has been patched in version 0.11.0. As a workaround, users should follow gnark maintainers' recommendation to use only a single commitment and then derive in-circuit commitments as needed using the std/multicommit package.

Attack profile

How easy it is to exploit

Attack vector
Local
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
High
Availability
None

Exploit likelihood

0.19%Up 0.1 points since Sep 7, 2024
90%50%10%1%

What each source reports

CVE List Score used 6.2

gnark's Groth16 commitment extension unsound for more than one commitment

gnark is a fast zk-SNARK library that offers a high-level API to design circuits. Versions prior to 0.11.0 have a soundness issue - in case of multiple commitments used inside the circuit the prover is able to choose all but the last commitment. As gnark uses the commitments for optimized non-native multiplication, lookup checks etc. as random challenges, then it could impact the soundness of the whole circuit. However, using multiple commitments has been discouraged due to the additional cost to the verifier and it has not been supported in the recursive in-circuit Groth16 verifier and Solidity verifier. gnark's maintainers expect the impact of the issue be very small - only for the users who have implemented the native Groth16 verifier or are using it with multiple commitments. We do not have information of such users. The issue has been patched in version 0.11.0. As a workaround, users should follow gnark maintainers' recommendation to use only a single commitment and then derive in-circuit commitments as needed using the std/multicommit package.

Record
CVE-2024-45039
CVSS 3.1
6.2 MediumCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-200
Updated
2026-11-02
EUVDEUVD-2024-2851 6.2

gnark is a fast zk-SNARK library that offers a high-level API to design circuits. Versions prior to 0.11.0 have a soundness issue - in case of multiple commitments used inside the circuit the prover is able to choose all but the last commitment. As gnark uses the commitments for optimized non-native multiplication, lookup checks etc. as random challenges, then it could impact the soundness of the whole circuit. However, using multiple commitments has been discouraged due to the additional cost to the verifier and it has not been supported in the recursive in-circuit Groth16 verifier and Solidity verifier. gnark's maintainers expect the impact of the issue be very small - only for the users who have implemented the native Groth16 verifier or are using it with multiple commitments. We do not have information of such users. The issue has been patched in version 0.11.0. As a workaround, users should follow gnark maintainers' recommendation to use only a single commitment and then derive in-circuit commitments as needed using the std/multicommit package.

Record
EUVD-2024-2851
CVSS 3.1
6.2 MediumCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Updated
2026-11-03
GitHub AdvisoriesGHSA-q3hw-3gm4-w5cr 6.2

gnark's Groth16 commitment extension unsound for more than one commitment

Description

The summary is that the proof of knowledge associated to a commitment is crucial to bind the commitment to the actual circuit variables that were supposed to be committed. However, the same σ is used for all proofs of knowledge for the commitments, which allows mixing between them, making it possible to fix the value of all but one commitment before choosing the circuit variable assignments.

In more detail: To simplify notation, let us consider the case of two commitments, each to only a single variable. Let's say the basis elements for those commitments are K_0 and K_1. Then the proving key will contain K_0 and K_1, and also σ*K_0 and σ*K_1 for the proof of knowledge. The honest prover assigning a to the first circuit variable and b to the second will then produce commitments D_0 = a*K_0 D_1 = b*K_1 Out of the two D's, a challenge r for the commitment folding will be generated. The folded commitment will then be D_folded = D_0 + r*D_1 = a*K_0 + r*b*K_1 The honest prover will supply a fitting proof of knowledge P = a*(σ*K_0) + r*b*(σ*K_1)

Now the verifier will only use all of this in two ways:

  1. In the check of the Groth16 proof itself, where only the sum D_0 + D_1 is used.
  2. In the proof of knowledge check, where it will be verified that P is indeed σ*(D_0 + r*D_1), with r calculated from D_0 and D_1 as before.

This has the following implications. In the following, a malicious prover's points will have an apostrophe appended, and we keep D_0 etc. for the legitimate values:

  1. A malicious prover is only forced to provide D'_0 and D'_1 such that the sum is correct. So they can use arbitrary D'_0 as long as they set D'_1 = D_0 + D_1 - D'_0.
  2. After choosing D'_0 and D'_1, the prover can always calculate r. Evaluating σ*(D'_0 + r*D'_1) is then possible as long as both D'_0 and D'_1 are linear combinations of basis elements for which σ times that basis element is known. In particular, this works as long as D'_0 and D'_1 are linear combinations of K_0 and K_1.

The upshot is that a malicious prover can choose arbitrary a' and b', and then set D'_0 = a'*K_0 + b'*K_1 D'_1 = (a - a')*K_0 + (b - b')*K_1 Then they calculate r for this, and set P = (a' + r*(a-a'))*(σ*K_0) + (b' + r*(b-b'))*(σ*K_1) This will then be accepted as a valid proof. Yet the first commitment point can be chosen completely independently of a and b, so in particular the malicious prover can use a constant for this, so that they will know the in-circuit challenge that will be added to the public inputs before they have to choose the witness assignments. For most use cases of such challenges (for proving things with Fiat-Shamir, random linear combinations etc.) this causes a critical soundness problem.

The problem generalizes to more than two commitments and commitments to more than one circuit variable each; one can freely choose all but one commitment as arbitrary linear combinations of the basis elements for all commitments, and then must choose the one remaining commitment in such a way that the sum is correct.

The root cause of the issue is that the σ used for the proofs of knowledge is the same, allowing to mix between the basis elements, as one has σ times them available for all of them. So the fix is to have a separate σ for each commitment. So in our example above, the proving key would have the basis elements K_0 and K_1, and for the proofs of knowledge now σ_0*K_0 and σ_1*K_1. Folding the commitments would not be possible in the same way now, so the verifier will have to do more pairings. The prover could still provide a folded proof of knowledge however. With D_0 = a*K_0 D_1 = b*K_1 the proof of knowledge would be P = a*(σ_0*K_0) + r*b*(σ_1*K_1) For later, let us use notation for the unfolded proofs of knowledge P_0 = a*(σ_0*K_0) P_1 = b*(σ_1*K_1) so that P = P_0 + r*P_1

The verifying key would need G and σ_0*G and σ_1*G.…

Record
GHSA-q3hw-3gm4-w5cr
CVSS 3.1
6.2 MediumCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-200
Updated
2026-11-02
NVD 6.2

gnark is a fast zk-SNARK library that offers a high-level API to design circuits. Versions prior to 0.11.0 have a soundness issue - in case of multiple commitments used inside the circuit the prover is able to choose all but the last commitment. As gnark uses the commitments for optimized non-native multiplication, lookup checks etc. as random challenges, then it could impact the soundness of the whole circuit. However, using multiple commitments has been discouraged due to the additional cost to the verifier and it has not been supported in the recursive in-circuit Groth16 verifier and Solidity verifier. gnark's maintainers expect the impact of the issue be very small - only for the users who have implemented the native Groth16 verifier or are using it with multiple commitments. We do not have information of such users. The issue has been patched in version 0.11.0. As a workaround, users should follow gnark maintainers' recommendation to use only a single commitment and then derive in-circuit commitments as needed using the std/multicommit package.

Record
CVE-2024-45039
CVSS 3.1
6.2 MediumCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-200
Updated
2026-11-02
OSV 6.2

gnark's Groth16 commitment extension unsound for more than one commitment

gnark is a fast zk-SNARK library that offers a high-level API to design circuits. Versions prior to 0.11.0 have a soundness issue - in case of multiple commitments used inside the circuit the prover is able to choose all but the last commitment. As gnark uses the commitments for optimized non-native multiplication, lookup checks etc. as random challenges, then it could impact the soundness of the whole circuit. However, using multiple commitments has been discouraged due to the additional cost to the verifier and it has not been supported in the recursive in-circuit Groth16 verifier and Solidity verifier. gnark's maintainers expect the impact of the issue be very small - only for the users who have implemented the native Groth16 verifier or are using it with multiple commitments. We do not have information of such users. The issue has been patched in version 0.11.0. As a workaround, users should follow gnark maintainers' recommendation to use only a single commitment and then derive in-circuit commitments as needed using the std/multicommit package.

Record
CVE-2024-45039
CVSS 3.1
6.2 MediumCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-200
Updated
2026-11-02
OSVGHSA-q3hw-3gm4-w5cr 6.2

gnark's Groth16 commitment extension unsound for more than one commitment

Description

The summary is that the proof of knowledge associated to a commitment is crucial to bind the commitment to the actual circuit variables that were supposed to be committed. However, the same σ is used for all proofs of knowledge for the commitments, which allows mixing between them, making it possible to fix the value of all but one commitment before choosing the circuit variable assignments.

In more detail: To simplify notation, let us consider the case of two commitments, each to only a single variable. Let's say the basis elements for those commitments are K_0 and K_1. Then the proving key will contain K_0 and K_1, and also σ*K_0 and σ*K_1 for the proof of knowledge. The honest prover assigning a to the first circuit variable and b to the second will then produce commitments D_0 = a*K_0 D_1 = b*K_1 Out of the two D's, a challenge r for the commitment folding will be generated. The folded commitment will then be D_folded = D_0 + r*D_1 = a*K_0 + r*b*K_1 The honest prover will supply a fitting proof of knowledge P = a*(σ*K_0) + r*b*(σ*K_1)

Now the verifier will only use all of this in two ways:

  1. In the check of the Groth16 proof itself, where only the sum D_0 + D_1 is used.
  2. In the proof of knowledge check, where it will be verified that P is indeed σ*(D_0 + r*D_1), with r calculated from D_0 and D_1 as before.

This has the following implications. In the following, a malicious prover's points will have an apostrophe appended, and we keep D_0 etc. for the legitimate values:

  1. A malicious prover is only forced to provide D'_0 and D'_1 such that the sum is correct. So they can use arbitrary D'_0 as long as they set D'_1 = D_0 + D_1 - D'_0.
  2. After choosing D'_0 and D'_1, the prover can always calculate r. Evaluating σ*(D'_0 + r*D'_1) is then possible as long as both D'_0 and D'_1 are linear combinations of basis elements for which σ times that basis element is known. In particular, this works as long as D'_0 and D'_1 are linear combinations of K_0 and K_1.

The upshot is that a malicious prover can choose arbitrary a' and b', and then set D'_0 = a'*K_0 + b'*K_1 D'_1 = (a - a')*K_0 + (b - b')*K_1 Then they calculate r for this, and set P = (a' + r*(a-a'))*(σ*K_0) + (b' + r*(b-b'))*(σ*K_1) This will then be accepted as a valid proof. Yet the first commitment point can be chosen completely independently of a and b, so in particular the malicious prover can use a constant for this, so that they will know the in-circuit challenge that will be added to the public inputs before they have to choose the witness assignments. For most use cases of such challenges (for proving things with Fiat-Shamir, random linear combinations etc.) this causes a critical soundness problem.

The problem generalizes to more than two commitments and commitments to more than one circuit variable each; one can freely choose all but one commitment as arbitrary linear combinations of the basis elements for all commitments, and then must choose the one remaining commitment in such a way that the sum is correct.

The root cause of the issue is that the σ used for the proofs of knowledge is the same, allowing to mix between the basis elements, as one has σ times them available for all of them. So the fix is to have a separate σ for each commitment. So in our example above, the proving key would have the basis elements K_0 and K_1, and for the proofs of knowledge now σ_0*K_0 and σ_1*K_1. Folding the commitments would not be possible in the same way now, so the verifier will have to do more pairings. The prover could still provide a folded proof of knowledge however. With D_0 = a*K_0 D_1 = b*K_1 the proof of knowledge would be P = a*(σ_0*K_0) + r*b*(σ_1*K_1) For later, let us use notation for the unfolded proofs of knowledge P_0 = a*(σ_0*K_0) P_1 = b*(σ_1*K_1) so that P = P_0 + r*P_1

The verifying key would need G and σ_0*G and σ_1*G.…

Record
GHSA-q3hw-3gm4-w5cr
CVSS 3.1
6.2 MediumCVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
Weakness
CWE-200
Updated
2026-11-02
OSVGO-2024-3122 No score

Groth16 commitment extension unsound for more than one commitment in github.com/consensys/gnark

Groth16 commitment extension unsound for more than one commitment in github.com/consensys/gnark

Record
GO-2024-3122
Updated
2026-11-02
OSVopenSUSE-SU-2024:14599-1 No score

govulncheck-vulndb-0.0.20241213T205935-1.1 on GA media

These are all security issues fixed in the govulncheck-vulndb-0.0.20241213T205935-1.1 package on the GA media of openSUSE Tumbleweed.

Record
openSUSE-SU-2024:14599-1
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
github.com/consensys/gnark
Go
through 0.10.0
0.11.0
github.com/consensys/gnark
Go
before 0.11.0
0.11.0
govulncheck-vulndb
openSUSE:Tumbleweed
From an advisory covering 21 CVEs
before 0.0.20241213T205935-1.1
0.0.20241213T205935-1.1

History

History
RecordedChangedSources
affected, facts
aliases, publishedEUVD
first indexedCVE List, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2024-45039 is a medium vulnerability (CVSS 6.2) in Consensys Gnark, published September 6, 2024. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.19%, the 8th percentile. Fixed in github.com/consensys/gnark 0.11.0.

References

Show 23 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open