-
how to use gnark v0.8.0 and gnark v.0.9.1 to make a MIMC verification?
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
cc @Tabaie |
Beta Was this translation helpful? Give feedback.
-
Hi @YurunChen! When you call 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"
"os"
"testing"
)
type Circuit struct {
PreImage frontend.Variable
Hash frontend.Variable `gnark:",public"`
}
func (circuit *Circuit) Define(api frontend.API) error {
api.Println(circuit.PreImage)
api.Println(circuit.Hash)
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()
f.Write(data)
hash := f.Sum(nil)
if len(hash) < 32 {
padding := make([]byte, 32-len(hash))
hash = append(hash, padding...)
}
hashInt := big.NewInt(0).SetBytes(hash)
return hashInt.String()
}
func main() {
preImage := []byte{0x01, 0x02, 0x03}
b := make([]byte, 32)
copy(b, preImage)
fmt.Println(b)
hash := mimcHash(b)
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
}
//vk.ExportSolidity(f)
assignment := &Circuit{
PreImage: frontend.Variable(b),
Hash: frontend.Variable(hash),
}
witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField())
proof, err := groth16.Prove(r1cs, pk, witness)
if err != nil {
fmt.Printf("Prove failed: %v\n", err)
return
}
// <CHANGE>
publicWitness, err := witness.Public()
if err != nil {
fmt.Printf("failed to extract public component: %v\n", err)
os.Exit(-1)
}
// </CHANGE>
error := groth16.Verify(proof, vk, publicWitness)
fmt.Println(error)
//if error != nil {
// fmt.Printf("verification failed: %v\n", err)
// return
//}
//fmt.Printf("verification succeded\n")
} the program runs successfully. |
Beta Was this translation helpful? Give feedback.
Hi @YurunChen!
When you call
frontend.NewWitness()
without any options, it expects a fully-assigned prover-side circuit. In that case you can extract the public component from the full witness.Alternatively you can use the option
frontend.PublicOnly()
as infrontend.NewWitness(circuit, frontend.PublicOnly())
. So for example if you modify your code slightly to get: