Skip to content

Latest commit

 

History

History
1168 lines (870 loc) · 51.5 KB

BUGS.md

File metadata and controls

1168 lines (870 loc) · 51.5 KB

Table of Contents

circomlib_mimc

circom/circomlib_mimc/kobi_gurkan_mimc_hash_assigned_but_not_constrained

MiMC Hash: Assigned but not Constrained

  • Id: iden3/circomlib/Kobi-Gurkan-MiMC-Hash-Assigned-but-not-Constrained
  • Project: https://github.com/iden3/circomlib
  • Commit: 324b8bf8cc4a80357354752deb6c2ae5be22e5f5
  • Fix Commit: 109cdf40567fce284dca1d535819ce28922653e0
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Assigned but Unconstrained
  • Reproduced: True
  • Location
    • Path: circuits/mimcsponge.circom
    • Function: MiMCSponge
    • Line: 28
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

In MiMCSponge template, outs[0] is assigned but not constrained, so it can be any value. Note that the circuit code is modified from a newer version since the original buggy code couldn't be reproduced in Circom version 2. The bug idea is still the same.

Short Description of the Exploit

Set ins[0] and k to any random field element. Generate a correct witness first then modify the 2nd entry to a number as you wish. You can see that outs[0] can be any number.

Proposed Mitigation

Use <== instead of <-- to add a constraint to outs[0].

Similar Bugs

  • reclaimprotocol_circom_chacha/zksecurity_unsound_left_rotation
  • spartan_ecdsa/yacademy_input_signal_s_is_not_constrained_in_eff_ecdsa_circom

semaphore-protocol_semaphore

circom/semaphore-protocol_semaphore/veridise_no_zero_value_validation

No Zero Value Validation

  • Id: semaphore-protocol/semaphore/veridise-V-SEM-VUL-001
  • Project: https://github.com/semaphore-protocol/semaphore
  • Commit: 27320f17233b18de477a74919084fba76513470f
  • Fix Commit:
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Missing Input Constraints
  • Reproduced: True
  • Location
    • Path: circuits/semaphore.circom
    • Function: Semaphore
    • Line: 47-88
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

The bug in the Semaphore protocol involves the use of a zeroValue in incremental Merkle trees, which acts as an implicit group member. This zeroValue cannot be removed, and its addition does not trigger a MemberAdded event, making it invisible in membership records. This allows the group creator guaranteed access, which can be problematic if the admin changes. Additionally, if common values like 0 are compromised, they could be used to gain unauthorized access to groups.

Short Description of the Exploit

generateInput.js gives all necessary inputs for the incremental merkle tree. In real-world attack, identityNullifier and identityTrapdoor should be correct values corresponding to zeroValue membership in the incremental merkle tree. Here we just use 0 to represent them. The actual checks are in the solidity contracts.

Proposed Mitigation

Disallow proofs where the leaf corresponds to the zeroValue to ensure only legitimate users are added.

zkopru

circom/zkopru/leastauthority_previously_correct_ownership_proof_disabled_via_code_changes

Previously Correct Ownership Proof Disabled via Code Changes

Short Description of the Vulnerability

The circuit integrates with EdDSAPoseidonVerifier template from circomlib, but the enabled signal is set to 0, disabling the verification. There is no signature verification in the circuit, so attacker can craft some non-existent signature and still generate a valid proof.

Short Description of the Exploit

Run zkbugs_js_setup.sh to set up the circomlibjs environment. Do node generateInput.js to generate the input for the circuit. Here every field besides S is valid, the signature is hardcoded to 13371337 for demonstrating the bug.

Proposed Mitigation

Change the line of code to eddsa.enabled <== 1.

uniRep_protocol

circom/uniRep_protocol/veridise_missing_range_checks_on_comparison_circuits

