mirror of
https://github.com/arnaucube/gnark-plonky2-verifier.git
synced 2026-01-12 17:11:31 +01:00
Step test case with public inputs (#23)
* added step test case * export solidity code * just set proof's public input as public variables * make serialization a command line option * added flag to output solidity * some changes to the benchmark file * used gnark cherry picked bug fix * removed fuzz testing * added some logging * more debug messages and test cases for the hint issue * removed usage of goldilocks reduce * removed prints * removed GoldilocksReduce * removed prints * added a todo * some serialization changes
This commit is contained in:
86
benchmark.go
86
benchmark.go
@@ -6,22 +6,25 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc"
|
||||
"github.com/consensys/gnark/backend/groth16"
|
||||
"github.com/consensys/gnark/constraint"
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/frontend/cs/r1cs"
|
||||
"github.com/consensys/gnark/profile"
|
||||
)
|
||||
|
||||
type BenchmarkPlonky2VerifierCircuit struct {
|
||||
ProofWithPis common.ProofWithPublicInputs `gnark:",public"`
|
||||
Proof common.Proof
|
||||
PublicInputs []field.F `gnark:",public"`
|
||||
|
||||
verifierChip *verifier.VerifierChip
|
||||
plonky2CircuitName string
|
||||
verifierChip *verifier.VerifierChip `gnark:"-"`
|
||||
plonky2CircuitName string `gnark:"-"`
|
||||
}
|
||||
|
||||
func (circuit *BenchmarkPlonky2VerifierCircuit) Define(api frontend.API) error {
|
||||
@@ -31,20 +34,21 @@ func (circuit *BenchmarkPlonky2VerifierCircuit) Define(api frontend.API) error {
|
||||
|
||||
circuit.verifierChip = verifier.NewVerifierChip(api, commonCircuitData)
|
||||
|
||||
circuit.verifierChip.Verify(circuit.ProofWithPis, verifierOnlyCircuitData, commonCircuitData)
|
||||
circuit.verifierChip.Verify(circuit.Proof, circuit.PublicInputs, verifierOnlyCircuitData, commonCircuitData)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func compileCircuit(plonky2Circuit string, doProfiling bool) {
|
||||
func compileCircuit(plonky2Circuit string, profileCircuit bool, serialize bool, outputSolidity bool) (constraint.ConstraintSystem, groth16.ProvingKey, groth16.VerifyingKey) {
|
||||
circuit := BenchmarkPlonky2VerifierCircuit{
|
||||
plonky2CircuitName: plonky2Circuit,
|
||||
}
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
circuit.ProofWithPis = proofWithPis
|
||||
circuit.Proof = proofWithPis.Proof
|
||||
circuit.PublicInputs = proofWithPis.PublicInputs
|
||||
|
||||
var p *profile.Profile
|
||||
if doProfiling {
|
||||
if profileCircuit {
|
||||
p = profile.Start()
|
||||
}
|
||||
r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit)
|
||||
@@ -53,7 +57,7 @@ func compileCircuit(plonky2Circuit string, doProfiling bool) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if doProfiling {
|
||||
if profileCircuit {
|
||||
p.Stop()
|
||||
p.Top()
|
||||
println("r1cs.GetNbCoefficients(): ", r1cs.GetNbCoefficients())
|
||||
@@ -63,9 +67,14 @@ func compileCircuit(plonky2Circuit string, doProfiling bool) {
|
||||
println("r1cs.GetNbInternalVariables(): ", r1cs.GetNbInternalVariables())
|
||||
}
|
||||
|
||||
fR1CS, _ := os.Create("circuit")
|
||||
r1cs.WriteTo(fR1CS)
|
||||
fR1CS.Close()
|
||||
// Don't serialize the circuit for now, since it takes up too much memory
|
||||
/*
|
||||
if serialize {
|
||||
fR1CS, _ := os.Create("circuit")
|
||||
r1cs.WriteTo(fR1CS)
|
||||
fR1CS.Close()
|
||||
}
|
||||
*/
|
||||
|
||||
fmt.Println("Running circuit setup", time.Now())
|
||||
pk, vk, err := groth16.Setup(r1cs)
|
||||
@@ -74,42 +83,37 @@ func compileCircuit(plonky2Circuit string, doProfiling bool) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fPK, _ := os.Create("proving.key")
|
||||
pk.WriteTo(fPK)
|
||||
fPK.Close()
|
||||
if serialize {
|
||||
fPK, _ := os.Create("proving.key")
|
||||
pk.WriteTo(fPK)
|
||||
fPK.Close()
|
||||
|
||||
fVK, _ := os.Create("verifying.key")
|
||||
vk.WriteTo(fVK)
|
||||
fVK.Close()
|
||||
fVK, _ := os.Create("verifying.key")
|
||||
vk.WriteTo(fVK)
|
||||
fVK.Close()
|
||||
}
|
||||
|
||||
if outputSolidity {
|
||||
fSolidity, _ := os.Create("proof.sol")
|
||||
err = vk.ExportSolidity(fSolidity)
|
||||
}
|
||||
|
||||
return r1cs, pk, vk
|
||||
}
|
||||
|
||||
func createProof(plonky2Circuit string) groth16.Proof {
|
||||
func createProof(plonky2Circuit string, r1cs constraint.ConstraintSystem, pk groth16.ProvingKey, vk groth16.VerifyingKey, serialize bool) groth16.Proof {
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs("./verifier/data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
|
||||
// Witness
|
||||
assignment := &BenchmarkPlonky2VerifierCircuit{
|
||||
ProofWithPis: proofWithPis,
|
||||
Proof: proofWithPis.Proof,
|
||||
PublicInputs: proofWithPis.PublicInputs,
|
||||
}
|
||||
|
||||
fmt.Println("Generating witness", time.Now())
|
||||
witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField())
|
||||
publicWitness, _ := witness.Public()
|
||||
|
||||
r1cs := groth16.NewCS(ecc.BN254)
|
||||
fR1CS, _ := os.Open("circuit")
|
||||
r1cs.ReadFrom(fR1CS)
|
||||
fR1CS.Close()
|
||||
|
||||
var pk groth16.ProvingKey
|
||||
fPK, _ := os.Open("proving.key")
|
||||
pk.ReadFrom(fPK)
|
||||
fPK.Close()
|
||||
|
||||
var vk groth16.VerifyingKey
|
||||
fVK, _ := os.Open("verifying.key")
|
||||
vk.ReadFrom(fVK)
|
||||
fVK.Close()
|
||||
|
||||
fmt.Println("Creating proof", time.Now())
|
||||
proof, err := groth16.Prove(r1cs, pk, witness)
|
||||
if err != nil {
|
||||
@@ -123,12 +127,20 @@ func createProof(plonky2Circuit string) groth16.Proof {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if serialize {
|
||||
fProof, _ := os.Create("proof.proof")
|
||||
proof.WriteTo(fProof)
|
||||
}
|
||||
|
||||
return proof
|
||||
}
|
||||
|
||||
func main() {
|
||||
plonky2Circuit := flag.String("plonky2-circuit", "", "plonky2 circuit to benchmark")
|
||||
doProfile := flag.Bool("profile", false, "profile the circuit")
|
||||
profileCircuit := flag.Bool("profile", false, "profile the circuit")
|
||||
serialize := flag.Bool("serialize", false, "serialize the circuit")
|
||||
outputSolidity := flag.Bool("solidity", false, "output solidity code for the circuit")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if plonky2Circuit == nil || *plonky2Circuit == "" {
|
||||
@@ -136,6 +148,6 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
compileCircuit(*plonky2Circuit, *doProfile)
|
||||
createProof(*plonky2Circuit)
|
||||
r1cs, pk, vk := compileCircuit(*plonky2Circuit, *profileCircuit, *serialize, *outputSolidity)
|
||||
createProof(*plonky2Circuit, r1cs, pk, vk, *serialize)
|
||||
}
|
||||
|
||||
@@ -165,12 +165,12 @@ func GoldilocksMulAdd(api frontend.API, operand1, operand2, operand3 frontend.Va
|
||||
|
||||
func GoldilocksMulAddHint(_ *big.Int, inputs []*big.Int, results []*big.Int) error {
|
||||
if len(inputs) != 3 {
|
||||
return fmt.Errorf("GoldilocksMulAddHint expects 3 input operands")
|
||||
panic("GoldilocksMulAddHint expects 3 input operands")
|
||||
}
|
||||
|
||||
for _, operand := range inputs {
|
||||
if operand.Cmp(GOLDILOCKS_MODULUS) >= 0 {
|
||||
return fmt.Errorf("%s is not in the field", operand.String())
|
||||
panic(fmt.Sprintf("%s is not in the field", operand.String()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,10 +184,3 @@ func GoldilocksMulAddHint(_ *big.Int, inputs []*big.Int, results []*big.Int) err
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GoldilocksReduce(api frontend.API, x frontend.Variable) frontend.Variable {
|
||||
// Use gnark's emulated field library.
|
||||
fieldAPI := NewFieldAPI(api)
|
||||
element := fieldAPI.NewElement(x)
|
||||
return fieldAPI.Reduce(element).Limbs[0]
|
||||
}
|
||||
|
||||
2
go.mod
2
go.mod
@@ -27,3 +27,5 @@ require (
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
rsc.io/tmplfunc v0.0.3 // indirect
|
||||
)
|
||||
|
||||
replace github.com/consensys/gnark => /Users/kevin/succinctlabs/gnark
|
||||
|
||||
2
go.sum
2
go.sum
@@ -2,8 +2,6 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM
|
||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
|
||||
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
|
||||
github.com/consensys/gnark v0.8.0 h1:0bQ2MyDG4oNjMQpNyL8HjrrUSSL3yYJg0Elzo6LzmcU=
|
||||
github.com/consensys/gnark v0.8.0/go.mod h1:aKmA7dIiLbTm0OV37xTq0z+Bpe4xER8EhRLi6necrm8=
|
||||
github.com/consensys/gnark-crypto v0.9.1 h1:mru55qKdWl3E035hAoh1jj9d7hVnYY5pfb6tmovSmII=
|
||||
github.com/consensys/gnark-crypto v0.9.1/go.mod h1:a2DQL4+5ywF6safEeZFEPGRiiGbjzGFRUN2sg06VuU4=
|
||||
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
|
||||
@@ -172,12 +172,11 @@ func (c *PoseidonChip) mdsRowShf(r int, v [SPONGE_WIDTH]frontend.Variable) front
|
||||
|
||||
for i := 0; i < 12; i++ {
|
||||
if i < SPONGE_WIDTH {
|
||||
res1 := c.api.Mul(v[(i+r)%SPONGE_WIDTH], MDS_MATRIX_CIRC_VARS[i])
|
||||
res = c.api.Add(res, res1)
|
||||
res = field.GoldilocksMulAdd(c.api, v[(i+r)%SPONGE_WIDTH], MDS_MATRIX_CIRC_VARS[i], res)
|
||||
}
|
||||
}
|
||||
|
||||
res = c.api.Add(res, c.api.Mul(v[r], MDS_MATRIX_DIAG_VARS[r]))
|
||||
res = field.GoldilocksMulAdd(c.api, v[r], MDS_MATRIX_DIAG_VARS[r], res)
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -203,15 +202,9 @@ func (c *PoseidonChip) mdsLayer(state_ PoseidonState) PoseidonState {
|
||||
result[i] = frontend.Variable(0)
|
||||
}
|
||||
|
||||
var state [SPONGE_WIDTH]frontend.Variable
|
||||
for i := 0; i < SPONGE_WIDTH; i++ {
|
||||
state[i] = field.GoldilocksReduce(c.api, state_[i])
|
||||
}
|
||||
|
||||
for r := 0; r < 12; r++ {
|
||||
if r < SPONGE_WIDTH {
|
||||
sum := c.mdsRowShf(r, state)
|
||||
result[r] = field.GoldilocksReduce(c.api, sum)
|
||||
result[r] = c.mdsRowShf(r, state_)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,14 +291,11 @@ func (c *PoseidonChip) mdsPartialLayerFast(state PoseidonState, r int) PoseidonS
|
||||
for i := 1; i < 12; i++ {
|
||||
if i < SPONGE_WIDTH {
|
||||
t := FAST_PARTIAL_ROUND_W_HATS_VARS[r][i-1]
|
||||
reducedState := field.GoldilocksReduce(c.api, state[i])
|
||||
dSum = c.api.Add(dSum, c.api.Mul(reducedState, t))
|
||||
dSum = field.GoldilocksMulAdd(c.api, state[i], t, dSum)
|
||||
}
|
||||
}
|
||||
|
||||
s0 := field.GoldilocksReduce(c.api, state[0])
|
||||
dSum = c.api.Add(dSum, c.api.Mul(s0, MDS0TO0_VAR))
|
||||
d := field.GoldilocksReduce(c.api, dSum)
|
||||
d := field.GoldilocksMulAdd(c.api, state[0], MDS0TO0_VAR, dSum)
|
||||
|
||||
var result PoseidonState
|
||||
for i := 0; i < SPONGE_WIDTH; i++ {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc"
|
||||
"github.com/consensys/gnark/backend"
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/test"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
@@ -58,3 +59,26 @@ func TestPublicInputsHashWitness(t *testing.T) {
|
||||
copy(out[:], utils.StrArrayToFrontendVariableArray(outStr))
|
||||
testCase(in, out)
|
||||
}
|
||||
|
||||
func TestPublicInputsHashWitness2(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
inStr := []string{"0", "1", "3736710860384812976"}
|
||||
outStr := []string{"8416658900775745054", "12574228347150446423", "9629056739760131473", "3119289788404190010"}
|
||||
var in [3]frontend.Variable
|
||||
var out [4]frontend.Variable
|
||||
copy(in[:], utils.StrArrayToFrontendVariableArray(inStr))
|
||||
copy(out[:], utils.StrArrayToFrontendVariableArray(outStr))
|
||||
|
||||
circuit := TestPublicInputsHashCircuit{In: in, Out: out}
|
||||
witness := TestPublicInputsHashCircuit{In: in, Out: out}
|
||||
|
||||
assert.ProverSucceeded(
|
||||
&circuit,
|
||||
&witness,
|
||||
test.WithBackends(backend.GROTH16),
|
||||
test.WithCurves(ecc.BN254),
|
||||
test.NoFuzzing(),
|
||||
test.NoSerialization(),
|
||||
)
|
||||
}
|
||||
|
||||
181
verifier/data/step/common_circuit_data.json
Normal file
181
verifier/data/step/common_circuit_data.json
Normal file
@@ -0,0 +1,181 @@
|
||||
{
|
||||
"config": {
|
||||
"num_wires": 136,
|
||||
"num_routed_wires": 80,
|
||||
"num_constants": 2,
|
||||
"use_base_arithmetic_gate": true,
|
||||
"security_bits": 100,
|
||||
"num_challenges": 2,
|
||||
"zero_knowledge": false,
|
||||
"max_quotient_degree_factor": 8,
|
||||
"fri_config": {
|
||||
"rate_bits": 3,
|
||||
"cap_height": 4,
|
||||
"proof_of_work_bits": 16,
|
||||
"reduction_strategy": {
|
||||
"ConstantArityBits": [
|
||||
4,
|
||||
5
|
||||
]
|
||||
},
|
||||
"num_query_rounds": 28
|
||||
}
|
||||
},
|
||||
"fri_params": {
|
||||
"config": {
|
||||
"rate_bits": 3,
|
||||
"cap_height": 4,
|
||||
"proof_of_work_bits": 16,
|
||||
"reduction_strategy": {
|
||||
"ConstantArityBits": [
|
||||
4,
|
||||
5
|
||||
]
|
||||
},
|
||||
"num_query_rounds": 28
|
||||
},
|
||||
"hiding": false,
|
||||
"degree_bits": 13,
|
||||
"reduction_arity_bits": [
|
||||
4,
|
||||
4
|
||||
]
|
||||
},
|
||||
"gates": [
|
||||
"NoopGate",
|
||||
"PoseidonMdsGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>",
|
||||
"PublicInputGate",
|
||||
"BaseSumGate { num_limbs: 63 } + Base: 2",
|
||||
"ReducingExtensionGate { num_coeffs: 33 }",
|
||||
"ReducingGate { num_coeffs: 44 }",
|
||||
"ArithmeticExtensionGate { num_ops: 10 }",
|
||||
"ArithmeticGate { num_ops: 20 }",
|
||||
"MulExtensionGate { num_ops: 13 }",
|
||||
"ExponentiationGate { num_power_bits: 67, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>",
|
||||
"RandomAccessGate { bits: 4, num_copies: 4, num_extra_constants: 2, _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>",
|
||||
"CosetInterpolationGate { subgroup_bits: 4, degree: 6, barycentric_weights: [17293822565076172801, 18374686475376656385, 18446744069413535745, 281474976645120, 17592186044416, 18446744069414584577, 18446744000695107601, 18446744065119617025, 1152921504338411520, 72057594037927936, 18446744069415632897, 18446462594437939201, 18446726477228539905, 18446744069414584065, 68719476720, 4294967296], _phantom: PhantomData<plonky2_field::goldilocks_field::GoldilocksField> }<D=2>",
|
||||
"PoseidonGate(PhantomData<plonky2_field::goldilocks_field::GoldilocksField>)<WIDTH=12>"
|
||||
],
|
||||
"selectors_info": {
|
||||
"selector_indices": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
3
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"start": 0,
|
||||
"end": 6
|
||||
},
|
||||
{
|
||||
"start": 6,
|
||||
"end": 10
|
||||
},
|
||||
{
|
||||
"start": 10,
|
||||
"end": 12
|
||||
},
|
||||
{
|
||||
"start": 12,
|
||||
"end": 13
|
||||
}
|
||||
]
|
||||
},
|
||||
"quotient_degree_factor": 8,
|
||||
"num_gate_constraints": 123,
|
||||
"num_constants": 6,
|
||||
"num_public_inputs": 1350,
|
||||
"k_is": [
|
||||
1,
|
||||
7,
|
||||
49,
|
||||
343,
|
||||
2401,
|
||||
16807,
|
||||
117649,
|
||||
823543,
|
||||
5764801,
|
||||
40353607,
|
||||
282475249,
|
||||
1977326743,
|
||||
13841287201,
|
||||
96889010407,
|
||||
678223072849,
|
||||
4747561509943,
|
||||
33232930569601,
|
||||
232630513987207,
|
||||
1628413597910449,
|
||||
11398895185373143,
|
||||
79792266297612001,
|
||||
558545864083284007,
|
||||
3909821048582988049,
|
||||
8922003270666332022,
|
||||
7113790686420571191,
|
||||
12903046666114829695,
|
||||
16534350385145470581,
|
||||
5059988279530788141,
|
||||
16973173887300932666,
|
||||
8131752794619022736,
|
||||
1582037354089406189,
|
||||
11074261478625843323,
|
||||
3732854072722565977,
|
||||
7683234439643377518,
|
||||
16889152938674473984,
|
||||
7543606154233811962,
|
||||
15911754940807515092,
|
||||
701820169165099718,
|
||||
4912741184155698026,
|
||||
15942444219675301861,
|
||||
916645121239607101,
|
||||
6416515848677249707,
|
||||
8022122801911579307,
|
||||
814627405137302186,
|
||||
5702391835961115302,
|
||||
3023254712898638472,
|
||||
2716038920875884983,
|
||||
565528376716610560,
|
||||
3958698637016273920,
|
||||
9264146389699333119,
|
||||
9508792519651578870,
|
||||
11221315429317299127,
|
||||
4762231727562756605,
|
||||
14888878023524711914,
|
||||
11988425817600061793,
|
||||
10132004445542095267,
|
||||
15583798910550913906,
|
||||
16852872026783475737,
|
||||
7289639770996824233,
|
||||
14133990258148600989,
|
||||
6704211459967285318,
|
||||
10035992080941828584,
|
||||
14911712358349047125,
|
||||
12148266161370408270,
|
||||
11250886851934520606,
|
||||
4969231685883306958,
|
||||
16337877731768564385,
|
||||
3684679705892444769,
|
||||
7346013871832529062,
|
||||
14528608963998534792,
|
||||
9466542400916821939,
|
||||
10925564598174000610,
|
||||
2691975909559666986,
|
||||
397087297503084581,
|
||||
2779611082521592067,
|
||||
1010533508236560148,
|
||||
7073734557655921036,
|
||||
12622653764762278610,
|
||||
14571600075677612986,
|
||||
9767480182670369297
|
||||
],
|
||||
"num_partial_products": 9
|
||||
}
|
||||
16697
verifier/data/step/proof_with_public_inputs.json
Normal file
16697
verifier/data/step/proof_with_public_inputs.json
Normal file
File diff suppressed because it is too large
Load Diff
21
verifier/data/step/verifier_only_circuit_data.json
Normal file
21
verifier/data/step/verifier_only_circuit_data.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"constants_sigmas_cap": [
|
||||
"16410135397206963995867986152754239948699603273283903389293816335827918317917",
|
||||
"793737431233885020076403438726099627357557537710771017261200370525509120433",
|
||||
"12956281394520952097582330637773878261111274369940411254759688417761804822142",
|
||||
"10577530380775003887407451820221412218265659263471194993014549768898454599785",
|
||||
"13610846379681807478607563401071620391800469867382019709290833315244210704863",
|
||||
"765151448660164966011013501838259753360401123903311092227424737087007538841",
|
||||
"13786717651422653112944870403443265466526140408716569251322854236333823743208",
|
||||
"12716088402533018234480445545939519356897157402541455414075663659898205294136",
|
||||
"7714394992134137076670975536966103814585482420260383440808539140364081464561",
|
||||
"21494844788603743891376885362562637287120172946709821128154824772001032728080",
|
||||
"14153637094178605853060659242981358456456672896438884686797867119060652807634",
|
||||
"8426523842338951741294543051254253278084158527312126154422449980067255373785",
|
||||
"9336152063716553400528035177375603771317196761317425271006398060378250593421",
|
||||
"19032686473689874529303788521545715886983137707759075261782048632012085567581",
|
||||
"15713676428971866339564327334872368460630508652571308740737040859682008007854",
|
||||
"11466448479127530610447443676955276964009242931295623425740153710621884444011"
|
||||
],
|
||||
"circuit_digest": "9787759494185596126611266365248694578977961103378519017707766709237231108177"
|
||||
}
|
||||
@@ -24,7 +24,7 @@ func (circuit *TestPlonkCircuit) Define(api frontend.API) error {
|
||||
|
||||
verifierChip := verifier.NewVerifierChip(api, commonCircuitData)
|
||||
publicInputsHash := verifierChip.GetPublicInputsHash(proofWithPis.PublicInputs)
|
||||
proofChallenges := verifierChip.GetChallenges(proofWithPis, publicInputsHash, commonCircuitData, verifierOnlyCircuitData)
|
||||
proofChallenges := verifierChip.GetChallenges(proofWithPis.Proof, publicInputsHash, commonCircuitData, verifierOnlyCircuitData)
|
||||
|
||||
fieldAPI := field.NewFieldAPI(api)
|
||||
qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI)
|
||||
|
||||
@@ -47,7 +47,7 @@ func (c *VerifierChip) GetPublicInputsHash(publicInputs []field.F) poseidon.Pose
|
||||
}
|
||||
|
||||
func (c *VerifierChip) GetChallenges(
|
||||
proofWithPis common.ProofWithPublicInputs,
|
||||
proof common.Proof,
|
||||
publicInputsHash poseidon.PoseidonHashOut,
|
||||
commonData common.CommonCircuitData,
|
||||
verifierData common.VerifierOnlyCircuitData,
|
||||
@@ -60,17 +60,17 @@ func (c *VerifierChip) GetChallenges(
|
||||
|
||||
challenger.ObserveBN128Hash(circuitDigest)
|
||||
challenger.ObserveHash(publicInputsHash)
|
||||
challenger.ObserveCap(proofWithPis.Proof.WiresCap)
|
||||
challenger.ObserveCap(proof.WiresCap)
|
||||
plonkBetas := challenger.GetNChallenges(numChallenges)
|
||||
plonkGammas := challenger.GetNChallenges(numChallenges)
|
||||
|
||||
challenger.ObserveCap(proofWithPis.Proof.PlonkZsPartialProductsCap)
|
||||
challenger.ObserveCap(proof.PlonkZsPartialProductsCap)
|
||||
plonkAlphas := challenger.GetNChallenges(numChallenges)
|
||||
|
||||
challenger.ObserveCap(proofWithPis.Proof.QuotientPolysCap)
|
||||
challenger.ObserveCap(proof.QuotientPolysCap)
|
||||
plonkZeta := challenger.GetExtensionChallenge()
|
||||
|
||||
challenger.ObserveOpenings(fri.ToFriOpenings(proofWithPis.Proof.Openings))
|
||||
challenger.ObserveOpenings(fri.ToFriOpenings(proof.Openings))
|
||||
|
||||
return common.ProofChallenges{
|
||||
PlonkBetas: plonkBetas,
|
||||
@@ -78,9 +78,9 @@ func (c *VerifierChip) GetChallenges(
|
||||
PlonkAlphas: plonkAlphas,
|
||||
PlonkZeta: plonkZeta,
|
||||
FriChallenges: challenger.GetFriChallenges(
|
||||
proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
|
||||
proofWithPis.Proof.OpeningProof.FinalPoly,
|
||||
proofWithPis.Proof.OpeningProof.PowWitness,
|
||||
proof.OpeningProof.CommitPhaseMerkleCaps,
|
||||
proof.OpeningProof.FinalPoly,
|
||||
proof.OpeningProof.PowWitness,
|
||||
commonData.DegreeBits,
|
||||
config.FriConfig,
|
||||
),
|
||||
@@ -154,18 +154,20 @@ func (c *VerifierChip) generateProofInput(commonData common.CommonCircuitData) c
|
||||
}
|
||||
*/
|
||||
|
||||
func (c *VerifierChip) Verify(proofWithPis common.ProofWithPublicInputs, verifierData common.VerifierOnlyCircuitData, commonData common.CommonCircuitData) {
|
||||
// Generate the parts of the witness that is for the plonky2 proof input
|
||||
publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs)
|
||||
proofChallenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData, verifierData)
|
||||
func (c *VerifierChip) Verify(proof common.Proof, publicInputs []field.F, verifierData common.VerifierOnlyCircuitData, commonData common.CommonCircuitData) {
|
||||
// TODO: Need to range check all the proof and public input elements to make sure they are within goldilocks field
|
||||
|
||||
c.plonkChip.Verify(proofChallenges, proofWithPis.Proof.Openings, publicInputsHash)
|
||||
// Generate the parts of the witness that is for the plonky2 proof input
|
||||
publicInputsHash := c.GetPublicInputsHash(publicInputs)
|
||||
proofChallenges := c.GetChallenges(proof, publicInputsHash, commonData, verifierData)
|
||||
|
||||
c.plonkChip.Verify(proofChallenges, proof.Openings, publicInputsHash)
|
||||
|
||||
initialMerkleCaps := []common.MerkleCap{
|
||||
verifierData.ConstantSigmasCap,
|
||||
proofWithPis.Proof.WiresCap,
|
||||
proofWithPis.Proof.PlonkZsPartialProductsCap,
|
||||
proofWithPis.Proof.QuotientPolysCap,
|
||||
proof.WiresCap,
|
||||
proof.PlonkZsPartialProductsCap,
|
||||
proof.QuotientPolysCap,
|
||||
}
|
||||
|
||||
// Seems like there is a bug in the emulated field code.
|
||||
@@ -189,9 +191,9 @@ func (c *VerifierChip) Verify(proofWithPis common.ProofWithPublicInputs, verifie
|
||||
|
||||
c.friChip.VerifyFriProof(
|
||||
fri.GetFriInstance(&commonData, c.qeAPI, proofChallenges.PlonkZeta, commonData.DegreeBits),
|
||||
fri.ToFriOpenings(proofWithPis.Proof.Openings),
|
||||
fri.ToFriOpenings(proof.Openings),
|
||||
&proofChallenges.FriChallenges,
|
||||
initialMerkleCaps,
|
||||
&proofWithPis.Proof.OpeningProof,
|
||||
&proof.OpeningProof,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,42 +3,121 @@ package verifier_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark-crypto/ecc"
|
||||
"github.com/consensys/gnark/backend"
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/std/math/emulated"
|
||||
"github.com/consensys/gnark/test"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/field"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
|
||||
"github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
|
||||
)
|
||||
|
||||
type TestVerifierCircuit struct {
|
||||
proofWithPIsFilename string `gnark:"-"`
|
||||
commonCircuitDataFilename string `gnark:"-"`
|
||||
verifierOnlyCircuitDataFilename string `gnark:"-"`
|
||||
Proof common.Proof
|
||||
PublicInputs []field.F `gnark:",public"`
|
||||
|
||||
verifierChip *verifier.VerifierChip `gnark:"-"`
|
||||
plonky2CircuitName string `gnark:"-"`
|
||||
}
|
||||
|
||||
func (c *TestVerifierCircuit) Define(api frontend.API) error {
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs(c.proofWithPIsFilename)
|
||||
commonCircuitData := utils.DeserializeCommonCircuitData(c.commonCircuitDataFilename)
|
||||
verfierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(c.verifierOnlyCircuitDataFilename)
|
||||
circuitDirname := "./data/" + c.plonky2CircuitName + "/"
|
||||
commonCircuitData := utils.DeserializeCommonCircuitData(circuitDirname + "common_circuit_data.json")
|
||||
verifierOnlyCircuitData := utils.DeserializeVerifierOnlyCircuitData(circuitDirname + "verifier_only_circuit_data.json")
|
||||
|
||||
c.verifierChip = verifier.NewVerifierChip(api, commonCircuitData)
|
||||
|
||||
c.verifierChip.Verify(c.Proof, c.PublicInputs, verifierOnlyCircuitData, commonCircuitData)
|
||||
|
||||
verifierChip := verifier.NewVerifierChip(api, commonCircuitData)
|
||||
verifierChip.Verify(proofWithPis, verfierOnlyCircuitData, commonCircuitData)
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestDecodeBlockVerifier(t *testing.T) {
|
||||
func TestStepVerifier(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func() {
|
||||
plonky2Circuit := "step"
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
circuit := TestVerifierCircuit{
|
||||
proofWithPIsFilename: "./data/decode_block/proof_with_public_inputs.json",
|
||||
commonCircuitDataFilename: "./data/decode_block/common_circuit_data.json",
|
||||
verifierOnlyCircuitDataFilename: "./data/decode_block/verifier_only_circuit_data.json",
|
||||
plonky2CircuitName: plonky2Circuit,
|
||||
Proof: proofWithPis.Proof,
|
||||
PublicInputs: proofWithPis.PublicInputs,
|
||||
}
|
||||
|
||||
proofWithPis2 := utils.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
witness := TestVerifierCircuit{
|
||||
plonky2CircuitName: plonky2Circuit,
|
||||
Proof: proofWithPis2.Proof,
|
||||
PublicInputs: proofWithPis2.PublicInputs,
|
||||
}
|
||||
|
||||
witness := TestVerifierCircuit{}
|
||||
err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
testCase()
|
||||
}
|
||||
|
||||
func TestStepVerifier2(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
plonky2Circuit := "step"
|
||||
proofWithPis := utils.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
circuit := TestVerifierCircuit{
|
||||
plonky2CircuitName: plonky2Circuit,
|
||||
Proof: proofWithPis.Proof,
|
||||
PublicInputs: proofWithPis.PublicInputs,
|
||||
}
|
||||
|
||||
proofWithPis2 := utils.DeserializeProofWithPublicInputs("./data/" + plonky2Circuit + "/proof_with_public_inputs.json")
|
||||
witness := TestVerifierCircuit{
|
||||
plonky2CircuitName: plonky2Circuit,
|
||||
Proof: proofWithPis2.Proof,
|
||||
PublicInputs: proofWithPis2.PublicInputs,
|
||||
}
|
||||
|
||||
assert.ProverSucceeded(
|
||||
&circuit,
|
||||
&witness,
|
||||
test.WithBackends(backend.GROTH16),
|
||||
test.WithCurves(ecc.BN254),
|
||||
test.NoFuzzing(),
|
||||
test.NoSerialization(),
|
||||
)
|
||||
}
|
||||
|
||||
type testCircuit struct {
|
||||
Arr [2]emulated.Element[emulated.Secp256k1Fp]
|
||||
Expected emulated.Element[emulated.Secp256k1Fp]
|
||||
}
|
||||
|
||||
func (circuit *testCircuit) Define(api frontend.API) error {
|
||||
field, _ := emulated.NewField[emulated.Secp256k1Fp](api)
|
||||
|
||||
mulRes := field.Mul(&circuit.Arr[0], &circuit.Arr[1])
|
||||
field.AssertIsEqual(mulRes, &circuit.Expected)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestMain(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
var circuit testCircuit
|
||||
|
||||
assert.ProverSucceeded(
|
||||
&circuit,
|
||||
&testCircuit{
|
||||
Arr: [2]emulated.Element[emulated.Secp256k1Fp]{
|
||||
emulated.ValueOf[emulated.Secp256k1Fp](42),
|
||||
emulated.ValueOf[emulated.Secp256k1Fp](24),
|
||||
},
|
||||
Expected: emulated.ValueOf[emulated.Secp256k1Fp](1008),
|
||||
},
|
||||
test.WithBackends(backend.GROTH16),
|
||||
test.WithCurves(ecc.BN254),
|
||||
test.NoFuzzing(),
|
||||
test.NoSerialization(),
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user