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

Plonk backend #31

Open
wants to merge 47 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
b7dd73a
add poseidon2 goldilocks
utkarsh-21st Dec 17, 2023
34afaf3
optimize reduction
utkarsh-21st Jan 9, 2024
736ad0c
add goldilocks algebra extension
utkarsh-21st Dec 18, 2023
444d3ec
fix goldilocks algebra
utkarsh-21st Dec 19, 2023
72d12ad
add arithmetic extension gate
utkarsh-21st Dec 19, 2023
91789c6
fix reduce bits in arithmetic gate
utkarsh-21st Dec 20, 2023
f511e43
add some goldilocks functions
utkarsh-21st Dec 21, 2023
ad75b9f
fix reduce bits in arithmetic extension
utkarsh-21st Dec 25, 2023
17591c6
refactor
utkarsh-21st Jan 9, 2024
c3f3874
optimize algebra; reevaluate bits in a in arithmetic extension gate
utkarsh-21st Jan 9, 2024
752d861
fix reduction bits
utkarsh-21st Jan 9, 2024
3bf5ef0
add coset interpolation gate
utkarsh-21st Dec 21, 2023
cb0386b
reve function export
utkarsh-21st Dec 22, 2023
a9a8bbe
fix reduce bits
utkarsh-21st Dec 26, 2023
9130252
refactor CosetInteroplationGate
utkarsh-21st Dec 26, 2023
77872e3
fix reduction bits in coset interpolation gate
utkarsh-21st Jan 20, 2024
d9855fa
add base_sum gate
utkarsh-21st Dec 24, 2023
fc5c9f0
add exponentiation gate
utkarsh-21st Dec 24, 2023
d1488e6
fix reduction in exponentiation
utkarsh-21st Jan 21, 2024
0a6caa9
add lookup gate
utkarsh-21st Dec 25, 2023
0214f40
add lookup_table gate
utkarsh-21st Dec 25, 2023
b7c2a03
add multiplication extension gate
utkarsh-21st Dec 25, 2023
7c38bc7
fix reduction bits in MulExtension gate
utkarsh-21st Jan 21, 2024
777ed6e
add noop gate
utkarsh-21st Dec 25, 2023
7aa8d7a
add random access gate
utkarsh-21st Dec 26, 2023
90bcf9b
fix reduction bits in ranom access gate
utkarsh-21st Jan 21, 2024
fc1a02a
add reducing gate
utkarsh-21st Dec 26, 2023
280e884
add reducing extension gate
utkarsh-21st Dec 26, 2023
b95016c
add poseidon mds gate
utkarsh-21st Dec 26, 2023
4308005
add u32 comparison gate
utkarsh-21st Jan 5, 2024
517a9ef
add U32AddManyGate
utkarsh-21st Jan 5, 2024
3cacfc0
add U32ArithmeticGate
utkarsh-21st Jan 7, 2024
2ccd438
fix SelectHashOutRecursive and SelectGoldilocksExt2Recursive
utkarsh-21st Jan 8, 2024
0a4a426
script to export solidity verifier
utkarsh-21st Jan 8, 2024
89ef7cb
add poseidon bn254 hash
utkarsh-21st Jan 11, 2024
afee10b
refactor poseidon
utkarsh-21st Jan 11, 2024
5c8d1e1
add poseidon bn254 hasher
utkarsh-21st Jan 11, 2024
c6d431c
fix goldilocks elements to bn254 conversion
utkarsh-21st Jan 12, 2024
32724a7
integrate poseidon bn254 hasher
utkarsh-21st Jan 14, 2024
79a705b
fix PoseidonBn254HashOut ToVec function
utkarsh-21st Jan 16, 2024
0e97f7b
add plonk backend scripts
utkarsh-21st Jan 21, 2024
fa5d188
update fri test
utkarsh-21st Jan 21, 2024
26f700d
some fixes
utkarsh-21st Jan 21, 2024
328fd64
add U32Interleave gate
utkarsh-21st Jan 28, 2024
047a364
add UninterleaveToU32 gate
utkarsh-21st Jan 29, 2024
290e9a8
add UninterleaveToB32 gate
utkarsh-21st Jan 29, 2024
97d8126
add U2Subtraction gate
utkarsh-21st Jan 29, 2024
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
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
Wraps up plonky2 verifier as a groth16 circuit

# TODOS
- [ ] Implement constraints for rest of the plonky2 gates
- [ ] ArithmeticExtensionGate
- [ ] BaseSumGate
- [ ] CosetInterpolationGate
- [ ] ExponentiationGate
- [ ] LookupGate
- [ ] LookupTableGate
- [ ] MulExtensionGate
- [ ] NoopGate
- [ ] PoseidonMdsGate
- [ ] RandomAccessGate
- [ ] ReducingGate
- [ ] ReducingExtensionGate
- [x] Implement constraints for rest of the plonky2 gates
- [x] ArithmeticExtensionGate
- [x] BaseSumGate
- [x] CosetInterpolationGate
- [x] ExponentiationGate
- [x] LookupGate
- [x] LookupTableGate
- [x] MulExtensionGate
- [x] NoopGate
- [x] PoseidonMdsGate
- [x] RandomAccessGate
- [x] ReducingGate
- [x] ReducingExtensionGate
- [ ] Implement constraints for lookups in vanishing polynomial evaluation
- [ ] Use poseidon over BN254 scalar field rather than goldilocks field; it will reduce constraints vastly. Also implement the corresponding config for plonky2 prover
- [x] Use poseidon over BN254 scalar field rather than goldilocks field; it will reduce constraints vastly. Also implement the corresponding config for plonky2 prover
9 changes: 9 additions & 0 deletions build_plonk.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
go build main.go
go install
plonky2-groth16-verifier buildPlonk --common_data ./data/tendermint/common_data.json

# plonky2-groth16-verifier provePlonk --plonky2_proof_path ./data/tendermint/proof_with_pis.json --verifier_only_path ./data/tendermint/verifier_only.json --public_inputs_path ./data/tendermint/pub_inputs.json --proving_key_path ./data/pk.bin --r1cs_path ./data/r1cs.bin

# plonky2-groth16-verifier verifyPlonk --plonkProofPath ./data/proofP --vkey_path ./data/vk.bin --pub_inputs_path ./data/tendermint/pub_inputs.json

# plonky2-groth16-verifier exportSolPlonk --vkey_path ./data/vk.bin
2 changes: 2 additions & 0 deletions build_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ plonky2-groth16-verifier build --common_data ./data/goldilocks/common_data.json
plonky2-groth16-verifier prove --plonky2_proof_path ./data/goldilocks/proof_with_pis.json --verifier_only_path ./data/goldilocks/verifier_only.json --public_inputs_path ./data/goldilocks/pub_inputs.json --proving_key_path ./data/pk.bin --r1cs_path ./data/r1cs.bin --vk_path ./data/vk.bin

plonky2-groth16-verifier verify --groth16_proof_path ./data/g16p --vkey_path ./data/vk.bin --pub_inputs_path ./data/goldilocks/pub_inputs.json

plonky2-groth16-verifier exportSol --vkey_path ./data/vk.bin
78 changes: 71 additions & 7 deletions cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,26 @@ package cmd

import (
"fmt"
"math"
"math/big"
"os"

"github.com/Electron-Labs/plonky2-groth16-verifier/verifier"
"github.com/consensys/gnark-crypto/ecc"
kzg_bn254 "github.com/consensys/gnark-crypto/ecc/bn254/kzg"
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/backend/plonk"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/frontend/cs/r1cs"
"github.com/consensys/gnark/frontend/cs/scs"
"github.com/spf13/cobra"
)

var common_data_path string