Missing Range Checks on Comparison Circuits

  • Id: Unirep/Unirep/veridise-V-UNI-VUL-002
  • Project: https://github.com/Unirep/Unirep
  • Commit: 0985a28c38c8b2e7b7a9e80f43e63179fdd08b89
  • Fix Commit: f7b0bcd39383d5ec4d17edec2ad91bc01333bf36
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Unsafe Reuse of Circuit
  • Reproduced: True
  • Location
    • Path: circuits/epochKeyLite.circom
    • Function: EpochKeyLite
    • Line: 45-48
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

Input of LessThan(8) is assumed to have <=8 bits, but there is no constraint for it in LessThan template. Attacker can use large values such as p - 1 to trigger overflow and make something like p - 1 < EPOCH_KEY_NONCE_PER_EPOCH return true.

Short Description of the Exploit

Set nonce = -1 in input.json and other inputs to 0 then generate witness. No need to modify the witness.

Proposed Mitigation

Implement range check so that attacker can't exploit overflow in LessThan.

Similar Bugs

  • darkforest_circuits/daira_hopwood_darkforest_v0_3_missing_bit_length_check

circom/uniRep_protocol/veridise_underconstrained_circuit_allows_invalid_comparison

Underconstrained Circuit allows Invalid Comparison

  • Id: Unirep/Unirep/veridise-V-UNI-VUL-001
  • Project: https://github.com/Unirep/Unirep
  • Commit: 0985a28c38c8b2e7b7a9e80f43e63179fdd08b89
  • Fix Commit: 3348caa362d5d632d29c532ffa88023d55628eab
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Arithmetic Field Errors
  • Reproduced: True
  • Location
    • Path: circuits/bigComparators.circom
    • Function: BigLessThan
    • Line: 45
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

Num2Bits(254) is used so malicious prover can provide input that is larger than scalar field modulus p but smaller than 2**254, exploiting the overflow. That makes some comparison opertions invalid, for example, 1 < p evaluates to true but in the circuit it is treated as 1 < 0.

Short Description of the Exploit

Set in[0] to 1 and in[1] to p, then generate the witness from inputs directly, no need to modify the witness.

Proposed Mitigation

Use Num2Bits_strict rather than Num2Bits(254).

circom-bigint_circomlib

circom/circom-bigint_circomlib/veridise_underconstrained_points_in_montgomeryAdd

Underconstrained points in MontgomeryAdd

  • Id: iden3/circomlib/veridise-V-CIRCOMLIB-VUL-004
  • Project: https://github.com/iden3/circomlib
  • Commit: cff5ab6288b55ef23602221694a6a38a0239dcc0
  • Fix Commit:
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Missing Input Constraint
  • Reproduced: True
  • Location
    • Path: circuits/montgomery.circom
    • Function: MontgomeryAdd
    • Line: 16-17
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

Lambda calculation involves a division but there is no constraint on the divisor to be non-zero. In this case out[1] is underconstrained and can be set to any value.

Short Description of the Exploit

Set out[0] to -168697. out[1] can be set to any value but it has to satisfy some relative relation with in1[1] and in2[1]. Check out detect.sage to learn more.

Proposed Mitigation

Send in2[0] - in1[0] to isZero template and let the constraint there do the work.

Similar Bugs

  • circom-bigint_circomlib/veridise_decoder_accepting_bogus_output_signal
  • circom-bigint_circomlib/veridise_underconstrained_outputs_in_bitElementMulAny
  • circom-bigint_circomlib/veridise_underconstrained_points_in_edwards2Montgomery
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomery2Edwards
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomeryDouble

circom/circom-bigint_circomlib/veridise_underconstrained_outputs_in_bitElementMulAny

Underconstrained outputs in BitElementMulAny

  • Id: iden3/circomlib/veridise-V-CIRCOMLIB-VUL-006
  • Project: https://github.com/iden3/circomlib
  • Commit: cff5ab6288b55ef23602221694a6a38a0239dcc0
  • Fix Commit:
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Unsafe Reuse of Circuit
  • Reproduced: True
  • Location
    • Path: circuits/escalarmulany.circom
    • Function: BitElementMulAny
    • Line: 21-22
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

BitElementMulAny template itself is fine, but it uses MontgomeryDouble and MontgomeryAdd, which have underconstraint bugs. With the same input.json, malicious prover can manipulate lambda value in MontgomeryDouble to let the circuit produce different outputs, making it nondeterministic.

Short Description of the Exploit

In input.json, just use dummy EC point (1,2) to pass the positive test. Then we exploit the MontgomeryDouble underconstrained bug, let divisor be 0 and solve for the exploitable witness in sagemath step by step.

Proposed Mitigation

Fix underconstraint bugs in MontgomeryDouble and MontgomeryAdd.

Similar Bugs

  • circom-bigint_circomlib/veridise_decoder_accepting_bogus_output_signal
  • circom-bigint_circomlib/veridise_underconstrained_points_in_edwards2Montgomery
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomery2Edwards
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomeryAdd
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomeryDouble

circom/circom-bigint_circomlib/veridise_underconstrained_points_in_montgomeryDouble

Underconstrained points in MontgomeryDouble

  • Id: iden3/circomlib/veridise-V-CIRCOMLIB-VUL-005
  • Project: https://github.com/iden3/circomlib
  • Commit: cff5ab6288b55ef23602221694a6a38a0239dcc0
  • Fix Commit:
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Missing Input Constraints
  • Reproduced: True
  • Location
    • Path: circuits/montgomery.circom
    • Function: MontgomeryDouble
    • Line: 18-19
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

Lambda calculation involves a division but there is no constraint on the divisor to be non-zero. In this case lamda is underconstrained and can be set to any value.

Short Description of the Exploit

Set in[1] to 0. Make the assumption that 3*x1_2 + 2*A*in[0] + 1 == 0 and solve for rest of the signals with some sagemath magic.

Proposed Mitigation

Send in[1] to isZero template and let the constraint there do the work.

Similar Bugs

  • circom-bigint_circomlib/veridise_decoder_accepting_bogus_output_signal
  • circom-bigint_circomlib/veridise_underconstrained_outputs_in_bitElementMulAny
  • circom-bigint_circomlib/veridise_underconstrained_points_in_edwards2Montgomery
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomery2Edwards
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomeryAdd

circom/circom-bigint_circomlib/veridise_decoder_accepting_bogus_output_signal

Decoder accepting bogus output signal

  • Id: iden3/circomlib/veridise-V-CIRCOMLIB-VUL-001
  • Project: https://github.com/iden3/circomlib
  • Commit: cff5ab6288b55ef23602221694a6a38a0239dcc0
  • Fix Commit:
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Wrong translation of logic into constraints
  • Reproduced: True
  • Location
    • Path: circuits/multiplexer.circom
    • Function: Decoder
    • Line: 10-11
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

The circuit does not constrain out properly, malicious prover can set a bogus out and set success to 0, the circuit won't throw error. This makes integration error-prone.

Short Description of the Exploit

Set out to be full of zeroes and set success to 0.

Proposed Mitigation

Send inp - i to isZero template and let the constraint there do the work.

Similar Bugs

  • circom-bigint_circomlib/veridise_underconstrained_outputs_in_bitElementMulAny
  • circom-bigint_circomlib/veridise_underconstrained_points_in_edwards2Montgomery
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomery2Edwards
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomeryAdd
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomeryDouble

circom/circom-bigint_circomlib/veridise_underconstrained_outputs_in_windowmulfix

Underconstrained outputs in WindowMulFix

  • Id: iden3/circomlib/veridise-V-CIRCOMLIB-VUL-008
  • Project: https://github.com/iden3/circomlib
  • Commit: cff5ab6288b55ef23602221694a6a38a0239dcc0
  • Fix Commit:
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Unsafe Reuse of Circuit
  • Reproduced: True
  • Location
    • Path: circuits/escalarmulfix.circom
    • Function: WindowMulFix
    • Line: 70-131
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

