Skip to content

Commit

Permalink
feat: add groth16 commitment verifier (#2)
Browse files Browse the repository at this point in the history
* feat: add groth16 commitment verifier

* remove --via-ir after optimizations

* refactor: merge commit/no-commit Groth16 templates

* chore: update template go.mod

---------

Co-authored-by: Ivo Kubjas <ivo.kubjas@consensys.net>
  • Loading branch information
ahmetyalp and ivokub authored Apr 3, 2024
1 parent d99fab9 commit a818a0d
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 15 deletions.
40 changes: 38 additions & 2 deletions cmd/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ func main() {
proofBytes, err := hex.DecodeString(proofHex)
checkErr(err, "decode proof hex failed")
{{ if eq .NbCommitments 0 }}
if len(proofBytes) != fpSize*8 {
panic("proofBytes != fpSize*8")
}
{{ end }}
inputBytes, err := hex.DecodeString(inputHex)
checkErr(err, "decode input hex failed")
Expand Down Expand Up @@ -75,6 +77,7 @@ func main() {
proof[i] = new(big.Int).SetBytes(proofBytes[fpSize*i : fpSize*(i+1)])
}
{{ if eq .NbCommitments 0 }}
// call the contract
err = verifierContract.VerifyProof(&bind.CallOpts{}, proof, input)
checkErr(err, "calling verifier on chain gave error")
Expand All @@ -86,6 +89,39 @@ func main() {
// verify compressed proof
err = verifierContract.VerifyCompressedProof(&bind.CallOpts{}, proofCompressed, input)
checkErr(err, "calling verifier with compressed proof on chain gave error")
{{ else }}
// prepare commitments for calling
c := new(big.Int).SetBytes(proofBytes[fpSize*8 : fpSize*8+4])
commitmentCount := int(c.Int64())
if commitmentCount != {{ .NbCommitments }} {
panic("commitmentCount != .NbCommitments")
}
var commitments [{{mul 2 .NbCommitments}}]*big.Int
var commitmentPok [2]*big.Int
// commitments
for i := 0; i < 2*commitmentCount; i++ {
commitments[i] = new(big.Int).SetBytes(proofBytes[fpSize*8+4+i*fpSize : fpSize*8+4+(i+1)*fpSize])
}
// commitmentPok
commitmentPok[0] = new(big.Int).SetBytes(proofBytes[fpSize*8+4+2*commitmentCount*fpSize : fpSize*8+4+2*commitmentCount*fpSize+fpSize])
commitmentPok[1] = new(big.Int).SetBytes(proofBytes[fpSize*8+4+2*commitmentCount*fpSize+fpSize : fpSize*8+4+2*commitmentCount*fpSize+2*fpSize])
// call the contract
err = verifierContract.VerifyProof(&bind.CallOpts{}, proof, commitments, commitmentPok, input)
checkErr(err, "calling verifier on chain gave error")
// compress proof
compressed, err := verifierContract.CompressProof(&bind.CallOpts{}, proof, commitments, commitmentPok)
checkErr(err, "compressing proof gave error")
// verify compressed proof
err = verifierContract.VerifyCompressedProof(&bind.CallOpts{}, compressed.Compressed, compressed.CompressedCommitments, compressed.CompressedCommitmentPok, input)
checkErr(err, "calling verifier with compressed proof on chain gave error")
{{ end }}
}
func checkErr(err error, ctx string) {
Expand Down Expand Up @@ -188,8 +224,8 @@ const tmplGoMod = `module tmpsolidity
go 1.20
require (
github.com/consensys/gnark v0.7.2-0.20230620210714-0713c1dc4def
github.com/consensys/gnark-crypto v0.11.1-0.20230609175512-0ee617fa6d43
github.com/consensys/gnark v0.9.2-0.20240401222041-3b3c1e89a35f
github.com/consensys/gnark-crypto v0.12.2-0.20240215234832-d72fcb379d3e
github.com/ethereum/go-ethereum v1.12.0
)
Expand Down
37 changes: 24 additions & 13 deletions cmd/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var (
fNbPublicInputs int // number of public inputs
fGroth16 bool
fPlonK bool
fNbCommitments int // number of commitments
)

// verifyCmd represents the verify command
Expand All @@ -36,20 +37,20 @@ func runVerify(cmd *cobra.Command, args []string) {
os.Exit(1)
}

if fGroth16 {
if err := generateMain(tmplGroth16, filepath.Join(fBaseDir, "main.go"), fProof, fPublicInputs, fNbPublicInputs); err != nil {
fmt.Println(err)
os.Exit(1)
}
} else if fPlonK {
if err := generateMain(tmplPlonK, filepath.Join(fBaseDir, "main.go"), fProof, fPublicInputs, fNbPublicInputs); err != nil {
fmt.Println(err)
os.Exit(1)
}
} else {
var tmpl string
switch {
case fGroth16:
tmpl = tmplGroth16
case fPlonK:
tmpl = tmplPlonK
default:
fmt.Println("please specify either --groth16 or --plonk")
os.Exit(1)
}
if err := generateMain(tmpl, filepath.Join(fBaseDir, "main.go"), fProof, fPublicInputs, fNbPublicInputs, fNbCommitments); err != nil {
fmt.Println(err)
os.Exit(1)
}

// generate go.mod file
if err := generateGoMod(filepath.Join(fBaseDir, "go.mod")); err != nil {
Expand Down Expand Up @@ -97,7 +98,7 @@ func generateGoMod(filename string) error {
return tmpl.Execute(f, nil)
}

func generateMain(tmplStr, filename, proof, publicInputs string, nbPublicInputs int) error {
func generateMain(tmplStr, filename, proof, publicInputs string, nbPublicInputs, fNbCommitments int) error {
fmt.Println("generating " + filename)
f, err := os.Create(filename)
if err != nil {
Expand All @@ -106,7 +107,13 @@ func generateMain(tmplStr, filename, proof, publicInputs string, nbPublicInputs
}
defer f.Close()

tmpl, err := template.New("").Parse(tmplStr)
helpers := template.FuncMap{
"mul": func(a, b int) int {
return a * b
},
}

tmpl, err := template.New("").Funcs(helpers).Parse(tmplStr)
if err != nil {
return err
}
Expand All @@ -115,10 +122,12 @@ func generateMain(tmplStr, filename, proof, publicInputs string, nbPublicInputs
Proof string
PublicInputs string
NbPublicInputs int
NbCommitments int
}{
Proof: proof,
PublicInputs: publicInputs,
NbPublicInputs: nbPublicInputs,
NbCommitments: fNbCommitments,
}

// execute template
Expand All @@ -141,4 +150,6 @@ func init() {
verifyCmd.Flags().BoolVar(&fPlonK, "plonk", false, "use plonk verification")

verifyCmd.MarkFlagsMutuallyExclusive("groth16", "plonk")

verifyCmd.Flags().IntVar(&fNbCommitments, "commitment", 0, "number of commitments in proof")
}

0 comments on commit a818a0d

Please sign in to comment.