// buildCmd represents the build command
var buildCmd = &cobra.Command{
Use: "build",
// buildGroth16Cmd represents the buildGroth16
var buildGroth16Cmd = &cobra.Command{
Use: "buildGroth16",
Short: "Build gnark groth16 circuit",
Long: `Builds gnark groth16 circuit corresponding to provided common_data and plonky2 config.`,
Run: func(cmd *cobra.Command, args []string) {
Expand Down Expand Up @@ -63,8 +68,67 @@ var buildCmd = &cobra.Command{
},
}

func init() {
buildCmd.Flags().StringVarP(&common_data_path, "common_data", "d", "", "JSON File path to common data of plonky2 circuit")
_ = buildCmd.MarkFlagRequired("common_data")
rootCmd.AddCommand(buildCmd)
// buildPlonkCmd represents the buildPlonk
var buildPlonkCmd = &cobra.Command{
Use: "buildPlonk",
Short: "Build gnark plonk circuit",
Long: `Builds gnark plonk circuit corresponding to provided common_data and plonky2 config.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("build called:\n common data: %s\n ", common_data_path)

common_data, err := read_common_data_from_file(common_data_path)
if err != nil {
fmt.Println("Failed to read common data file:", err)
os.Exit(1)
}
circuitConstraints := getCircuitConstants(common_data)

var myCircuit verifier.Runner

// Arrays are resized according to circuitConstants before compiling
myCircuit.Make(circuitConstraints, common_data)

ccs, _ := frontend.Compile(ecc.BN254.ScalarField(), scs.NewBuilder, &myCircuit)
// r1cs := ccs.(*cs.SparseR1CS)
// scs := r1cs.(*cs.SparseR1CS)
// srs, err := test.NewKZGSRS(scs)
srs, err := kzg_bn254.NewSRS(uint64(math.Pow(2, 28)), big.NewInt(-1))
if err != nil {
panic(err)
}
// pk, vk, _ := plonk.Setup(r1cs, srs)
pk, vk, _ := plonk.Setup(ccs, srs)

f_r1cs, err := os.Create("data/r1cs.bin")
if err != nil {
fmt.Println("Failed to create r1cs file:", err)
os.Exit(1)
}
// r1cs.WriteTo(f_r1cs)
ccs.WriteTo(f_r1cs)

f_pd, _ := os.Create("data/pk.bin")
if err != nil {
fmt.Println("Failed to create pk file:", err)
os.Exit(1)
}
pk.WriteTo(f_pd)

f_vk, err := os.Create("data/vk.bin")
if err != nil {
fmt.Println("Failed to create vk file:", err)
os.Exit(1)
}
vk.WriteTo(f_vk)
},
}

func init() {
buildGroth16Cmd.Flags().StringVarP(&common_data_path, "common_data", "d", "", "JSON File path to common data of plonky2 circuit")
_ = buildGroth16Cmd.MarkFlagRequired("common_data")
rootCmd.AddCommand(buildGroth16Cmd)

buildPlonkCmd.Flags().StringVarP(&common_data_path, "common_data", "d", "", "JSON File path to common data of plonky2 circuit")
_ = buildPlonkCmd.MarkFlagRequired("common_data")
rootCmd.AddCommand(buildPlonkCmd)
}
85 changes: 85 additions & 0 deletions cmd/export_solidity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
"fmt"
"os"

"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/backend/plonk"
"github.com/spf13/cobra"
)

// exportSolGroth16Cmd represents the exportSolGroth16 command
var exportSolGroth16Cmd = &cobra.Command{
Use: "exportSolGroth16",
Short: "Exports Solidity contract for groth16 backend",
Long: `Exports VerifyingKey as a Solidity contract for groth16 backend`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("export_solidity called:\n vkey: %s\n ", vkey_path)

vk := groth16.NewVerifyingKey(ecc.BN254)
vkFile, err := os.Open(vkey_path)
if err != nil {
fmt.Println("vkFile open wrong: ", err)
os.Exit(1)
}
vk.ReadFrom(vkFile)

f_sol, err := os.Create("data/Verifier.sol")
if err != nil {
fmt.Println("Failed to create Verifier.sol file:", err)
os.Exit(1)
}
err = vk.ExportSolidity(f_sol)
if err != nil {
fmt.Println("Failed to export Solidity Verifier")
os.Exit(1)
} else {
fmt.Println("Exported succesfully")
}
},
}

var exportSolPlonkCmd = &cobra.Command{
Use: "exportSolPlonk",
Short: "Exports Solidity contract for groth16 backend",
Long: `Exports VerifyingKey as a Solidity contract for plonk backend`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("export_solidity called:\n vkey: %s\n ", vkey_path)

vk := plonk.NewVerifyingKey(ecc.BN254)
vkFile, err := os.Open(vkey_path)
if err != nil {
fmt.Println("vkFile open wrong: ", err)
os.Exit(1)
}
vk.ReadFrom(vkFile)

f_sol, err := os.Create("data/Verifier.sol")
if err != nil {
fmt.Println("Failed to create Verifier.sol file:", err)
os.Exit(1)
}
err = vk.ExportSolidity(f_sol)
if err != nil {
fmt.Println("Failed to export Solidity Verifier")
os.Exit(1)
} else {
fmt.Println("Exported succesfully")
}
},
}

func init() {
exportSolGroth16Cmd.Flags().StringVarP(&vkey_path, "vkey_path", "v", "", "path to the vk.bin file")
_ = exportSolGroth16Cmd.MarkFlagRequired("vkey")
rootCmd.AddCommand(exportSolGroth16Cmd)

exportSolPlonkCmd.Flags().StringVarP(&vkey_path, "vkey_path", "v", "", "path to the vk.bin file")
_ = exportSolPlonkCmd.MarkFlagRequired("vkey")
rootCmd.AddCommand(exportSolPlonkCmd)
}
119 changes: 91 additions & 28 deletions cmd/prove.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/Electron-Labs/plonky2-groth16-verifier/verifier"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/backend/groth16"
"github.com/consensys/gnark/backend/plonk"
"github.com/consensys/gnark/frontend"
"github.com/spf13/cobra"
)
Expand All @@ -21,9 +22,9 @@ var proving_key_path string
var r1cs_path string
var vk_path string

// proveCmd represents the prove command
var proveCmd = &cobra.Command{
Use: "prove",
// proveGroth16Cmd represents the prove proveGroth16
var proveGroth16Cmd = &cobra.Command{
Use: "proveGroth16",
Short: "Generate groth16 proof",
Long: `Generates a groth16 proof corresponding to a plonky2 proof and given public inputs.`,
Run: func(cmd *cobra.Command, args []string) {
Expand All @@ -49,8 +50,6 @@ var proveCmd = &cobra.Command{
os.Exit(1)
}

// public, _ := witness.Public()

r1cs := groth16.NewCS(ecc.BN254)
r1csFile, err := os.Open(r1cs_path)
if err != nil {
Expand Down Expand Up @@ -93,28 +92,92 @@ var proveCmd = &cobra.Command{
},
}

// provePlonkCmd represents the provePlonk command
var provePlonkCmd = &cobra.Command{
Use: "provePlonk",
Short: "Generate plonk proof",
Long: `Generates a plonk proof corresponding to a plonky2 proof and given public inputs.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("Proof gen called:\n proof: %s\n pub_inputs: %s\n pkey: %s\n r1cs: %s\n",
plonky2_proof_path, public_inputs_path, proving_key_path, r1cs_path)
proof, _ := read_proof_from_file(plonky2_proof_path)
verifier_only, _ := read_verifier_data_from_file(verifier_only_path)
public_inputs, _ := read_public_inputs_from_file(public_inputs_path)

proof_variable := proof.GetVariable()
vd_variable := verifier_only.GetVariable()
public_inputs_variable := public_inputs.GetVariable()

assignment := &verifier.Runner{
Proof: proof_variable,
VerifierOnly: vd_variable,
PubInputs: public_inputs_variable,
}

witness, err := frontend.NewWitness(assignment, ecc.BN254.ScalarField())
if err != nil {
fmt.Println("witness wrong: ", err)
os.Exit(1)
}

r1cs := plonk.NewCS(ecc.BN254)
r1csFile, err := os.Open(r1cs_path)
if err != nil {
fmt.Println("r1cs file open wrong: ", err)
os.Exit(1)
}
r1cs.ReadFrom(r1csFile)

pk := plonk.NewProvingKey(ecc.BN254)
pkFile, err := os.Open(proving_key_path)
if err != nil {
fmt.Println("pkFile open wrong: ", err)
os.Exit(1)
}
pk.ReadFrom(pkFile)

plonkP, err := plonk.Prove(r1cs, pk, witness)
if err != nil {
fmt.Println("proving error ", err)
os.Exit(1)
}
proof_file, err := os.Create("./data/proofP")
if err != nil {
fmt.Println("proof file open wrong: ", err)
os.Exit(1)
}
plonkP.WriteTo(proof_file)
if err != nil {
fmt.Println("prove wrong: ", err)
os.Exit(1)
}
},
}

func init() {
proveCmd.Flags().StringVarP(&plonky2_proof_path, "plonky2_proof_path", "p", "", "JSON File path to plonky2 proof")
_ = buildCmd.MarkFlagRequired("plonky2_proof_path")
proveCmd.Flags().StringVarP(&verifier_only_path, "verifier_only_path", "v", "", "JSON File path to verifier only data")
_ = buildCmd.MarkFlagRequired("verifier_only_path")
proveCmd.Flags().StringVarP(&public_inputs_path, "public_inputs_path", "i", "", "JSON File path to public inputs")
_ = buildCmd.MarkFlagRequired("public_inputs_path")
proveCmd.Flags().StringVarP(&proving_key_path, "proving_key_path", "k", "", "JSON File path to proving key")
_ = buildCmd.MarkFlagRequired("proving_key_path")
proveCmd.Flags().StringVarP(&r1cs_path, "r1cs_path", "r", "", "JSON File path to r1cs")
_ = buildCmd.MarkFlagRequired("r1cs_path")
proveCmd.Flags().StringVarP(&vk_path, "vk_path", "e", "", "JSON File path to vkey")
_ = buildCmd.MarkFlagRequired("vk_path")
rootCmd.AddCommand(proveCmd)

// Here you will define your flags and configuration settings.

// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// proveCmd.PersistentFlags().String("foo", "", "A help for foo")

// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// proveCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
proveGroth16Cmd.Flags().StringVarP(&plonky2_proof_path, "plonky2_proof_path", "p", "", "JSON File path to plonky2 proof")
_ = proveGroth16Cmd.MarkFlagRequired("plonky2_proof_path")
proveGroth16Cmd.Flags().StringVarP(&verifier_only_path, "verifier_only_path", "v", "", "JSON File path to verifier only data")
_ = proveGroth16Cmd.MarkFlagRequired("verifier_only_path")
proveGroth16Cmd.Flags().StringVarP(&public_inputs_path, "public_inputs_path", "i", "", "JSON File path to public inputs")
_ = proveGroth16Cmd.MarkFlagRequired("public_inputs_path")
proveGroth16Cmd.Flags().StringVarP(&proving_key_path, "proving_key_path", "k", "", "JSON File path to proving key")
_ = proveGroth16Cmd.MarkFlagRequired("proving_key_path")
proveGroth16Cmd.Flags().StringVarP(&r1cs_path, "r1cs_path", "r", "", "JSON File path to r1cs")
_ = proveGroth16Cmd.MarkFlagRequired("r1cs_path")
proveGroth16Cmd.Flags().StringVarP(&vk_path, "vk_path", "e", "", "JSON File path to vkey")
_ = proveGroth16Cmd.MarkFlagRequired("vk_path")
rootCmd.AddCommand(proveGroth16Cmd)

provePlonkCmd.Flags().StringVarP(&plonky2_proof_path, "plonky2_proof_path", "p", "", "JSON File path to plonky2 proof")
_ = provePlonkCmd.MarkFlagRequired("plonky2_proof_path")
provePlonkCmd.Flags().StringVarP(&verifier_only_path, "verifier_only_path", "v", "", "JSON File path to verifier only data")
_ = provePlonkCmd.MarkFlagRequired("verifier_only_path")
provePlonkCmd.Flags().StringVarP(&public_inputs_path, "public_inputs_path", "i", "", "JSON File path to public inputs")
_ = provePlonkCmd.MarkFlagRequired("public_inputs_path")
provePlonkCmd.Flags().StringVarP(&proving_key_path, "proving_key_path", "k", "", "JSON File path to proving key")
_ = provePlonkCmd.MarkFlagRequired("proving_key_path")
provePlonkCmd.Flags().StringVarP(&r1cs_path, "r1cs_path", "r", "", "JSON File path to r1cs")
_ = provePlonkCmd.MarkFlagRequired("r1cs_path")
rootCmd.AddCommand(provePlonkCmd)
}
3 changes: 2 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ var rootCmd = &cobra.Command{
Long: `The following tasks are supported as part of the application :
1. (build)Generate circuit for custom plonky2 configs requires plonky2_config.json, common_data
2. (prove)Generate groth16 proof corresponding to a plonky2 proof with pis
3. (verify)Verification of groth16 proof`,
3. (verify)Verification of groth16 proof
4. (exportSol)Exports VerifyingKey as a Solidity contract`,
// Uncomment the following line if your bare application
// has an action associated with it:
// Run: func(cmd *cobra.Command, args []string) { },
Expand Down
Loading