arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
gnark-plonky2-verifier/poseidon/poseidon_test.go
poseidon/poseidon_test.goRaw
  1package poseidon
  2
  3import (
  4	. "gnark-ed25519/goldilocks"
  5	"math/big"
  6	"testing"
  7
  8	"github.com/consensys/gnark-crypto/ecc"
  9	"github.com/consensys/gnark/backend/groth16"
 10	"github.com/consensys/gnark/frontend"
 11	"github.com/consensys/gnark/frontend/cs/r1cs"
 12	"github.com/consensys/gnark/test"
 13)
 14
 15var testCurve = ecc.BN254
 16
 17type TestPoseidonCircuit struct {
 18	In  [12]frontend.Variable
 19	Out [12]frontend.Variable
 20}
 21
 22func (circuit *TestPoseidonCircuit) Define(api frontend.API) error {
 23	goldilocksApi := NewGoldilocksAPI(api)
 24
 25	// BN254 -> Binary(64) -> GoldilocksElement
 26	var input PoseidonState
 27	for i := 0; i < 12; i++ {
 28		input[i] = goldilocksApi.FromBinary(api.ToBinary(circuit.In[i], 64)).(GoldilocksElement)
 29	}
 30
 31	output := Poseidon(api, goldilocksApi, input)
 32
 33	// Check that output is correct
 34	for i := 0; i < 12; i++ {
 35		goldilocksApi.AssertIsEqual(
 36			output[i],
 37			goldilocksApi.FromBinary(api.ToBinary(circuit.Out[i])).(GoldilocksElement),
 38		)
 39	}
 40
 41	return nil
 42}
 43
 44func TestPoseidonWitness(t *testing.T) {
 45	assert := test.NewAssert(t)
 46
 47	testCase := func(inBigInt [12]big.Int, outBigInt [12]big.Int) {
 48		var in [12]frontend.Variable
 49		var out [12]frontend.Variable
 50
 51		for i := 0; i < 12; i++ {
 52			in[i] = inBigInt[i]
 53			out[i] = outBigInt[i]
 54		}
 55
 56		circuit := TestPoseidonCircuit{In: in, Out: out}
 57		witness := TestPoseidonCircuit{In: in, Out: out}
 58		err := test.IsSolved(&circuit, &witness, testCurve.ScalarField())
 59		assert.NoError(err)
 60	}
 61
 62	inStr := [12]string{"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"}
 63	outStr := [12]string{
 64		"4330397376401421145", "14124799381142128323", "8742572140681234676",
 65		"14345658006221440202", "15524073338516903644", "5091405722150716653",
 66		"15002163819607624508", "2047012902665707362", "16106391063450633726",
 67		"4680844749859802542", "15019775476387350140", "1698615465718385111",
 68	}
 69
 70	var inBigInt [12]big.Int
 71	var outBigInt [12]big.Int
 72
 73	for i := 0; i < 12; i++ {
 74		inTmp := new(big.Int)
 75		inTmp, _ = inTmp.SetString(inStr[i], 10)
 76		inBigInt[i] = *inTmp
 77
 78		outTmp := new(big.Int)
 79		outTmp, _ = outTmp.SetString(outStr[i], 10)
 80		outBigInt[i] = *outTmp
 81	}
 82
 83	testCase(inBigInt, outBigInt)
 84}
 85
 86func TestPoseidonProof(t *testing.T) {
 87	inStr := [12]string{"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"}
 88	outStr := [12]string{
 89		"4330397376401421145", "14124799381142128323", "8742572140681234676",
 90		"14345658006221440202", "15524073338516903644", "5091405722150716653",
 91		"15002163819607624508", "2047012902665707362", "16106391063450633726",
 92		"4680844749859802542", "15019775476387350140", "1698615465718385111",
 93	}
 94
 95	var in [12]frontend.Variable
 96	var out [12]frontend.Variable
 97
 98	for i := 0; i < 12; i++ {
 99		inTmp := new(big.Int)
100		inTmp, _ = inTmp.SetString(inStr[i], 10)
101		in[i] = *inTmp
102
103		outTmp := new(big.Int)
104		outTmp, _ = outTmp.SetString(outStr[i], 10)
105		out[i] = *outTmp
106	}
107
108	circuit := TestPoseidonCircuit{In: in, Out: out}
109	assignment := TestPoseidonCircuit{In: in, Out: out}
110
111	r1cs, err := frontend.Compile(testCurve.ScalarField(), r1cs.NewBuilder, &circuit)
112	if err != nil {
113		panic(err)
114	}
115
116	witness, err := frontend.NewWitness(&assignment, testCurve.ScalarField())
117	if err != nil {
118		panic(err)
119	}
120
121	pk, vk, err := groth16.Setup(r1cs)
122	if err != nil {
123		panic(err)
124	}
125
126	err = test.IsSolved(&circuit, &assignment, testCurve.ScalarField())
127	if err != nil {
128		panic(err)
129	}
130
131	proof, err := groth16.Prove(r1cs, pk, witness)
132	if err != nil {
133		panic(err)
134	}
135
136	publicWitness, err := witness.Public()
137	if err != nil {
138		panic(err)
139	}
140
141	err = groth16.Verify(proof, vk, publicWitness)
142	if err != nil {
143		panic(err)
144	}
145}