WindowMulFix template itself is fine, but it uses MontgomeryDouble and MontgomeryAdd, which have underconstraint bugs. With the same input.json, malicious prover can manipulate lambda value in MontgomeryDouble to let the circuit produce different outputs, making it nondeterministic.

Short Description of the Exploit

Here we exploit the MontgomeryDouble underconstrained bug, let divisor be 0 and solve for signals in sagemath step by step. The full witness is provided in veridise report.

Proposed Mitigation

Fix underconstraint bugs in MontgomeryDouble and MontgomeryAdd.

circom/circom-bigint_circomlib/veridise_underconstrained_outputs_in_window4

Underconstrained outputs in Window4

  • Id: iden3/circomlib/veridise-V-CIRCOMLIB-VUL-007
  • Project: https://github.com/iden3/circomlib
  • Commit: cff5ab6288b55ef23602221694a6a38a0239dcc0
  • Fix Commit:
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Unsafe Reuse of Circuit
  • Reproduced: True
  • Location
    • Path: circuits/pederson.circom
    • Function: Window4
    • Line: 47-108
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

Window4 template itself is fine, but it uses MontgomeryDouble and MontgomeryAdd, which have underconstraint bugs. With the same input.json, malicious prover can manipulate lambda value in MontgomeryDouble to let the circuit produce different outputs, making it nondeterministic.

Short Description of the Exploit

Here we exploit the MontgomeryDouble underconstrained bug, let divisor be 0 and solve for signals in sagemath step by step. The full witness is provided in veridise report.

Proposed Mitigation

Fix underconstraint bugs in MontgomeryDouble and MontgomeryAdd.

circom/circom-bigint_circomlib/veridise_underconstrained_points_in_edwards2Montgomery

Underconstrained points in Edwards2Montgomery

  • Id: iden3/circomlib/veridise-V-CIRCOMLIB-VUL-002
  • Project: https://github.com/iden3/circomlib
  • Commit: cff5ab6288b55ef23602221694a6a38a0239dcc0
  • Fix Commit:
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Missing Input Constraints
  • Reproduced: True
  • Location
    • Path: circuits/montgomery.circom
    • Function: Edwards2Montgomery
    • Line: 7-8
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

The circuit does not implement constraint to avoid division by zero. When setting the divisor to 0, out[1] is underconstrained and can be set to any value.

Short Description of the Exploit

Set in[0] to 0 to trigger division by zero. Set out[1] to 1337 just to show that it can be set to any value.

Proposed Mitigation

Send in[0] and 1 - in[1] to isZero template and let the constraint there do the work.

Similar Bugs

  • circom-bigint_circomlib/veridise_decoder_accepting_bogus_output_signal
  • circom-bigint_circomlib/veridise_underconstrained_outputs_in_bitElementMulAny
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomery2Edwards
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomeryAdd
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomeryDouble

circom/circom-bigint_circomlib/veridise_missing_range_checks_in_bigmod

Missing range checks in BigMod

  • Id: 0xbok/circom-bigint/veridise-V-BIGINT-COD-001
  • Project: https://github.com/0xbok/circom-bigint
  • Commit: 436665bf01728ae8c581fdb39e8428cb6b835c37
  • Fix Commit: d3edd7503f48f98a71b6013c248ef3ad55e19703
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Arithmetic Field Errors
  • Reproduced: True
  • Location
    • Path: circuits/bigint.circom
    • Function: BigMod
    • Line: 363-417
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

The bug in the BigMod template arises from missing range checks on the remainder mod[i], allowing it to exceed the expected range of 2**n. This underconstrained error can be exploited by providing inputs that result in a remainder larger than 2^n, potentially compromising the integrity of the circuit. Proper range checks are applied to the quotient div[i], but not to mod[i], leaving the system vulnerable to malicious inputs that break the invariant of the modulus operation.

Short Description of the Exploit

We design a pair of a and b such that the remainder after divmod overflows 2**126.

Proposed Mitigation

Add additional range checking constraints for mod[i]. This can be done using the Num2Bits template.

circom/circom-bigint_circomlib/veridise_underconstrained_points_in_montgomery2Edwards

Underconstrained points in Montgomery2Edwards

  • Id: iden3/circomlib/veridise-V-CIRCOMLIB-VUL-003
  • Project: https://github.com/iden3/circomlib
  • Commit: cff5ab6288b55ef23602221694a6a38a0239dcc0
  • Fix Commit:
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Missing Input Constraints
  • Reproduced: True
  • Location
    • Path: circuits/montgomery.circom
    • Function: Montgomery2Edwards
    • Line: 7-8
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

The circuit does not implement constraint to avoid division by zero. When setting the divisor to 0, out[0] is underconstrained and can be set to any value.

Short Description of the Exploit

Set in[1] to 0 to trigger division by zero. Set out[0] to 1337 just to show that it can be set to any value.

Proposed Mitigation

Send in[1] and in[0] + 1 to isZero template and let the constraint there do the work.

Similar Bugs

  • circom-bigint_circomlib/veridise_decoder_accepting_bogus_output_signal
  • circom-bigint_circomlib/veridise_underconstrained_outputs_in_bitElementMulAny
  • circom-bigint_circomlib/veridise_underconstrained_points_in_edwards2Montgomery
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomeryAdd
  • circom-bigint_circomlib/veridise_underconstrained_points_in_montgomeryDouble

darkforest_circuits

circom/darkforest_circuits/daira_hopwood_darkforest_v0_3_missing_bit_length_check

Dark Forest v0.3: Missing Bit Length Check

Short Description of the Vulnerability

Input of LessThan(bits) is assumed to take inputs bounded by 2**(bits-1), but there is no constraint for it in LessThan template. Attacker can use unexpected values outside the range and pass all the constraints, rendering this RangeProof useless. Note: The original circuit does not contain the output out, it was added to prevent snarkJS 'Scalar size does not match' error.

Short Description of the Exploit

Set in = -255 then generate witness. No need to modify the witness.

Proposed Mitigation

Add constraints to check the range of in and max_abs_value. This can be done using the Num2Bits template.

Similar Bugs

  • uniRep_protocol/veridise_missing_range_checks_on_comparison_circuits

reclaimprotocol_circom_chacha

circom/reclaimprotocol_circom_chacha/zksecurity_unsound_left_rotation

Unsound Left Rotation

  • Id: reclaimprotocol/circom-chacha20/zksecurity-1
  • Project: https://github.com/reclaimprotocol/circom-chacha20
  • Commit: ef9f5a5ad899d852740a26b30eabe5765673c71f
  • Fix Commit: e5e756375fc1fc8dc48667b00cdf38c79a0fdf50
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Wrong translation of logic into constraints
  • Reproduced: True
  • Location
    • Path: circuits/generics.circom
    • Function: RotateLeft32Bits
    • Line: 39-45
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

The part1 and part2 signals are not sufficiently constrained. One can arbitrarily set a value to part1 or part2 and find a value for the other signal to satisfy the constraint on line 45. This way you can get another out value for a given in.

Short Description of the Exploit

To exploit the vulnerability, one has to simply find a witness that produces a different value for out rather than the one produced by the witness generator. The sage script demonstrates how to find another witness that satisfies the constraints. Then, you simply need to produce a new proof.

Proposed Mitigation

The recommendation to fix this issue was to constrain part1 (resp. part2) to be (resp. ) bit-sized values. For the concrete mitigation applied, check the commit of the fix.

Similar Bugs

  • circomlib_mimc/kobi_gurkan_mimc_hash_assigned_but_not_constrained
  • spartan_ecdsa/yacademy_input_signal_s_is_not_constrained_in_eff_ecdsa_circom

spartan_ecdsa

circom/spartan_ecdsa/yacademy_input_signal_s_is_not_constrained_in_eff_ecdsa_circom

