how to use gnark v0.8.0 to do MIMC verification?

298 views Asked by At

Can anyone tell me how to do MIMC verification with gnark v0.8.0 and gnark-crypto v0.9.1? my code as fllow

package main

import (
 "fmt"
 "github.com/consensys/gnark-crypto/ecc"
 bn254 "github.com/consensys/gnark-crypto/ecc/bn254/fr/mimc"
 "github.com/consensys/gnark/backend/groth16"
 "github.com/consensys/gnark/frontend"
 r1cs2 "github.com/consensys/gnark/frontend/cs/r1cs"
 "github.com/consensys/gnark/std/hash/mimc"
 "math/big"
)

type Circuit struct {
 PreImage frontend.Variable
 Hash     frontend.Variable `gnark:",public"`
}

func (circuit *Circuit) Define(api frontend.API) error {
 api.Println(circuit.Hash)
 api.Println(circuit.PreImage)
 mimc, _ := mimc.NewMiMC(api)
 mimc.Write(circuit.PreImage)
 api.Println(mimc.Sum())
 api.AssertIsEqual(circuit.Hash, mimc.Sum())
 return nil
}

func mimcHash(data []byte) string {
 f := bn254.NewMiMC()
 hash := f.Sum(data)
 hashInt := big.NewInt(0).SetBytes(hash)
 return hashInt.String()
}

func main() {
 preImage := []byte("1")
 fmt.Println(preImage)
 hash := mimcHash(preImage)

 fmt.Println(preImage)

 fmt.Printf("hash: %s\n", hash)

 var circuit Circuit

 r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs2.NewBuilder, &circuit)
 if err != nil {
  fmt.Printf("Compile failed : %v\n", err)
  return
 }

 pk, vk, err := groth16.Setup(r1cs)
 if err != nil {
  fmt.Printf("Setup failed\n")
  return
 }

 assignment := &Circuit{
  PreImage: frontend.Variable(preImage),
  Hash:     frontend.Variable(hash),
 }
 fmt.Println("assignment.Hash", assignment.Hash)

 witness, err := frontend.NewWitness(assignment, ecc.BN254.ScalarField())
 proof, err := groth16.Prove(r1cs, pk, witness)
 if err != nil {
  fmt.Printf("Prove failed: %v\n", err)
  return
 }

 publicAssignment := &Circuit{
  Hash: frontend.Variable(hash),
 }
 fmt.Println(hash)

 publicWitness, err := frontend.NewWitness(publicAssignment, ecc.BN254.ScalarField())
 err = groth16.Verify(proof, vk, publicWitness)
 if err != nil {
  fmt.Printf("verification failed: %v\n", err)
  return
 }
 fmt.Printf("verification succeded\n")
}

it always return a wrong verification, I don't know the reason. The reason for this seems to be that the value of the hash changes after it is passed into the Define function.If possible, please tell me the answer.

hash: 5673812372628493575754978265425707484810229248616387637933421616387743352356864
04:08:31 INF compiling circuit
04:08:31 INF parsed circuit inputs nbPublic=1 nbSecret=1
04:08:31 INF building constraint builder nbConstraints=331
04:08:31 ERR error="unsatisfied constraint" backend=groth16 id=330 nbConstraints=331
Prove failed: constraint #330 is not satisfied: [assertIsEqual] 4757468822121293193159177404073236876202868908634742915586732064608951992061 == 21518545289977633059516571167495097594845616311010087326595465475420112732966
r1cs.(*builder).AssertIsEqual
        api_assertions.go:35
main.(*Circuit).Define
        test.go:22
1

There are 1 answers

0
Shreyas Londhe On

You are hashing it twice - once in the println and then in assert statement. Try storing the hash and then check the assert statement.