Search code examples
circuitcircomzk-snark

Can a non-constrained public signal be changed by an adversary in a Circom circuit?


I have a circuit that verifies the prover has the preimage of a hash, and I want to additionally commit to some extra data.

Kind of like a signature scheme, where the private key is the preimage, the public key is the hash, and I want to sign some message.

Is it safe to have the message as a non-constrained public signal to the circuit? (the circuit will validate that I have the preimage to the hash, where the preimage is a private signal, and the hash is a public signal)

Or can an adversary take my proof and swap the message (public signal) to whatever value they want because it is unconstrained?


Solution

  • Looks like if I add an intermediary signal that squares the public signal, it renders it untamperable

    As you can see done in the Semaphore circuit:

        // Dummy square to prevent tampering signalHash.
        signal signalHashSquared;
        signalHashSquared <== signalHash * signalHash;
    

    https://github.com/semaphore-protocol/semaphore/blob/main/packages/circuits/semaphore.circom#L83