Input signal s is not constrained in eff_ecdsa.circom

  • Id: personaelabs/spartan-ecdsa/yacademy-high-01
  • Project: https://github.com/personaelabs/spartan-ecdsa
  • Commit: 3386b30d9b5b62d8a60735cbeab42bfe42e80429
  • Fix Commit:
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Missing Input Constraints
  • Reproduced: True
  • Location
    • Path: circuits/eff_ecdsa.circom
    • Function: EfficientECDSA
    • Line: 25-28
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

The circuit computes pubKey = s * T + U but s isn't constrained. If we set s = 0 and (Ux, Uy) = pubKey, then (Tx, Ty) can be any pair of values.

Short Description of the Exploit

Set s = 0 and rest of the inputs can be any number.

Proposed Mitigation

Add constraint to s so that s * T can't be skipped in the computation.

Similar Bugs

  • circomlib_mimc/kobi_gurkan_mimc_hash_assigned_but_not_constrained
  • reclaimprotocol_circom_chacha/zksecurity_unsound_left_rotation

circom/spartan_ecdsa/yacademy_under_constrained_circuits_compromising_the_soundness_of_the_system

Under constrained circuits compromising the soundness of the system (Not Reproduce)

  • Id: personaelabs/spartan-ecdsa/yacademy-high-03
  • Project: https://github.com/personaelabs/spartan-ecdsa
  • Commit: 3386b30d9b5b62d8a60735cbeab42bfe42e80429
  • Fix Commit:
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Assigned but Unconstrained
  • Reproduced: False
  • Location
    • Path: circuits/mul.circom
    • Function: K
    • Line: 123-124
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

The signals slo and shi are assigned but not constrained

Short Description of the Exploit

Modify slo or shi, then deduce all related intermediate signals and modify the witness.

Proposed Mitigation

Use <== instead of <--.

succinctlabs_telepathy-circuits

circom/succinctlabs_telepathy-circuits/trailofbits_prover_can_lock_user_funds_by_including_ill-formed_bigints_in_public_key_commitment

Prover can lock user funds by including ill-formed BigInts in public key commitment (Not Reproduce)

  • Id: succinctlabs/telepathy-circuits/trailofbits-succinct-1
  • Project: https://github.com/iden3/circomlib
  • Commit: b0c839cef30c3c25ef41d1ad3000081784766934
  • Fix Commit: 1a88e657932edc59b51e35095618f1e1a46ceef6
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Completeness
  • Root Cause: Unsafe Reuse of Circuit
  • Reproduced: False
  • Location
    • Path: circuits/pairing/bls12_381_hash_to_G2
    • Function: SubgroupCheckG1WithValidX
    • Line: 723-731
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

The Rotate() template in rotate.circom fails to validate the format of BigInts in public keys. SubgroupCheckG1WithValidX assumes that its input is a properly formed BigInt, with all limbs less than 2**55. This property is not validated anywhere in the Rotate() template. It allows a malicious prover to manipulate public keys by inserting ill-formed BigInts, specifically by altering the y-coordinate of public keys. This manipulation can lock user funds by preventing future provers from generating valid proofs, as the circuit uses these malformed keys without proper validation. The exploit involves modifying the y coordinate in a public key to create an invalid commitment, which then updates the system's commitment state, potentially leading to incorrect or fraudulent operations.

Short Description of the Exploit

Subtract one from the most significant limb and add 2**55 to the second-most significant limb.

Proposed Mitigation

Use Num2Bits() template to verify that each limb of the pubkeysBigIntY, witness value is less than 2**55.

circom/succinctlabs_telepathy-circuits/veridise_template_CoreVerifyPubkeyG1_does_not_perform_input_validation_simplified

