gnark-plonky2-verifier/poseidon/poseidon_test.go
poseidon/poseidon_test.goRaw
1package poseidon
2
3import (
4 "testing"
5
6 "github.com/consensys/gnark/backend/groth16"
7 "github.com/consensys/gnark/frontend"
8 "github.com/consensys/gnark/frontend/cs/r1cs"
9 "github.com/consensys/gnark/test"
10 "github.com/succinctlabs/gnark-plonky2-verifier/field"
11 "github.com/succinctlabs/gnark-plonky2-verifier/utils"
12)
13
14type TestPoseidonCircuit struct {
15 In [12]frontend.Variable
16 Out [12]frontend.Variable
17}
18
19func (circuit *TestPoseidonCircuit) Define(api frontend.API) error {
20 goldilocksApi := field.NewFieldAPI(api)
21 qeAPI := field.NewQuadraticExtensionAPI(api, goldilocksApi, 3)
22
23 var input PoseidonState
24 for i := 0; i < 12; i++ {
25 input[i] = goldilocksApi.FromBits(api.ToBinary(circuit.In[i], 64)...)
26 }
27
28 poseidonChip := NewPoseidonChip(api, goldilocksApi, qeAPI)
29 output := poseidonChip.Poseidon(input)
30
31 for i := 0; i < 12; i++ {
32 goldilocksApi.AssertIsEqual(
33 output[i],
34 goldilocksApi.FromBits(api.ToBinary(circuit.Out[i])...),
35 )
36 }
37
38 return nil
39}
40
41func TestPoseidonWitness(t *testing.T) {
42 assert := test.NewAssert(t)
43
44 testCase := func(in [12]frontend.Variable, out [12]frontend.Variable) {
45 circuit := TestPoseidonCircuit{In: in, Out: out}
46 witness := TestPoseidonCircuit{In: in, Out: out}
47 err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
48 assert.NoError(err)
49 }
50
51 inStr := []string{"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"}
52 outStr := []string{
53 "4330397376401421145", "14124799381142128323", "8742572140681234676",
54 "14345658006221440202", "15524073338516903644", "5091405722150716653",
55 "15002163819607624508", "2047012902665707362", "16106391063450633726",
56 "4680844749859802542", "15019775476387350140", "1698615465718385111",
57 }
58 var in [12]frontend.Variable
59 var out [12]frontend.Variable
60 copy(in[:], utils.StrArrayToFrontendVariableArray(inStr))
61 copy(out[:], utils.StrArrayToFrontendVariableArray(outStr))
62 testCase(in, out)
63}
64
65func TestPoseidonProof(t *testing.T) {
66 inStr := []string{"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"}
67 outStr := []string{
68 "4330397376401421145", "14124799381142128323", "8742572140681234676",
69 "14345658006221440202", "15524073338516903644", "5091405722150716653",
70 "15002163819607624508", "2047012902665707362", "16106391063450633726",
71 "4680844749859802542", "15019775476387350140", "1698615465718385111",
72 }
73 var in [12]frontend.Variable
74 var out [12]frontend.Variable
75 copy(in[:], utils.StrArrayToFrontendVariableArray(inStr))
76 copy(out[:], utils.StrArrayToFrontendVariableArray(outStr))
77
78 circuit := TestPoseidonCircuit{In: in, Out: out}
79 assignment := TestPoseidonCircuit{In: in, Out: out}
80
81 r1cs, err := frontend.Compile(field.TEST_CURVE.ScalarField(), r1cs.NewBuilder, &circuit)
82 if err != nil {
83 panic(err)
84 }
85
86 witness, err := frontend.NewWitness(&assignment, field.TEST_CURVE.ScalarField())
87 if err != nil {
88 panic(err)
89 }
90
91 pk, vk, err := groth16.Setup(r1cs)
92 if err != nil {
93 panic(err)
94 }
95
96 err = test.IsSolved(&circuit, &assignment, field.TEST_CURVE.ScalarField())
97 if err != nil {
98 panic(err)
99 }
100
101 proof, err := groth16.Prove(r1cs, pk, witness)
102 if err != nil {
103 panic(err)
104 }
105
106 publicWitness, err := witness.Public()
107 if err != nil {
108 panic(err)
109 }
110
111 err = groth16.Verify(proof, vk, publicWitness)
112 if err != nil {
113 panic(err)
114 }
115}