diff --git a/Cargo.toml b/Cargo.toml index add5176fe..5c13832c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] -members = ["math", "crypto", "gpu", "benches", "provers/plonk", "provers/stark", "provers/cairo", "provers/groth16", "provers/groth16/arkworks-adapter", "examples/merkle-tree-cli", "examples/prove-miden", "winterfell_adapter"] +members = ["math", "crypto", "gpu", "benches", "provers/plonk", "provers/stark", "provers/cairo", "provers/groth16", "provers/groth16/arkworks-adapter", "examples/merkle-tree-cli", "examples/prove-miden", "examples/prove-gnark-plonk", "winterfell_adapter"] exclude = ["ensure-no_std"] resolver = "2" @@ -18,6 +18,8 @@ lambdaworks-math = { path = "./math", version = "0.5.0", default-features = fals stark-platinum-prover = { path = "./provers/stark" } cairo-platinum-prover = { path = "./provers/cairo" } lambdaworks-winterfell-adapter = { path = "./winterfell_adapter"} +lambdaworks-plonk = { path = "./provers/plonk"} + [patch.crates-io] winter-air = { git = "https://github.com/lambdaclass/winterfell-for-lambdaworks.git", branch = "derive-clone-v6.4"} winter-prover = { git = "https://github.com/lambdaclass/winterfell-for-lambdaworks.git", branch = "derive-clone-v6.4"} diff --git a/examples/prove-gnark-plonk/.gitignore b/examples/prove-gnark-plonk/.gitignore new file mode 100644 index 000000000..a6c57f5fb --- /dev/null +++ b/examples/prove-gnark-plonk/.gitignore @@ -0,0 +1 @@ +*.json diff --git a/examples/prove-gnark-plonk/Cargo.toml b/examples/prove-gnark-plonk/Cargo.toml new file mode 100644 index 000000000..529516bdc --- /dev/null +++ b/examples/prove-gnark-plonk/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "prove-gnark-example" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true + +[[bin]] +name = "prove-gnark-example" +path = "src/main.rs" + +[dependencies] +lambdaworks-crypto = { workspace = true } +lambdaworks-math = { workspace = true, features = ["lambdaworks-serde-string"] } +lambdaworks-plonk = { workspace = true } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" diff --git a/examples/prove-gnark-plonk/README copy.md b/examples/prove-gnark-plonk/README copy.md new file mode 100644 index 000000000..3e4fdf82d --- /dev/null +++ b/examples/prove-gnark-plonk/README copy.md @@ -0,0 +1,8 @@ +
+ +# Lambdaworks Polygon Miden Proving example + +This programs compiles and executes a miden fibonacci programs, obtains the trace, and then proves it and verifies it with lambdaworks Stark Platinum Prover. + +Special thanks to Polygon Miden team for providing the open source VM used here, the prover, and documenting the project. + diff --git a/examples/prove-gnark-plonk/README.md b/examples/prove-gnark-plonk/README.md new file mode 100644 index 000000000..3fd1d642f --- /dev/null +++ b/examples/prove-gnark-plonk/README.md @@ -0,0 +1,3 @@ +# Example of how to use Gnark frontend with lambdaworks + +Gnark version needs to be v0.9.1 for the gnark exporter to work (latest as of jan 2024) diff --git a/examples/prove-gnark-plonk/frontend_precomputed_values.json b/examples/prove-gnark-plonk/frontend_precomputed_values.json new file mode 100644 index 000000000..a0ba8b4e4 --- /dev/null +++ b/examples/prove-gnark-plonk/frontend_precomputed_values.json @@ -0,0 +1,71 @@ +{ + "N": 4, + "N_Padded": 4, + "Omega": "8d51ccce760304d0ec030002760300000001000000000000", + "Input": [ + "3", + "9" + ], + "Ql": [ + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000", + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000", + "0", + "1" + ], + "Qr": [ + "0", + "0", + "0", + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000" + ], + "Qm": [ + "0", + "0", + "1", + "0" + ], + "Qo": [ + "0", + "0", + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000", + "0" + ], + "Qc": [ + "0", + "0", + "0", + "0" + ], + "A": [ + "3", + "9", + "3", + "9" + ], + "B": [ + "3", + "3", + "3", + "9" + ], + "C": [ + "3", + "3", + "9", + "3" + ], + "Permutation": [ + 11, + 3, + 0, + 1, + 2, + 4, + 5, + 10, + 6, + 8, + 7, + 9 + ] +} \ No newline at end of file diff --git a/examples/prove-gnark-plonk/go_exporter_example/example.go b/examples/prove-gnark-plonk/go_exporter_example/example.go new file mode 100644 index 000000000..c22387ab3 --- /dev/null +++ b/examples/prove-gnark-plonk/go_exporter_example/example.go @@ -0,0 +1,312 @@ +// Copyright 2020 ConsenSys AG +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "reflect" + "strconv" + "unsafe" + + "encoding/json" + + "github.com/consensys/gnark-crypto/ecc" + fr_bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" + "github.com/consensys/gnark/backend/plonk" + plonk_bls12381 "github.com/consensys/gnark/backend/plonk/bls12-381" + "github.com/consensys/gnark/backend/witness" + cs "github.com/consensys/gnark/constraint/bls12-381" + "github.com/consensys/gnark/frontend/cs/scs" + "github.com/consensys/gnark/test" + + "github.com/consensys/gnark/frontend" +) + +type SerializedCircuit struct { + N int + N_Padded uint64 + Omega string + Input []string + Ql []string + Qr []string + Qm []string + Qo []string + Qc []string + A []string + B []string + C []string + Permutation []int64 +} + +func witness_to_json_array(fullWitness witness.Witness) string { + + witnessVec := fullWitness.Vector() + witnessVecString := fmt.Sprint(witnessVec) + inputJSON := fmt.Sprint("{\"witness\": ", witnessVecString, "}\n") + + fmt.Println("Witness json") + fmt.Println(inputJSON) + + // Unmarshal JSON into a map + var data map[string]interface{} + json.Unmarshal([]byte(inputJSON), &data) + + // Convert array values to strings + witnessArray, _ := data["witness"].([]interface{}) + + var witnessStrings []string + for _, value := range witnessArray { + // Convert the value to a string + strValue := strconv.Itoa(int(value.(float64))) + witnessStrings = append(witnessStrings, strValue) + } + + // Update the map with the converted array + data["witness"] = witnessStrings + + // Marshal the updated map back to JSON + outputJSON, _ := json.Marshal(data) + + return string(outputJSON) +} + +func ToJSON(_r1cs *cs.SparseR1CS, pk *plonk_bls12381.ProvingKey, fullWitness witness.Witness, witnessPublic fr_bls12381.Vector) { // n + nbConstraints := _r1cs.GetNbConstraints() + nbPublic := len(_r1cs.Public) + n := nbConstraints + nbPublic + omega := pk.Domain[0].Generator.Text(16) + + // Ql, Qm, Qr, Qo, Qk, S1, S2, S3 + var Ql, Qr, Qm, Qo, Qc []string + + for i := 0; i < nbPublic; i++ { + var minus_one fr_bls12381.Element + minus_one = fr_bls12381.NewElement(1) + minus_one.Neg(&minus_one) + zero := fr_bls12381.NewElement(0) + Ql = append(Ql, minus_one.Text(16)) + Qr = append(Qr, zero.Text(16)) + Qm = append(Qm, zero.Text(16)) + Qo = append(Qo, zero.Text(16)) + Qc = append(Qc, zero.Text(16)) + } + + constraint_list := _r1cs.GetSparseR1Cs() + + fmt.Println("Coeffs") + fmt.Println(_r1cs.Coefficients[0].Text(16)) + fmt.Println(_r1cs.Coefficients[1].Text(16)) + fmt.Println(_r1cs.Coefficients[2].Text(16)) + fmt.Println(_r1cs.Coefficients[3].Text(16)) + fmt.Println("") + + for i := 0; i < nbConstraints; i++ { // constraints + Ql = append(Ql, _r1cs.Coefficients[int(constraint_list[i].QL)].Text(16)) + + fmt.Println("Constraint") + fmt.Println("Index QL,QR,QO, QM, QC") + fmt.Println(constraint_list[i].QL) + fmt.Println(constraint_list[i].QR) + fmt.Println(constraint_list[i].QO) + fmt.Println(constraint_list[i].QM) + fmt.Println(constraint_list[i].QC) + + fmt.Println("Values") + fmt.Println(_r1cs.Coefficients[int(constraint_list[i].QL)].Text(16)) + fmt.Println(_r1cs.Coefficients[int(constraint_list[i].QR)].Text(16)) + fmt.Println(_r1cs.Coefficients[int(constraint_list[i].QO)].Text(16)) + fmt.Println("") + + Qr = append(Qr, _r1cs.Coefficients[int(constraint_list[i].QR)].Text(16)) + + var new_Qm fr_bls12381.Element + /* + var new_Qm fr_bls12381.Element + new_Qm.Set(&_r1cs.Coefficients[_r1cs.Constraints[i].M[0].CoeffID()]).Mul(&new_Qm, &_r1cs.Coefficients[_r1cs.Constraints[i].M[1].CoeffID()]) + + */ + new_Qm.Set(&_r1cs.Coefficients[int(constraint_list[i].QM)]) + // new_Qm.Double(&new_Qm) + Qm = append(Qm, new_Qm.Text(16)) + + Qo = append(Qo, _r1cs.Coefficients[int(constraint_list[i].QO)].Text(16)) + Qc = append(Qc, _r1cs.Coefficients[int(constraint_list[i].QC)].Text(16)) + } + + // Witness + // opt, _ := backend.NewProverConfig() + var _solution, _ = _r1cs.Solve(fullWitness) + abc := _solution.(*cs.SparseR1CSSolution) + + fmt.Println("L = A") + fmt.Println(abc.L) + fmt.Println("R = B") + fmt.Println(abc.R) + fmt.Println("O = C") + fmt.Println(abc.O) + + var a, b, c []string + + for i := 0; i < abc.L.Len(); i++ { + a = append(a, abc.L[i].Text(16)) + b = append(b, abc.R[i].Text(16)) + c = append(c, abc.O[i].Text(16)) + } + + var input []string + for i := 0; i < len(_r1cs.Public); i++ { + input = append(input, witnessPublic[i].Text(16)) + } + + /* + Permutation is a private field, and for a reason, they are changing the API a lot here. It's a bit different in the current main. + + This code needs to be update. Currently working with Gnark 9.1 + */ + + rs := reflect.ValueOf(pk).Elem() + rf := rs.Field(0) + rf = reflect.NewAt(rf.Type(), unsafe.Pointer(rf.UnsafeAddr())).Elem() + + var trace_pointer plonk_bls12381.Trace = rf.Interface().(plonk_bls12381.Trace) + + s := trace_pointer.S + fmt.Println("Trace Permutation") + fmt.Println(s) + + data := SerializedCircuit{ + N: n, + Omega: omega, + N_Padded: pk.Domain[0].Cardinality, + Input: input, + Ql: Ql, + Qr: Qr, + Qm: Qm, + Qo: Qo, + Qc: Qc, + A: a, + B: b, + C: c, + Permutation: s, + } + file, _ := json.MarshalIndent(data, "", " ") + _ = ioutil.WriteFile("frontend_precomputed_values.json", file, 0644) + + witnessVec := fullWitness.Vector() + println() + witnessVecString := fmt.Sprint(witnessVec) + + fmt.Println(witnessVecString) + + f, _ := os.Create("witness.json") + fmt.Fprintf(f, witness_to_json_array(fullWitness)) + + // witnessFormatted := fmt.Sprintln(witnessVec) + + // f, _ := os.Create("witness.json") + // fmt.Fprintln(f, witnessVec) + + // schema, _ := frontend.NewSchema(&fullWitness) + // json_wit, _ := fullWitness.ToJSON(schema) + // _ = ioutil.WriteFile("witness.json", witnessFormatted, 0644) + +} + +// In this example we show how to use PLONK with KZG commitments. The circuit that is +// showed here is the same as in ../exponentiate. + +// Circuit y == x**e +// only the bitSize least significant bits of e are used +type Circuit struct { + // tagging a variable is optional + // default uses variable name and secret visibility. + X frontend.Variable `gnark:",public"` + Y frontend.Variable `gnark:",public"` +} + +// Define declares the circuit's constraints +// y == x*x*x +func (circuit *Circuit) Define(api frontend.API) error { + api.AssertIsEqual(circuit.Y, api.Mul(circuit.X, circuit.X, circuit.X)) + return nil +} + +func main() { + + var circuit Circuit + + // building the circuit... + ccs, err := frontend.Compile(ecc.BLS12_381.ScalarField(), scs.NewBuilder, &circuit) + + if err != nil { + fmt.Println("circuit compilation error") + } + + // create the necessary data for KZG. + // This is a toy example, normally the trusted setup to build ZKG + // has been ran before. + // The size of the data in KZG should be the closest power of 2 bounding // + // above max(nbConstraints, nbVariables). + _r1cs := ccs.(*cs.SparseR1CS) + srs, err := test.NewKZGSRS(_r1cs) + if err != nil { + panic(err) + } + + // Correct data: the proof passes + { + // Witnesses instantiation. Witness is known only by the prover, + // while public w is a public data known by the verifier. + var w Circuit + w.X = 3 + w.Y = 27 + + witnessFull, err := frontend.NewWitness(&w, ecc.BLS12_381.ScalarField()) + + if err != nil { + log.Fatal(err) + } + + witnessPublic, err := frontend.NewWitness(&w, ecc.BLS12_381.ScalarField(), frontend.PublicOnly()) + if err != nil { + log.Fatal(err) + } + + // public data consists the polynomials describing the constants involved + // in the constraints, the polynomial describing the permutation ("grand + // product argument"), and the FFT domains. + pk, _, err := plonk.Setup(ccs, srs) + + // cs implements io.WriterTo + // var buf bytes.Buffer + // ccs.WriteTo(&buf) + + // a, err := json.Marshal(pk) + // fmt.Println(buf) + // fmt.Println(string(buf.Bytes())) + + //_, err := plonk.Setup(r1cs, kate, &publicWitness) + if err != nil { + log.Fatal(err) + } + + publicWitness, _ := witnessPublic.Vector().(fr_bls12381.Vector) + + ToJSON(_r1cs, pk.(*plonk_bls12381.ProvingKey), witnessFull, publicWitness) + } +} diff --git a/examples/prove-gnark-plonk/go_exporter_example/go.mod b/examples/prove-gnark-plonk/go_exporter_example/go.mod new file mode 100644 index 000000000..c7c3fd720 --- /dev/null +++ b/examples/prove-gnark-plonk/go_exporter_example/go.mod @@ -0,0 +1,30 @@ +module gnark_example + +go 1.20 + +require ( + github.com/consensys/gnark v0.9.1 + github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb +) + +require ( + github.com/bits-and-blooms/bitset v1.8.0 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/consensys/bavard v0.1.13 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fxamacker/cbor/v2 v2.5.0 // indirect + github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/rs/zerolog v1.30.0 // indirect + github.com/stretchr/testify v1.8.4 // indirect + github.com/x448/float16 v0.8.4 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.11.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + rsc.io/tmplfunc v0.0.3 // indirect +) diff --git a/examples/prove-gnark-plonk/go_exporter_example/go.sum b/examples/prove-gnark-plonk/go_exporter_example/go.sum new file mode 100644 index 000000000..861ec9f68 --- /dev/null +++ b/examples/prove-gnark-plonk/go_exporter_example/go.sum @@ -0,0 +1,62 @@ +github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c= +github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark v0.9.1 h1:aTwBp5469MY/2jNrf4ABrqHRW3+JytfkADdw4ZBY7T0= +github.com/consensys/gnark v0.9.1/go.mod h1:udWvWGXnfBE7mn7BsNoGAvZDnUhcONBEtNijvVjfY80= +github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb h1:f0BMgIjhZy4lSRHCXFbQst85f5agZAjtDMixQqBWNpc= +github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE= +github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= +github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= +github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/examples/prove-gnark-plonk/src/main.rs b/examples/prove-gnark-plonk/src/main.rs new file mode 100644 index 000000000..a694b266f --- /dev/null +++ b/examples/prove-gnark-plonk/src/main.rs @@ -0,0 +1,147 @@ + +use std::fs; + +use lambdaworks_math::field::element::FieldElement; +use lambdaworks_math::field::traits::IsFFTField; +use lambdaworks_math::{ + elliptic_curve::short_weierstrass::curves::bls12_381::default_types::{FrElement, FrField}, + polynomial::Polynomial, +}; + +use lambdaworks_plonk::test_utils::circuit_json::common_preprocessed_input_from_json; + +use serde::{Deserialize, Serialize}; + +fn main() { + // This is the circuit for x * e + 5 == y + let data = fs::read_to_string("go_exporter/example/frontend_precomputed_values.json").expect("Unable to read file"); + + let srs = common_preprocessed_input_from_json(&data); + + // Public input + let x = FieldElement::from(2_u64); + let y = FieldElement::from(11_u64); + + // Private variable + let e = FieldElement::from(3_u64); + + let public_input = vec![x.clone(), y]; + let witness = test_witness_2(x, e); + + let kzg = KZG::new(srs); + let verifying_key = setup(&common_preprocessed_input, &kzg); + let random_generator = TestRandomFieldGenerator {}; + + let prover = Prover::new(kzg.clone(), random_generator); + let proof = prover.prove( + &witness, + &public_input, + &common_preprocessed_input, + &verifying_key, + ); + + let verifier = Verifier::new(kzg); + assert!(verifier.verify( + &proof, + &public_input, + &common_preprocessed_input, + &verifying_key + )); + } + fn test_happy_path_from_json() { + let (witness, common_preprocessed_input, public_input) = + common_preprocessed_input_from_json( + r#"{ + "N": 4, + "N_Padded": 4, + "Omega": "8d51ccce760304d0ec030002760300000001000000000000", + "Input": [ + "2", + "4" + ], + "Ql": [ + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000", + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000", + "0", + "1" + ], + "Qr": [ + "0", + "0", + "0", + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000" + ], + "Qm": [ + "0", + "0", + "1", + "0" + ], + "Qo": [ + "0", + "0", + "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000", + "0" + ], + "Qc": [ + "0", + "0", + "0", + "0" + ], + "A": [ + "2", + "4", + "2", + "4" + ], + "B": [ + "2", + "2", + "2", + "4" + ], + "C": [ + "2", + "2", + "4", + "2" + ], + "Permutation": [ + 11, + 3, + 2, + 1, + 0, + 4, + 5, + 10, + 6, + 8, + 7, + 9 + ] + }"#, + ); + let srs = test_srs(common_preprocessed_input.n); + + let kzg = KZG::new(srs); + let verifying_key = setup(&common_preprocessed_input, &kzg); + let random_generator = TestRandomFieldGenerator {}; + + let prover = Prover::new(kzg.clone(), random_generator); + let proof = prover.prove( + &witness, + &public_input, + &common_preprocessed_input, + &verifying_key, + ); + + let verifier = Verifier::new(kzg); + assert!(verifier.verify( + &proof, + &public_input, + &common_preprocessed_input, + &verifying_key + )); +} diff --git a/provers/plonk/Cargo.toml b/provers/plonk/Cargo.toml index fe24503d5..79a7aae39 100644 --- a/provers/plonk/Cargo.toml +++ b/provers/plonk/Cargo.toml @@ -8,5 +8,5 @@ edition = "2021" [dependencies] lambdaworks-math.workspace = true lambdaworks-crypto.workspace = true -serde = "1.0" +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0"