Template CoreVerifyPubkeyG1 does not perform input validation (Simplified)

  • Id: succinctlabs/telepathy-circuits/veridise-V-SUC-VUL-002-simplified
  • Project: https://github.com/succinctlabs/telepathy-circuits
  • Commit: 9c84fb0f38531718296d9b611f8bd6107f61a9b8
  • Fix Commit: b0c839cef30c3c25ef41d1ad3000081784766934
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Unsafe Reuse of Circuit
  • Reproduced: True
  • Location
    • Path: circuits/bls_signature.circom
    • Function: CoreVerifyPubkeyG1ToyExample
    • Line: 77-95
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

This bug is in the circom-pairing BLS signature verification logic. pubkey, signature and hash are divided into 7-entry chunks of 55-bit data, and each entry is checked against according entry in p. When calling BigLessThan(), the output isn't verified therefore attacker can manipulate the input so that it overflows p.

Short Description of the Exploit

The circuit had been simplified to demonstrate the bug, the attack idea is calculating a delta such that it makes the input overflow but still bounded by 2**55 - 1 to pass the range check inside BigLessThan(). In reality, attacker would bruteforce a special set of inputs satisfying a list of constraints. The details are explained in the PR comment.

Proposed Mitigation

In each iteration of the for loop, add a constraint lt[idx].out === 1 to make sure the input is indeed bounded by p.

circom/succinctlabs_telepathy-circuits/veridise_zero_padding_for_sha256_in_ExpandMessageXMD_is_vulnerable_to_an_overflow

Zero Padding for Sha256 in ExpandMessageXMD is vulnerable to an overflow

  • Id: succinctlabs/telepathy-circuits/veridise-V-SUC-VUL-003
  • Project: https://github.com/succinctlabs/telepathy-circuits/
  • Commit: 9c84fb0f38531718296d9b611f8bd6107f61a9b8
  • Fix Commit: b0c839cef30c3c25ef41d1ad3000081784766934
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Arithmetic Field Errors
  • Reproduced: True
  • Location
    • Path: circuits/hash_to_field.circom
    • Function: I2OSP
    • Line: 3-23
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

Template ExpandMessageXMD calls I2OSP(64) with in set to 0. In template I2OSP, numbers are represented in bigint format, a 64-byte chunk. This representation allows number much larger than scalar field modulus p, so attacker can compute 0 + k * p and turn that into bigint representation and still pass the constraints.

Short Description of the Exploit

Compute 0 + p and turn that into bigint format. Also keep track of the accumulator acc[64].

Proposed Mitigation

Add assertion assert(l < 31) when using template I2OSP(l), so the largest possible number is 31 * 8 = 248 bit, which is less than scalar field modulus p.

circom/succinctlabs_telepathy-circuits/trailofbits_prover_can_lock_user_funds_by_supplying_non-reduced_Y_values_to_G1BigIntToSignFlag

Prover can lock user funds by supplying non-reduced Y values to G1BigIntToSignFlag

  • Id: succinctlabs/telepathy-circuits/trailofbits-succinct-2
  • Project: https://github.com/succinctlabs/telepathy-circuits
  • Commit: b0c839cef30c3c25ef41d1ad3000081784766934
  • Fix Commit: 1a88e657932edc59b51e35095618f1e1a46ceef6
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Completeness
  • Root Cause: Unsafe Reuse of Circuit
  • Reproduced: True
  • Location
    • Path: circuits/bls.circom
    • Function: G1BigIntToSignFlag
    • Line: 198-227
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

G1BigIntToSignFlag fails to check if the y-coordinate is properly reduced mod p. This missing of range check allows malicious prover to lock user funds by supplying a non-reduced y-coordinate, which can be manipulated to have a positive sign when it should be negative. This manipulation can prevent future provers from generating valid proofs, effectively halting the LightClient and trapping user funds in the bridge.

Short Description of the Exploit

In detect.sage, we grab a 'positive' y-coordinate from a public key and turn it into 'negative' by negating it and mod p. We call this new value y and it has negative sign. Now we compute 2*p - y and use it as input. This value is congruent to -y mod p so it is positive, but the circuit still considers it as negative. This fact can be observed in exploitable_witness.json: the second entry is 0, which represents negative sign.

