Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add groth16 commitment verifier #2

Merged
merged 4 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")
}