Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proofs from Different Circom Circuits Can Be Interchanged, Leading to Potential Security Risks #330

Open
ly574605863 opened this issue Dec 28, 2024 · 4 comments

Comments

@ly574605863
Copy link

Description:
We discovered a potential security issue in the Circom framework where proofs generated by one circuit can be verified using the verification key of another circuit, provided their outputs match. This behavior could lead to security vulnerabilities in applications relying on Circom for critical operations.

Steps to Reproduce:
Define two Circom circuits with different internal constraints but potentially producing the same output for certain inputs.
For example:
Circuit 1: Add and Add

pragma circom 2.1.6;

template Multiply() {
  signal input a;
  signal input b;
  signal input c;
  signal s1;
  signal output out;

  s1 <== a + b;
  out <== s1 + c;
}

component main = Multiply();

Circuit 2: Multiply and Multiply

pragma circom 2.1.6;

template Multiply() {
  signal input a;
  signal input b;
  signal input c;
  signal s1;
  signal output out;

  s1 <== a * b;
  out <== s1 * c;
}

component main = Multiply();

Generate proofs for specific inputs where the output out matches for both circuits:

Circuit 1: a = 10, b = 10, c = 4, out = 24
Circuit 2: a = 2, b = 3, c = 4, out = 24
Attempt to verify the proof generated by Circuit 1 using the verification key of Circuit 2.

Expected Behavior:
Proofs generated by one circuit should not pass verification when using a different circuit’s verification key.

Actual Behavior:
The proof from Circuit 1 passes verification using the verification key of Circuit 2 due to matching outputs.

Potential Risks:
Bypassing Stronger Constraints: An adversary could use a simpler circuit to generate proofs that pass verification in a more restrictive circuit.
Undermining Application Logic: Applications relying on distinct circuits for specific guarantees might become vulnerable to unintended proof reuse.
Proposed Solutions:
Verification Key Binding: Bind verification keys more strictly to the specific circuit they correspond to. This could involve embedding a unique circuit identifier or hash within the verification process.
Output Validation: Require additional checks on intermediate signals or constraints during verification.
Environment:
Circom Version: 2.1.6

Additional Context:
I reuse this ptau in the trust setup: powersOfTau28_hez_final_08.ptau and didn't do zkey contribute in the next step.

@OBrezhniev
Copy link
Member

Hi! You haven't finished the trusted setup ceremony if you are using groth16 and don't have contributions.

@ly574605863
Copy link
Author

Thank you for your reply. May I ask, if I directly use a public PTAU without contributing myself, does it mean the constraints of Groth16 are not effective? I’m a bit curious about this because if the constraints were effective, it should be impossible to mix proofs.

@OBrezhniev
Copy link
Member

There is a problem with you circuits: in case of "Circuit 1" you don't have non-linear constraints, and linear ones were removed by the compiler (because in groth16 they are not contributing to circuit security, only additions that are part of non-linear constraints count):

template instances: 1
non-linear constraints: 0
linear constraints: 0
public inputs: 0
private inputs: 3 (none belong to witness)
public outputs: 1
wires: 2
labels: 6

Note this line:
private inputs: 3 (none belong to witness)
So whatever you put as private inputs here doesn't matter.
Anyway without zkey contributions behavior of the groth16 verifier is not defined, as it's not a valid state of a circuit.

@ly574605863
Copy link
Author

thanks a lot for your kindly response

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

No branches or pull requests

2 participants