Proposed Mitigation

Constrain the pubkeysBigIntY values to be less than p using BigLessThan template.

circom/succinctlabs_telepathy-circuits/trailofbits_incorrect_handling_of_point_doubling_can_allow_signature_forgery

Incorrect handling of point doubling can allow signature forgery

  • Id: succinctlabs/telepathy-contracts
  • Project: https://github.com/succinctlabs/telepathy-contracts
  • Commit: b0c839cef30c3c25ef41d1ad3000081784766934
  • Fix Commit:
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Unsafe Reuse of Circuit
  • Reproduced: True
  • Location
    • Path: circuits/curve.circom
    • Function: EllipticCurveAddUnequal
    • Line: 155-227
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

G1Add calls EllipticCurveAddUnequal. The template EllipticCurveAddUnequal assumes input a and b are two unequal public keys but this is not checked. Attacker can use two same public keys to do sophisticated attacks. In such scenario, the constraint on output in EllipticCurveAddUnequal reduces to 0 = 0 so it is always true. In other words, attacker can do point doubling at a place where it is supposed to do point addition of two unequal EC points.

Short Description of the Exploit

We generate A = aG, B = bG and C = (a+b)G. We use (a+b)G for both inputs.

Proposed Mitigation

Change G1Add to use EllipticCurveAdd, which correctly handles equal inputs by checking and managing point doubling.

circom/succinctlabs_telepathy-circuits/veridise_arrayxor_is_under_constrained

ArrayXOR is under constrained

  • Id: succinctlabs/telepathy-circuits/veridise-V-SUC-VUL-001
  • Project: https://github.com/succinctlabs/telepathy-circuits
  • Commit: 9c84fb0f38531718296d9b611f8bd6107f61a9b8
  • Fix Commit: b0c839cef30c3c25ef41d1ad3000081784766934
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Assigned but Unconstrained
  • Reproduced: True
  • Location
    • Path: circuits/hash_to_field.circom
    • Function: ArrayXOR
    • Line: 9
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

out[i]is assigned with<--but not constrained with<==`, so it can be set to any value.

Short Description of the Exploit

Generate a correct witness first, then modify entry 2 to 5 to any field element.

Proposed Mitigation

Change the code to out[i] <== a[i] ^ b[i].

maci

circom/maci/hashcloak_data_are_not_fully_verified_during_state_update

Initial Conditions Are Not Properly Enforced (Not Reproduce)

  • Id: privacy-scaling-explorations/maci/hashcloak_initial_conditions_are_not_properly_enforced
  • Project: https://github.com/privacy-scaling-explorations/maci
  • Commit: 2db5f625b67a6b810bd851950d7a42c26189088b
  • Fix Commit: d0792d1e532fd0a7fead4a21cb8f54af6022c4c4
  • DSL: Circom
  • Vulnerability: Under-Constrained
  • Impact: Soundness
  • Root Cause: Wrong translation of logic into constraints
  • Reproduced: False
  • Location
    • Path: circuits/tallyVotes.circom
    • Function: ResultCommitmentVerifier
    • Line: 89-92
  • Source: Audit Report
  • Commands
    • Setup Environment: ./zkbugs_setup.sh
    • Reproduce: ./zkbugs_exploit.sh
    • Compile and Preprocess: ./zkbugs_compile_setup.sh
    • Positive Test: ./zkbugs_positive_test.sh
    • Find Exploit: ./zkbugs_find_exploit.sh
    • Clean: ./zkbugs_clean.sh

Short Description of the Vulnerability

If the batch is the first batch, iz.out will be 0, and hz will be 0, so the constraint hz <== iz.out * currentTallyCommitmentHasher.hash will always hold true. There is no checks confirming that the current tally is actually the initial tally in such a case.

Short Description of the Exploit

Use some random values as tally data and set current_tally_commitment = 0.

Proposed Mitigation

In 2023 the protocol was refactored, as explained here: privacy-scaling-explorations/maci#279.