-
Notifications
You must be signed in to change notification settings - Fork 0
/
circuit.go
68 lines (53 loc) · 2.43 KB
/
circuit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package main
import (
"fmt"
"math/big"
"github.com/consensys/gnark/frontend"
"github.com/succinctlabs/gnark-plonky2-verifier/types"
"github.com/succinctlabs/gnark-plonky2-verifier/variables"
"github.com/succinctlabs/gnark-plonky2-verifier/verifier"
)
type Plonky2xVerifierCircuit struct {
// A digest of the plonky2x circuit that is being verified.
VerifierDigest frontend.Variable `gnark:"verifierDigest,public"`
// The input hash is the hash of all onchain inputs into the function.
InputHash frontend.Variable `gnark:"inputHash,public"`
// The output hash is the hash of all outputs from the function.
OutputHash frontend.Variable `gnark:"outputHash,public"`
// Private inputs to the circuit
ProofWithPis variables.ProofWithPublicInputs
VerifierData variables.VerifierOnlyCircuitData
// Circuit configuration that is not part of the circuit itself.
CommonCircuitData types.CommonCircuitData `gnark:"-"`
}
func (c *Plonky2xVerifierCircuit) Define(api frontend.API) error {
// initialize the verifier chip
verifierChip := verifier.NewVerifierChip(api, c.CommonCircuitData)
// verify the plonky2 proof
verifierChip.Verify(c.ProofWithPis.Proof, c.ProofWithPis.PublicInputs, c.VerifierData)
// We assume that the publicInputs have 64 bytes
// publicInputs[0:32] is a big-endian representation of a SHA256 hash that has been truncated to 253 bits.
// Note that this truncation happens in the `WrappedCircuit` when computing the `input_hash`
// The reason for truncation is that we only want 1 public input on-chain for the input hash
// to save on gas costs
publicInputs := c.ProofWithPis.PublicInputs
if len(publicInputs) != 64 {
return fmt.Errorf("expected 64 public inputs, got %d", len(publicInputs))
}
inputDigest := frontend.Variable(0)
for i := 0; i < 32; i++ {
pubByte := publicInputs[31-i].Limb
inputDigest = api.Add(inputDigest, api.Mul(pubByte, frontend.Variable(new(big.Int).Lsh(big.NewInt(1), uint(8*i)))))
}
api.AssertIsEqual(c.InputHash, inputDigest)
outputDigest := frontend.Variable(0)
for i := 0; i < 32; i++ {
pubByte := publicInputs[63-i].Limb
outputDigest = api.Add(outputDigest, api.Mul(pubByte, frontend.Variable(new(big.Int).Lsh(big.NewInt(1), uint(8*i)))))
}
api.AssertIsEqual(c.OutputHash, outputDigest)
// We have to assert that the VerifierData we verified the proof with
// matches the VerifierDigest public input.
api.AssertIsEqual(c.VerifierDigest, c.VerifierData.CircuitDigest)
return nil
}