diff --git a/README.md b/README.md index 28a9adc..d4f67ef 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,6 @@ +# gnark-plonky2-verifier -# gnark-ed25519 -ed25519 implementation in Gnark - -To test: -``` -go test gnark-ed25519/edwards_curve -``` - -To build and run: -``` -go build gnark-ed25519 && ./gnark-ed25519 +To run the benchmark, ``` - -if it panics on compilation.... make vriables capitalzie +go run benchmark.go +``` \ No newline at end of file diff --git a/cubic.go b/cubic.go deleted file mode 100644 index e4504e8..0000000 --- a/cubic.go +++ /dev/null @@ -1,74 +0,0 @@ -// 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" -// "os" -// "github.com/consensys/gnark/frontend" -// "github.com/consensys/gnark-crypto/ecc" -// "github.com/consensys/gnark/frontend/cs/r1cs" -// "github.com/consensys/gnark/backend/groth16" -// _ "gnark-ed25519/edwards_curve" -// _ "gnark-ed25519/sha512" -// ) - -// // Circuit defines a simple circuit -// // x**3 + x + 5 == y -// type Circuit struct { -// // struct tags on a variable is optional -// // default uses variable name and secret visibility. -// X frontend.Variable `gnark:"x"` -// Y frontend.Variable `gnark:",public"` -// } - -// // Define declares the circuit constraints -// // x**3 + x + 5 == y -// func (circuit *Circuit) Define(api frontend.API) error { -// x3 := api.Mul(circuit.X, circuit.X, circuit.X) -// api.AssertIsEqual(circuit.Y, api.Add(x3, circuit.X, 5)) -// return nil -// } - -// func main() { -// err := mainImpl() -// if err != nil { -// fmt.Println(err) -// os.Exit(1) -// } -// } - -// func mainImpl() error { -// var myCircuit Circuit -// r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &myCircuit) -// if err != nil { -// return err -// } - -// assignment := &Circuit{ -// X: "2", -// Y: "15", -// } -// witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) -// publicWitness, _ := witness.Public() -// pk, vk, err := groth16.Setup(r1cs) -// proof, err := groth16.Prove(r1cs, pk, witness) -// err = groth16.Verify(proof, vk, publicWitness) -// if err != nil { -// return err -// } -// fmt.Println(proof) -// return nil -// } diff --git a/ed25519.go b/ed25519.go deleted file mode 100644 index c94cbdd..0000000 --- a/ed25519.go +++ /dev/null @@ -1,277 +0,0 @@ -// 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" - "gnark-ed25519/poseidon" - "math/big" - "time" - - "github.com/consensys/gnark-crypto/ecc" - "github.com/consensys/gnark/backend/groth16" - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/frontend/cs/r1cs" - "github.com/consensys/gnark/test" -) - -// type Eddsa25519Circuit struct { -// M []frontend.Variable -// Pk []frontend.Variable -// Sig []frontend.Variable -// } - -// func (circuit *Eddsa25519Circuit) Define(api frontend.API) error { -// c, err := edwards_curve.New[edwards_curve.Ed25519, edwards_curve.Ed25519Scalars](api) -// if err != nil { -// return err -// } -// edwards_curve.CheckValid(c, circuit.Sig, circuit.M, circuit.Pk) -// return nil -// } - -// type Sha512Circuit struct { -// in []frontend.Variable `gnark:"in"` -// out []frontend.Variable `gnark:"out"` -// } - -// func (circuit *Sha512Circuit) Define(api frontend.API) error { -// res := sha512.Sha512(api, circuit.in) -// if len(res) != 512 { -// panic("bad length") -// } -// for i := 0; i < 512; i++ { -// api.AssertIsEqual(res[i], circuit.out[i]) -// } -// return nil -// } - -// func main() { -// err := mainImpl() -// if err != nil { -// fmt.Println(err) -// os.Exit(1) -// } -// } - -// // func mainImpl() error { -// // in := bytesToBits([]byte("Succinct Labs")) -// // out := hexToBits("503ace098aa03f6feec1b5df0a38aee923f744a775508bc81f2b94ad139be297c2e8cd8c44af527b5d3f017a7fc929892c896604047e52e3f518924f52bff0dc") - -// // myCircuit := Sha512Circuit{ -// // in, -// // out, -// // } -// // fmt.Println(time.Now(), "compiling...") -// // r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &myCircuit) -// // if err != nil { -// // return err -// // } - -// // assignment := &Sha512Circuit{ -// // in, -// // out, -// // } -// // fmt.Println(time.Now(), "generating witness...") -// // witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) -// // publicWitness, _ := witness.Public() -// // fmt.Println(time.Now(), "groth setup...") -// // pk, vk, err := groth16.Setup(r1cs) -// // fmt.Println(time.Now(), "groth prove...") -// // proof, err := groth16.Prove(r1cs, pk, witness) -// // fmt.Println(time.Now(), "groth verify...") -// // err = groth16.Verify(proof, vk, publicWitness) -// // if err != nil { -// // return err -// // } -// // fmt.Println(proof) -// // return nil -// // } - -// func mainImpl() error { -// M := "53756363696e6374204c616273" -// Pk := "f7ec1c43f4de9d49556de87b86b26a98942cb078486fdb44de38b80864c39731" -// Sig := "35c323757c20640a294345c89c0bfcebe3d554fdb0c7b7a0bdb72222c531b1ec849fed99a053e0f5b02dd9a25bb6eb018885526d9f583cdbde0b1e9f6329da09" - -// myCircuit := Eddsa25519Circuit{ -// M: hexToBits(M), -// Pk: hexToBits(Pk), -// Sig: hexToBits(Sig), -// } -// fmt.Println(time.Now(), "compiling...") -// r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &myCircuit) -// if err != nil { -// return err -// } - -// assignment := &Eddsa25519Circuit{ -// M: hexToBits(M), -// Pk: hexToBits(Pk), -// Sig: hexToBits(Sig), -// } -// fmt.Println(time.Now(), "generating witness...") -// witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) -// publicWitness, _ := witness.Public() -// fmt.Println(time.Now(), "groth setup...") -// pk, vk, err := groth16.Setup(r1cs) -// fmt.Println(time.Now(), "groth prove...") -// proof, err := groth16.Prove(r1cs, pk, witness) -// fmt.Println(time.Now(), "groth verify...") -// err = groth16.Verify(proof, vk, publicWitness) -// if err != nil { -// return err -// } -// fmt.Println(proof) -// return nil -// } - -// func hexToBits(h string) []frontend.Variable { -// b, err := hex.DecodeString(h) -// if err != nil { -// panic(err) -// } -// result := make([]frontend.Variable, len(b)*8) -// for i, v := range b { -// for j := 0; j < 8; j++ { -// if (v & (1 << j)) != 0 { -// result[i*8+j] = 1 -// } else { -// result[i*8+j] = 0 -// } -// } -// } -// return result -// } - -// func bytesToBits(arr []byte) []frontend.Variable { -// result := make([]frontend.Variable, len(arr)*8) -// for i, v := range arr { -// for j := 0; j < 8; j++ { -// if (v & (1 << (7 - j))) != 0 { -// result[i*8+j] = 1 -// } else { -// result[i*8+j] = 0 -// } -// } -// } -// return result -// } - -type PoseidonCircuit struct { - In [12]frontend.Variable - Out [12]frontend.Variable -} - -func (circuit *PoseidonCircuit) Define(api frontend.API) error { - poseidon.Poseidon(api, circuit.In, circuit.Out) - return nil -} - -func main() { - in_str := [12]string{ - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - } - out_str := [12]string{ - "4330397376401421145", - "14124799381142128323", - "8742572140681234676", - "14345658006221440202", - "15524073338516903644", - "5091405722150716653", - "15002163819607624508", - "2047012902665707362", - "16106391063450633726", - "4680844749859802542", - "15019775476387350140", - "1698615465718385111", - } - - var in [12]big.Int - var out [12]big.Int - for i := 0; i < 12; i++ { - n := new(big.Int) - n, _ = n.SetString(in_str[i], 10) - in[i] = *n - } - for i := 0; i < 12; i++ { - n := new(big.Int) - n, _ = n.SetString(out_str[i], 10) - out[i] = *n - } - - var _in [12]frontend.Variable - var _out [12]frontend.Variable - - for i := 0; i < 12; i++ { - _in[i] = in[i] - _out[i] = out[i] - } - - myCircuit := PoseidonCircuit{ - In: _in, - Out: _out, - } - - fmt.Println(time.Now(), "compiling...") - r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &myCircuit) - if err != nil { - fmt.Println(err) - panic(err) - } - - assignment := &PoseidonCircuit{ - In: _in, - Out: _out, - } - - witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) - publicWitness, err := witness.Public() - if err != nil { - panic(err) - } - fmt.Println(time.Now(), "groth setup...") - pk, vk, err := groth16.Setup(r1cs) - if err != nil { - panic(err) - } - err = test.IsSolved(&myCircuit, assignment, ecc.BN254.ScalarField()) - if err != nil { - panic(err) - } - - fmt.Println(time.Now(), "groth prove...") - proof, err := groth16.Prove(r1cs, pk, witness) - if err != nil { - panic(err) - } - fmt.Println(time.Now(), "groth verify...") - - err = groth16.Verify(proof, vk, publicWitness) - if err != nil { - panic(err) - } - -} diff --git a/edwards_curve/eddsa25519.go b/edwards_curve/eddsa25519.go deleted file mode 100644 index e15de5b..0000000 --- a/edwards_curve/eddsa25519.go +++ /dev/null @@ -1,297 +0,0 @@ -package edwards_curve - - -// This file is little-endian - -import ( - "math/big" - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/std/math/emulated" - "gnark-ed25519/sha512" -) - - -func H(api frontend.API, m []frontend.Variable) []frontend.Variable { - rawResult := sha512.Sha512(api, swapByteEndianness(m)) - sResult := swapByteEndianness(rawResult[:]) - return sResult -} - -func pow2(n uint) *big.Int { - result := big.NewInt(1) - result.Lsh(result, n) - return result -} - -type EdCurve = Curve[Ed25519, Ed25519Scalars] -type EdPoint = AffinePoint[Ed25519] -type EdCoordinate = emulated.Element[Ed25519] -type EdScalar = emulated.Element[Ed25519Scalars] - -func bits_to_scalar(c *EdCurve, s []frontend.Variable) EdCoordinate { - if len(s) != 256 { panic("bad length") } - elt := emulated.NewElement[Ed25519](0) - if len(elt.Limbs) != 4 { panic("bad length") } - i := 0 - for k := 0; k < 4; k++ { - elt.Limbs[k] = c.api.FromBinary(s[i:i+64]...) - i += 64 - } - if i != len(s) { panic("bad length") } - return elt -} - -// func bits_to_clamped_scalar(c *EdCurve, input []frontend.Variable) EdScalar { -// if len(input) != 256 { panic("bad length") } -// s := make([]frontend.Variable, len(input)) -// copy(s, input) -// s[0] = 0 -// s[1] = 0 -// s[2] = 0 -// s[254] = 1 -// return bits_to_scalar[Ed25519Scalars](c, s) -// } - -func bits_to_element(c *EdCurve, input []frontend.Variable) EdPoint { - // L := emulated.NewElement[Ed25519Scalars](rEd25519) - unchecked_point := decodepoint(c, input) - - // // TODO: https://github.com/warner/python-pure25519 says this check is not necessary: - // // - // // > This library is conservative, and performs full subgroup-membership checks on decoded - // // > points, which adds considerable overhead. The Curve25519/Ed25519 algorithms were - // // > designed to not require these checks, so a careful application might be able to - // // > improve on this slightly (Ed25519 verify down to 6.2ms, DH-finish to 3.2ms). - // c.AssertIsZero(c.ScalarMul(unchecked_point, L)) - - return unchecked_point -} - -// func publickey(c *EdCurve, seed []frontend.Variable) EdPoint { -// if len(seed) != 32 { panic("bad length") } -// a := bits_to_clamped_scalar(c, H(c.api, seed)[:256]) -// return c.ScalarMul(c.g, a) -// } - -func CheckValid(c *EdCurve, s, m, pk []frontend.Variable) { - if len(s) != 512 { panic("bad signature length") } - if len(pk) != 256 { panic("bad public key length") } - if len(m) % 8 != 0 { panic("bad message length") } - R := bits_to_element(c, s[:256]) - A := bits_to_element(c, pk) - h := H(c.api, concat(s[:256], pk, m)) - v1 := c.ScalarMulBinary(c.g, s[256:]) - v2 := c.Add(R, c.ScalarMulBinary(A, h)) - c.AssertIsEqual(v1, v2) -} - -func reverse[T interface{}](arr []T) []T { - result := make([]T, len(arr)) - for i, v := range arr { - result[len(result)-i-1] = v - } - return result -} - -func concat(args ...[]frontend.Variable) []frontend.Variable { - result := []frontend.Variable{} - for _, v := range args { - result = append(result, v...) - } - return result -} - -func decodepoint(c *EdCurve, unclamped []frontend.Variable) EdPoint { - if len(unclamped) != 256 { panic("bad length") } - - s := make([]frontend.Variable, len(unclamped)) - copy(s, unclamped) - s[255] = 0 - y := bits_to_scalar(c, s) -// unclamped = int(binascii.hexlify(s[:32][::-1]), 16) -// clamp = (1 << 255) - 1 -// y = unclamped & clamp # clear MSB - - x := xrecover(c, y) -// x = xrecover(y) - - xbits := c.baseApi.ToBinary(x) - if len(xbits) != 256 { panic("bad length") } - mismatch := c.api.Xor(xbits[0], unclamped[255]) - x = c.baseApi.Select(mismatch, c.baseApi.Neg(x), x).(EdCoordinate) -// if bool(x & 1) != bool(unclamped & (1<<255)): x = Q-x - - P := AffinePoint[Ed25519]{ - X: x, - Y: y, - } -// P = [x,y] - - c.AssertIsOnCurve(P) -// if not isoncurve(P): raise NotOnCurve("decoding point that is not on curve") - - return P -} - -func toValue(s EdCoordinate) *big.Int { - result := big.NewInt(0) - placeValue := big.NewInt(1) - for _, v := range s.Limbs { - q := new(big.Int).Mul(placeValue, v.(*big.Int)) - result.Add(result, q) - placeValue.Lsh(placeValue, Ed25519{}.BitsPerLimb()) - } - return result -} - -func _const(x int64) EdCoordinate { - return emulated.NewElement[Ed25519](big.NewInt(x)) -} - -// Q = 2**255 - 19 -// L = 2**252 + 27742317777372353535851937790883648493 -// def inv(x): -// return pow(x, Q-2, Q) -// d = -121665 * inv(121666) -// I = pow(2,(Q-1)//4,Q) - -func xrecover(c *EdCurve, y EdCoordinate) EdCoordinate { - Q := Ed25519{}.Modulus() - I := emulated.NewElement[Ed25519](newBigInt("2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0")) - - yy := c.baseApi.Mul(y, y) - xx := c.baseApi.Div( - c.baseApi.Sub(yy, _const(1)), - c.baseApi.Add(c.baseApi.Mul(c.d, yy), _const(1)), - ).(EdCoordinate) - // xx = (y*y-1) * inv(d*y*y+1) - - power := new(big.Int).Add(Q, big.NewInt(3)) - power.Rsh(power, 3) - x := pow(c, xx, power) - // x = pow(xx,(Q+3)//8,Q) - - matches := c.baseApi.IsZero(c.baseApi.Sub( - c.baseApi.Mul(x, x), - xx, - )) - x = c.baseApi.Select(matches, x, c.baseApi.Mul(x, emulated.NewElement[Ed25519](I))).(EdCoordinate) - // if (x*x - xx) % Q != 0: x = (x*I) % Q - - odd := c.baseApi.ToBinary(x)[0] - x = c.baseApi.Select(odd, c.baseApi.Neg(x), x).(EdCoordinate) - // if x % 2 != 0: x = Q-x - - return x -} - -func pow(c *EdCurve, base EdCoordinate, exponent *big.Int) EdCoordinate { - mul := base - result := _const(1) - for exponent.Sign() > 0 { - if exponent.Bit(0) != 0 { - result = c.baseApi.Mul(result, mul).(EdCoordinate) - } - mul = c.baseApi.Mul(mul, mul).(EdCoordinate) - exponent.Rsh(exponent, 1) - } - return result -} - -func swapByteEndianness(in []frontend.Variable) []frontend.Variable { - if len(in) % 8 != 0 { panic("must be a multiple of 8 bits") } - result := make([]frontend.Variable, len(in)) - for i := 0; i < len(in); i += 8 { - for j := 0; j < 8; j++ { - result[i+j] = in[i+7-j] - } - } - return result -} - -// def checkvalid(s, m, pk): -// if len(s) != 64: raise Exception("signature length is wrong") -// if len(pk) != 32: raise Exception("public-key length is wrong") -// R = bytes_to_element(s[:32]) -// A = bytes_to_element(pk) -// S = bytes_to_scalar(s[32:]) -// h = Hint(s[:32] + pk + m) -// v1 = Base.scalarmult(S) -// v2 = R.add(A.scalarmult(h)) -// return v1==v2 - -// def publickey(seed): -// # turn first half of SHA512(seed) into scalar, then into point -// assert len(seed) == 32 -// a = bytes_to_clamped_scalar(H(seed)[:32]) -// A = Base.scalarmult(a) -// return A.to_bytes() - -// def bytes_to_scalar(s): -// assert len(s) == 32, len(s) -// return int(binascii.hexlify(s[::-1]), 16) - - -// from pure25519.basic import (bytes_to_clamped_scalar, -// bytes_to_scalar, scalar_to_bytes, -// bytes_to_element, Base) -// import hashlib, binascii - -// def H(m): -// return hashlib.sha512(m).digest() - -// def Hint(m): -// h = H(m) -// return int(binascii.hexlify(h[::-1]), 16) - -// def signature(m,sk,pk): -// assert len(sk) == 32 # seed -// assert len(pk) == 32 -// h = H(sk[:32]) -// a_bytes, inter = h[:32], h[32:] -// a = bytes_to_clamped_scalar(a_bytes) -// r = Hint(inter + m) -// R = Base.scalarmult(r) -// R_bytes = R.to_bytes() -// S = r + Hint(R_bytes + pk + m) * a -// return R_bytes + scalar_to_bytes(S) - -// def checkvalid(s, m, pk): -// if len(s) != 64: raise Exception("signature length is wrong") -// if len(pk) != 32: raise Exception("public-key length is wrong") -// R = bytes_to_element(s[:32]) -// A = bytes_to_element(pk) -// S = bytes_to_scalar(s[32:]) -// h = Hint(s[:32] + pk + m) -// v1 = Base.scalarmult(S) -// v2 = R.add(A.scalarmult(h)) -// return v1==v2 - -// # wrappers - -// import os - -// def create_signing_key(): -// seed = os.urandom(32) -// return seed -// def create_verifying_key(signing_key): -// return publickey(signing_key) - -// def sign(skbytes, msg): -// """Return just the signature, given the message and just the secret -// key.""" -// if len(skbytes) != 32: -// raise ValueError("Bad signing key length %d" % len(skbytes)) -// vkbytes = create_verifying_key(skbytes) -// sig = signature(msg, skbytes, vkbytes) -// return sig - -// def verify(vkbytes, sig, msg): -// if len(vkbytes) != 32: -// raise ValueError("Bad verifying key length %d" % len(vkbytes)) -// if len(sig) != 64: -// raise ValueError("Bad signature length %d" % len(sig)) -// rc = checkvalid(sig, msg, vkbytes) -// if not rc: -// raise ValueError("rc != 0", rc) -// return True diff --git a/edwards_curve/eddsa25519_test.go b/edwards_curve/eddsa25519_test.go deleted file mode 100644 index d3cbf5f..0000000 --- a/edwards_curve/eddsa25519_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package edwards_curve - -import ( - "testing" - "encoding/hex" - - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/test" -) - -type Eddsa25519Circuit struct { - m []frontend.Variable - pk []frontend.Variable - sig []frontend.Variable -} - -func (circuit *Eddsa25519Circuit) Define(api frontend.API) error { - c, err := New[Ed25519, Ed25519Scalars](api) - if err != nil { - return err - } - CheckValid(c, circuit.sig, circuit.m, circuit.pk) - return nil -} - -func TestEddsa25519(t *testing.T) { - assert := test.NewAssert(t) - - m := "53756363696e6374204c616273" - pk := "f7ec1c43f4de9d49556de87b86b26a98942cb078486fdb44de38b80864c39731" - sig := "35c323757c20640a294345c89c0bfcebe3d554fdb0c7b7a0bdb72222c531b1ec849fed99a053e0f5b02dd9a25bb6eb018885526d9f583cdbde0b1e9f6329da09" - - circuit := Eddsa25519Circuit { - m: hexToBits(m), - pk: hexToBits(pk), - sig: hexToBits(sig), - } - witness := Eddsa25519Circuit { - m: hexToBits(m), - pk: hexToBits(pk), - sig: hexToBits(sig), - } - - err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) - assert.NoError(err) -} - -func hexToBits(h string) []frontend.Variable { - b, err := hex.DecodeString(h) - if err != nil { - panic(err) - } - result := make([]frontend.Variable, len(b) * 8) - for i, v := range b { - for j := 0; j < 8; j++ { - if (v & (1 << j)) != 0 { - result[i*8+j] = 1 - } else { - result[i*8+j] = 0 - } - } - } - return result -} - diff --git a/edwards_curve/edparams.go b/edwards_curve/edparams.go deleted file mode 100644 index 47bbca7..0000000 --- a/edwards_curve/edparams.go +++ /dev/null @@ -1,34 +0,0 @@ -package edwards_curve - -import ( - "math/big" -) - -var ( - qEd25519, rEd25519 *big.Int -) - -func init() { - // https://neuromancer.sk/std/other/Ed25519 - qEd25519 = newBigInt("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed") - rEd25519 = newBigInt("1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed") -} - -type Ed25519 struct{} - -func (fp Ed25519) NbLimbs() uint { return 4 } -func (fp Ed25519) BitsPerLimb() uint { return 64 } -func (fp Ed25519) IsPrime() bool { return true } -func (fp Ed25519) Modulus() *big.Int { return qEd25519 } -func (fp Ed25519) Generator() (*big.Int, *big.Int) { - return newBigInt("216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"), - newBigInt("6666666666666666666666666666666666666666666666666666666666666658") -} - -type Ed25519Scalars struct{} - -func (fp Ed25519Scalars) NbLimbs() uint { return 4 } -func (fp Ed25519Scalars) BitsPerLimb() uint { return 64 } -func (fp Ed25519Scalars) IsPrime() bool { return true } -func (fp Ed25519Scalars) Modulus() *big.Int { return rEd25519 } - diff --git a/edwards_curve/edpoint.go b/edwards_curve/edpoint.go deleted file mode 100644 index 75c9300..0000000 --- a/edwards_curve/edpoint.go +++ /dev/null @@ -1,201 +0,0 @@ -package edwards_curve - -import ( - "fmt" - "math/big" - - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/std/math/emulated" -) - -func New[T, S emulated.FieldParams](api frontend.API) (*Curve[T, S], error) { - var t T - var s S - var gxb, gyb *big.Int - var A, D *big.Int - _, is_25519_t := any(t).(Ed25519) - _, is_25519_s := any(s).(Ed25519Scalars) - if is_25519_t && is_25519_s { - // https://neuromancer.sk/std/other/Ed25519 - gxb = newBigInt("216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A") - gyb = newBigInt("6666666666666666666666666666666666666666666666666666666666666658") - A = newBigInt("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec") - D = newBigInt("52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3") - } else { - return nil, fmt.Errorf("unknown curve") - } - return newCurve[T, S]( - api, - emulated.NewElement[T](A), - emulated.NewElement[T](D), - emulated.NewElement[T](gxb), - emulated.NewElement[T](gyb)) -} - -func newBigInt(s string) *big.Int { - result, success := new(big.Int).SetString(s, 16) - if !success { - panic("invalid bigint") - } - return result -} - -// TODO: could also have a type constraint for curve parameters (fields, -// equation and generator). But for now we don't do arbitrary curves. - -type Curve[T, S emulated.FieldParams] struct { - a emulated.Element[T] - d emulated.Element[T] - - // api is the native api, we construct it ourselves to be sure - api frontend.API - // baseApi is the api for point operations - baseApi frontend.API - // scalarApi is the api for scalar operations - scalarApi frontend.API - - g AffinePoint[T] -} - -func (c *Curve[T, S]) Generator() AffinePoint[T] { - return c.g -} - -func newCurve[T, S emulated.FieldParams](api frontend.API, a, d, Gx, Gy emulated.Element[T]) (*Curve[T, S], error) { - ba, err := emulated.NewField[T](api) - if err != nil { - return nil, fmt.Errorf("new base api: %w", err) - } - sa, err := emulated.NewField[S](api) - if err != nil { - return nil, fmt.Errorf("new scalar api: %w", err) - } - return &Curve[T, S]{ - a: a, - d: d, - api: api, - baseApi: ba, - scalarApi: sa, - g: AffinePoint[T]{ - X: Gx, - Y: Gy, - }, - }, nil -} - -type AffinePoint[T emulated.FieldParams] struct { - X, Y emulated.Element[T] -} - -func (c *Curve[T, S]) Neg(p AffinePoint[T]) AffinePoint[T] { - return AffinePoint[T]{ - X: p.X, - Y: c.baseApi.Neg(p.Y).(emulated.Element[T]), - } -} - -func (c *Curve[T, S]) AssertIsEqual(p, q AffinePoint[T]) { - c.baseApi.AssertIsEqual(p.X, q.X) - c.baseApi.AssertIsEqual(p.Y, q.Y) -} - -func (c *Curve[T, S]) AssertIsOnCurve(p AffinePoint[T]) { - xx := c.baseApi.Mul(p.X, p.X) - yy := c.baseApi.Mul(p.Y, p.Y) - axx := c.baseApi.Mul(xx, c.a) - lhs := c.baseApi.Add(axx, yy) - - dxx := c.baseApi.Mul(xx, c.d) - dxxyy := c.baseApi.Mul(dxx, yy) - rhs := c.baseApi.Add(dxxyy, 1) - - c.baseApi.AssertIsEqual(lhs, rhs) -} - -func (c *Curve[T, S]) AssertIsZero(p AffinePoint[T]) { - c.baseApi.AssertIsEqual(p.X, 0) - c.baseApi.AssertIsEqual(p.Y, 1) -} - -func (c *Curve[T, S]) Add(q, r AffinePoint[T]) AffinePoint[T] { - // u = (x1 + y1) * (x2 + y2) - u1 := c.baseApi.Mul(q.X, c.a) - u1 = c.baseApi.Sub(q.Y, u1) - u2 := c.baseApi.Add(r.X, r.Y) - u := c.baseApi.Mul(u1, u2) - - // v0 = x1 * y2 - v0 := c.baseApi.Mul(r.Y, q.X) - - // v1 = x2 * y1 - v1 := c.baseApi.Mul(r.X, q.Y) - - // v2 = d * v0 * v1 - v2 := c.baseApi.Mul(c.d, v0, v1) - - var px, py frontend.Variable - - // x = (v0 + v1) / (1 + v2) - px = c.baseApi.Add(v0, v1) - px = c.baseApi.DivUnchecked(px, c.baseApi.Add(1, v2)) - - // y = (u + a * v0 - v1) / (1 - v2) - py = c.baseApi.Mul(c.a, v0) - py = c.baseApi.Sub(py, v1) - py = c.baseApi.Add(py, u) - py = c.baseApi.DivUnchecked(py, c.baseApi.Sub(1, v2)) - - return AffinePoint[T]{ - X: px.(emulated.Element[T]), - Y: py.(emulated.Element[T]), - } -} - -func (c *Curve[T, S]) Double(p AffinePoint[T]) AffinePoint[T] { - u := c.baseApi.Mul(p.X, p.Y) - v := c.baseApi.Mul(p.X, p.X) - w := c.baseApi.Mul(p.Y, p.Y) - - n1 := c.baseApi.Add(u, u) - av := c.baseApi.Mul(v, c.a) - n2 := c.baseApi.Sub(w, av) - d1 := c.baseApi.Add(w, av) - d2 := c.baseApi.Sub(2, d1) - - px := c.baseApi.DivUnchecked(n1, d1) - py := c.baseApi.DivUnchecked(n2, d2) - - return AffinePoint[T]{ - X: px.(emulated.Element[T]), - Y: py.(emulated.Element[T]), - } -} - -func (c *Curve[T, S]) Select(b frontend.Variable, p, q AffinePoint[T]) AffinePoint[T] { - x := c.baseApi.Select(b, p.X, q.X) - y := c.baseApi.Select(b, p.Y, q.Y) - return AffinePoint[T]{ - X: x.(emulated.Element[T]), - Y: y.(emulated.Element[T]), - } -} - -func (c *Curve[T, S]) ScalarMul(p AffinePoint[T], s emulated.Element[S]) AffinePoint[T] { - return c.ScalarMulBinary(p, c.scalarApi.ToBinary(s)) -} - -func (c *Curve[T, S]) ScalarMulBinary(p AffinePoint[T], sBits []frontend.Variable) AffinePoint[T] { - res := AffinePoint[T]{ - X: emulated.NewElement[T](0), - Y: emulated.NewElement[T](1), - } - acc := p - - for i := 0; i < len(sBits); i++ { - tmp := c.Add(res, acc) - res = c.Select(sBits[i], tmp, res) - acc = c.Double(acc) - } - - return res -} diff --git a/edwards_curve/edpoint_test.go b/edwards_curve/edpoint_test.go deleted file mode 100644 index c53f476..0000000 --- a/edwards_curve/edpoint_test.go +++ /dev/null @@ -1,230 +0,0 @@ -package edwards_curve - -import ( - "math/big" - "testing" - - "github.com/consensys/gnark-crypto/ecc" - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/std/math/emulated" - "github.com/consensys/gnark/test" - // "github.com/ethereum/go-ethereum/crypto/secp256k1" -) - -type OnCurveTest[T, S emulated.FieldParams] struct { - P AffinePoint[T] -} - -func (c *OnCurveTest[T, S]) Define(api frontend.API) error { - cr, err := New[T, S](api) - if err != nil { - return err - } - cr.AssertIsOnCurve(c.P) - return nil -} - -func TestGeneratorIsOnCurve(t *testing.T) { - assert := test.NewAssert(t) - circuit := OnCurveTest[Ed25519, Ed25519Scalars]{} - witness := OnCurveTest[Ed25519, Ed25519Scalars]{ - P: AffinePoint[Ed25519]{ - X: emulated.NewElement[Ed25519](newBigInt("216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A")), - Y: emulated.NewElement[Ed25519](newBigInt("6666666666666666666666666666666666666666666666666666666666666658")), - }, - } - err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) - assert.NoError(err) -} - -// s1*x1 + s2*x2 = y -type MulAddTest[T, S emulated.FieldParams] struct { - X1, X2 AffinePoint[T] - S1, S2 emulated.Element[S] - Y AffinePoint[T] -} - -func (c *MulAddTest[T, S]) Define(api frontend.API) error { - cr, err := New[T, S](api) - if err != nil { - return err - } - X1S1 := cr.ScalarMul(c.X1, c.S1) - X2S2 := cr.ScalarMul(c.X2, c.S2) - sum := cr.Add(X1S1, X2S2) - cr.AssertIsEqual(sum, c.Y) - cr.scalarApi.AssertIsEqual( - cr.scalarApi.Add(c.S1, c.S2), - emulated.NewElement[S](big.NewInt(1)), - ) - return nil -} - -func TestGeneratorGeneratesCurveOfCorrectOrder(t *testing.T) { - assert := test.NewAssert(t) - Gx, Gy := Ed25519{}.Generator() - G := AffinePoint[Ed25519]{ - X: emulated.NewElement[Ed25519](Gx), - Y: emulated.NewElement[Ed25519](Gy), - } - for i := 2; i <= 3; i++ { - S1 := new(big.Int).Sub(rEd25519, big.NewInt(int64(i - 1))) - S2 := big.NewInt(int64(i)) - circuit := MulAddTest[Ed25519, Ed25519Scalars]{} - witness := MulAddTest[Ed25519, Ed25519Scalars]{ - X1: G, - X2: G, - S1: emulated.NewElement[Ed25519Scalars](S1), - S2: emulated.NewElement[Ed25519Scalars](S2), - Y: G, - } - err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) - assert.NoError(err) - } -} - -var testCurve = ecc.BN254 - -// type NegTest[T, S emulated.FieldParams] struct { -// P, Q AffinePoint[T] -// } - -// func (c *NegTest[T, S]) Define(api frontend.API) error { -// cr, err := New[T, S](api) -// if err != nil { -// return err -// } -// res := cr.Neg(c.P) -// cr.AssertIsEqual(res, c.Q) -// return nil -// } - -// func TestNeg(t *testing.T) { -// assert := test.NewAssert(t) -// secpCurve := secp256k1.S256() -// yn := new(big.Int).Sub(secpCurve.P, secpCurve.Gy) -// circuit := NegTest[emulated.Secp256k1, emulated.Secp256k1Scalars]{} -// witness := NegTest[emulated.Secp256k1, emulated.Secp256k1Scalars]{ -// P: AffinePoint[emulated.Secp256k1]{ -// X: emulated.NewElement[emulated.Secp256k1](secpCurve.Gx), -// Y: emulated.NewElement[emulated.Secp256k1](secpCurve.Gy), -// }, -// Q: AffinePoint[emulated.Secp256k1]{ -// X: emulated.NewElement[emulated.Secp256k1](secpCurve.Gx), -// Y: emulated.NewElement[emulated.Secp256k1](yn), -// }, -// } -// err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) -// assert.NoError(err) -// } - -// type AddTest[T, S emulated.FieldParams] struct { -// P, Q, R AffinePoint[T] -// } - -// func (c *AddTest[T, S]) Define(api frontend.API) error { -// cr, err := New[T, S](api) -// if err != nil { -// return err -// } -// res := cr.Add(c.P, c.Q) -// cr.AssertIsEqual(res, c.R) -// return nil -// } - -// func TestAdd(t *testing.T) { -// assert := test.NewAssert(t) -// secpCurve := secp256k1.S256() -// xd, yd := secpCurve.Double(secpCurve.Gx, secpCurve.Gy) -// xa, ya := secpCurve.Add(xd, yd, secpCurve.Gx, secpCurve.Gy) -// circuit := AddTest[emulated.Secp256k1, emulated.Secp256k1Scalars]{} -// witness := AddTest[emulated.Secp256k1, emulated.Secp256k1Scalars]{ -// P: AffinePoint[emulated.Secp256k1]{ -// X: emulated.NewElement[emulated.Secp256k1](secpCurve.Gx), -// Y: emulated.NewElement[emulated.Secp256k1](secpCurve.Gy), -// }, -// Q: AffinePoint[emulated.Secp256k1]{ -// X: emulated.NewElement[emulated.Secp256k1](xd), -// Y: emulated.NewElement[emulated.Secp256k1](yd), -// }, -// R: AffinePoint[emulated.Secp256k1]{ -// X: emulated.NewElement[emulated.Secp256k1](xa), -// Y: emulated.NewElement[emulated.Secp256k1](ya), -// }, -// } -// err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) -// assert.NoError(err) -// } - -// type DoubleTest[T, S emulated.FieldParams] struct { -// P, Q AffinePoint[T] -// } - -// func (c *DoubleTest[T, S]) Define(api frontend.API) error { -// cr, err := New[T, S](api) -// if err != nil { -// return err -// } -// res := cr.Double(c.P) -// cr.AssertIsEqual(res, c.Q) -// return nil -// } - -// func TestDouble(t *testing.T) { -// assert := test.NewAssert(t) -// secpCurve := secp256k1.S256() -// xd, yd := secpCurve.Double(secpCurve.Gx, secpCurve.Gy) -// circuit := DoubleTest[emulated.Secp256k1, emulated.Secp256k1Scalars]{} -// witness := DoubleTest[emulated.Secp256k1, emulated.Secp256k1Scalars]{ -// P: AffinePoint[emulated.Secp256k1]{ -// X: emulated.NewElement[emulated.Secp256k1](secpCurve.Gx), -// Y: emulated.NewElement[emulated.Secp256k1](secpCurve.Gy), -// }, -// Q: AffinePoint[emulated.Secp256k1]{ -// X: emulated.NewElement[emulated.Secp256k1](xd), -// Y: emulated.NewElement[emulated.Secp256k1](yd), -// }, -// } -// err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) -// assert.NoError(err) -// } - -// type ScalarMulTest[T, S emulated.FieldParams] struct { -// P, Q AffinePoint[T] -// S emulated.Element[S] -// } - -// func (c *ScalarMulTest[T, S]) Define(api frontend.API) error { -// cr, err := New[T, S](api) -// if err != nil { -// return err -// } -// res := cr.ScalarMul(c.P, c.S) -// cr.AssertIsEqual(res, c.Q) -// return nil -// } - -// func TestScalarMul(t *testing.T) { -// assert := test.NewAssert(t) -// secpCurve := secp256k1.S256() -// s, ok := new(big.Int).SetString("44693544921776318736021182399461740191514036429448770306966433218654680512345", 10) -// assert.True(ok) -// sx, sy := secpCurve.ScalarMult(secpCurve.Gx, secpCurve.Gy, s.Bytes()) - -// circuit := ScalarMulTest[emulated.Secp256k1, emulated.Secp256k1Scalars]{} -// witness := ScalarMulTest[emulated.Secp256k1, emulated.Secp256k1Scalars]{ -// S: emulated.NewElement[emulated.Secp256k1Scalars](s), -// P: AffinePoint[emulated.Secp256k1]{ -// X: emulated.NewElement[emulated.Secp256k1](secpCurve.Gx), -// Y: emulated.NewElement[emulated.Secp256k1](secpCurve.Gy), -// }, -// Q: AffinePoint[emulated.Secp256k1]{ -// X: emulated.NewElement[emulated.Secp256k1](sx), -// Y: emulated.NewElement[emulated.Secp256k1](sy), -// }, -// } -// err := test.IsSolved(&circuit, &witness, testCurve.ScalarField()) -// assert.NoError(err) -// // _, err = frontend.Compile(testCurve.ScalarField(), r1cs.NewBuilder, &circuit) -// // assert.NoError(err) -// } diff --git a/fibonacci.go b/fibonacci.go deleted file mode 100644 index 5bfade3..0000000 --- a/fibonacci.go +++ /dev/null @@ -1,94 +0,0 @@ -package main - -import ( - "fmt" - . "gnark-ed25519/field" - . "gnark-ed25519/plonky2_verifier" - "gnark-ed25519/poseidon" - "os" - "time" - - "github.com/consensys/gnark-crypto/ecc" - "github.com/consensys/gnark/backend/groth16" - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/frontend/cs/r1cs" -) - -type BenchmarkPlonky2VerifierCircuit struct { - proofWithPis ProofWithPublicInputs - - verifierChip *VerifierChip -} - -func (circuit *BenchmarkPlonky2VerifierCircuit) Define(api frontend.API) error { - proofWithPis := DeserializeProofWithPublicInputs("./plonky2_verifier/data/fibonacci/proof_with_public_inputs.json") - commonCircuitData := DeserializeCommonCircuitData("./plonky2_verifier/data/fibonacci/common_circuit_data.json") - verifierOnlyCircuitData := DeserializeVerifierOnlyCircuitData("./plonky2_verifier/data/fibonacci/verifier_only_circuit_data.json") - - fieldAPI := NewFieldAPI(api) - qeAPI := NewQuadraticExtensionAPI(fieldAPI, commonCircuitData.DegreeBits) - hashAPI := NewHashAPI(fieldAPI) - poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI) - friChip := NewFriChip(api, fieldAPI, qeAPI, hashAPI, poseidonChip, &commonCircuitData.FriParams) - plonkChip := NewPlonkChip(api, qeAPI, commonCircuitData) - circuit.verifierChip = NewVerifierChip(api, fieldAPI, qeAPI, poseidonChip, plonkChip, friChip) - - circuit.verifierChip.Verify(proofWithPis, verifierOnlyCircuitData, commonCircuitData) - - return nil -} - -func compileCircuit() frontend.CompiledConstraintSystem { - circuit := BenchmarkPlonky2VerifierCircuit{} - proofWithPis := DeserializeProofWithPublicInputs("./plonky2_verifier/data/fibonacci/proof_with_public_inputs.json") - circuit.proofWithPis = proofWithPis - - r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) - if err != nil { - fmt.Println("error in building circuit", err) - os.Exit(1) - } - - return r1cs -} - -func createProof(r1cs frontend.CompiledConstraintSystem) groth16.Proof { - proofWithPis := DeserializeProofWithPublicInputs("./plonky2_verifier/data/fibonacci/proof_with_public_inputs.json") - - // Witness - assignment := &BenchmarkPlonky2VerifierCircuit{ - proofWithPis: proofWithPis, - } - - fmt.Println("Generating witness", time.Now()) - witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) - publicWitness, _ := witness.Public() - - fmt.Println("Running circuit setup", time.Now()) - pk, vk, err := groth16.Setup(r1cs) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - fmt.Println("Creating proof", time.Now()) - proof, err := groth16.Prove(r1cs, pk, witness) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - fmt.Println("Verifying proof", time.Now()) - err = groth16.Verify(proof, vk, publicWitness) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - return proof -} - -func main() { - r1cs := compileCircuit() - proof := createProof(r1cs) - fmt.Println(proof.CurveID(), time.Now()) -} diff --git a/fri_benchmark.go b/fri_benchmark.go deleted file mode 100644 index e66dc99..0000000 --- a/fri_benchmark.go +++ /dev/null @@ -1,407 +0,0 @@ -package main - -import ( - "fmt" - . "gnark-ed25519/field" - . "gnark-ed25519/plonky2_verifier" - "gnark-ed25519/poseidon" - "os" - "time" - - "github.com/consensys/gnark-crypto/ecc" - "github.com/consensys/gnark/backend/groth16" - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/frontend/cs/r1cs" -) - -type BenchmarkLargeDummyFriCircuit struct { - zeta QuadraticExtension - openings FriOpenings - friChallenges FriChallenges - initialMerkleCaps []MerkleCap - friProof FriProof -} - -func (circuit *BenchmarkLargeDummyFriCircuit) Define(api frontend.API) error { - commonCircuitData := DeserializeCommonCircuitData("./plonky2_verifier/data/dummy_2^14_gates/common_circuit_data.json") - - field := NewFieldAPI(api) - qeAPI := NewQuadraticExtensionAPI(field, commonCircuitData.DegreeBits) - poseidonChip := poseidon.NewPoseidonChip(api, field) - friChip := NewFriChip(api, field, qeAPI, poseidonChip, &commonCircuitData.FriParams) - - friChip.VerifyFriProof( - commonCircuitData.GetFriInstance(qeAPI, circuit.zeta, commonCircuitData.DegreeBits), - circuit.openings, - &circuit.friChallenges, - circuit.initialMerkleCaps, - &circuit.friProof, - ) - - return nil -} - -func compileCircuit() frontend.CompiledConstraintSystem { - fmt.Println("compiling circuit", time.Now()) - circuit := BenchmarkLargeDummyFriCircuit{} - - /* - commonCircuitData := DeserializeCommonCircuitData("./plonky2_verifier/data/dummy_2^14_gates/common_circuit_data.json") - - circuit.zeta[0] = emulated.NewElement[EmulatedField](nil) - circuit.zeta[1] = emulated.NewElement[EmulatedField](nil) - - fmt.Println("circuit zeta allocated") - - // Batch 0 has the following openings - // Constants (config.num_constants + 1) - // Sigmas (config.num_routed_wires) - // Wires (config.num_wires) - // Plonk_Z (config.num_challenges) - // Partial Products (config.num_challenges * config.num_partial_products) - // Quotient Polynomails (config.num_challenges * config.quotient_degree_factor) - - // Batch 1 has the following openings - // Plonk_Z_next (config.num_challenges) - - circuit.openings.Batches = make([]FriOpeningBatch, 2) - - batch1Size := commonCircuitData.NumConstants + 1 + - commonCircuitData.Config.NumRoutedWires + - commonCircuitData.Config.NumWires + - commonCircuitData.Config.NumChallenges + - (commonCircuitData.Config.NumChallenges * commonCircuitData.NumPartialProducts) + - (commonCircuitData.Config.NumChallenges * commonCircuitData.QuotientDegreeFactor) - - circuit.openings.Batches[0].Values = make([]QuadraticExtension, 0) - for i := uint64(0); i < batch1Size; i++ { - circuit.openings.Batches[0].Values = append(circuit.openings.Batches[0].Values, NewEmptyQuadraticExtension()) - } - - batch2Size := commonCircuitData.Config.NumChallenges - circuit.openings.Batches[1].Values = make([]QuadraticExtension, 0) - for i := uint64(0); i < batch2Size; i++ { - circuit.openings.Batches[1].Values = append(circuit.openings.Batches[1].Values, NewEmptyQuadraticExtension()) - } - - fmt.Println("circuit openings allocated") - - circuit.friChallenges.FriAlpha = NewEmptyQuadraticExtension() - circuit.friChallenges.FriPowResponse = emulated.NewElement[EmulatedField](nil) - circuit.friChallenges.FriBetas = make([]QuadraticExtension, 0) - for i := 0; i < len(commonCircuitData.FriParams.ReductionArityBits); i++ { - circuit.friChallenges.FriBetas = append(circuit.friChallenges.FriBetas, NewEmptyQuadraticExtension()) - } - circuit.friChallenges.FriQueryIndicies = make([]F, 0) - for i := uint64(0); i < commonCircuitData.FriParams.Config.NumQueryRounds; i++ { - circuit.friChallenges.FriQueryIndicies = append(circuit.friChallenges.FriQueryIndicies, NewEmptyFieldElement()) - } - - fmt.Println("circuit challenges allocated") - - // initial merkle caps is the merkle cap for - // the constant/sigmas, wires, partial products, - // and quotient composite polynomial - // The merkle cap size is 2**cap_height hashes - numMerkleCaps := 4 - merkleCapSize := 1 << commonCircuitData.Config.FriConfig.CapHeight - circuit.initialMerkleCaps = make([]MerkleCap, 0) - for i := 0; i < numMerkleCaps; i++ { - merkleCap := make([]Hash, 0) - for j := 0; j < merkleCapSize; j++ { - merkleCap = append(merkleCap, NewEmptyHash()) - } - circuit.initialMerkleCaps = append(circuit.initialMerkleCaps, merkleCap) - } - - fmt.Println("circuit initialMerkleCaps allocated") - - // CommitPhaseMerkleCap is number of reduction_arity_bits - // finalPoly has 2^(degreeBits - sum(arity_bits)) coefficients - numCommitPhaseMerkleCaps := len(commonCircuitData.FriParams.ReductionArityBits) - for i := 0; i < numCommitPhaseMerkleCaps; i++ { - circuit.friProof.CommitPhaseMerkleCaps = make([]MerkleCap, 0) - merkleCap := make([]Hash, 0) - for j := 0; j < merkleCapSize; j++ { - merkleCap = append(merkleCap, NewEmptyHash()) - } - circuit.friProof.CommitPhaseMerkleCaps = append(circuit.friProof.CommitPhaseMerkleCaps, merkleCap) - } - - fmt.Println("circuit friproof CommitPhaseMerkleCaps allocated") - - friOracleInfo := commonCircuitData.FriOracles() - circuit.friProof.QueryRoundProofs = make([]FriQueryRound, 0) - for i := 0; i < int(commonCircuitData.FriParams.Config.NumQueryRounds); i++ { - - evalsProof := make([]EvalProof, 0) - // Allocation for the initial trees proof - for j := 0; j < len(friOracleInfo); j++ { - leafSize := friOracleInfo[0].NumPolys - merkleProofLen := commonCircuitData.DegreeBits + commonCircuitData.Config.FriConfig.RateBits - commonCircuitData.Config.FriConfig.CapHeight - - evalElements := make([]F, 0) - for k := uint64(0); k < leafSize; k++ { - evalElements = append(evalElements, NewEmptyFieldElement()) - } - - merkleProofSiblings := make([]Hash, 0) - for k := uint64(0); k < merkleProofLen; k++ { - merkleProofSiblings = append(merkleProofSiblings, NewEmptyHash()) - } - - evalsProof = append( - evalsProof, - EvalProof{ - Elements: evalElements, - MerkleProof: MerkleProof{merkleProofSiblings}, - }, - ) - } - - // Allocation for the steps - steps := make([]FriQueryStep, 0) - codewordLenBits := commonCircuitData.DegreeBits + commonCircuitData.Config.FriConfig.RateBits - for j := 0; j < len(commonCircuitData.FriParams.ReductionArityBits); j++ { - arityBits := commonCircuitData.FriParams.ReductionArityBits[j] - leafSize := 1 << int(arityBits) - codewordLenBits -= arityBits - merkleProofLen := codewordLenBits - commonCircuitData.Config.FriConfig.CapHeight - - evalQEs := make([]QuadraticExtension, 0) - for k := 0; k < leafSize; k++ { - evalQEs = append(evalQEs, NewEmptyQuadraticExtension()) - } - - merkleProofSiblings := make([]Hash, 0) - for k := uint64(0); k < merkleProofLen; k++ { - merkleProofSiblings = append(merkleProofSiblings, NewEmptyHash()) - } - - steps = append( - steps, - FriQueryStep{ - Evals: evalQEs, - MerkleProof: MerkleProof{merkleProofSiblings}, - }, - ) - } - - circuit.friProof.QueryRoundProofs = append( - circuit.friProof.QueryRoundProofs, - FriQueryRound{ - InitialTreesProof: FriInitialTreeProof{evalsProof}, - Steps: steps, - }, - ) - - fmt.Println("circuit friproof QueryRoundProofs allocated for round", i) - } - - // Final poly allocation - finalPolyLenBit := commonCircuitData.DegreeBits - for _, arityBit := range commonCircuitData.FriParams.ReductionArityBits { - finalPolyLenBit -= arityBit - } - - circuit.friProof.FinalPoly.Coeffs = make([]QuadraticExtension, 0) - for i := 0; i < (1 << finalPolyLenBit); i++ { - circuit.friProof.FinalPoly.Coeffs = append(circuit.friProof.FinalPoly.Coeffs, NewEmptyQuadraticExtension()) - } - - fmt.Println("circuit friproof FinalPoly allocated") - - // PowWitness allocation - circuit.friProof.PowWitness = NewEmptyFieldElement() - fmt.Println("Partial witness allocation done") - */ - - proofWithPis := DeserializeProofWithPublicInputs("./plonky2_verifier/data/dummy_2^14_gates/proof_with_public_inputs.json") - verifierOnlyCircuitData := DeserializeVerifierOnlyCircuitData("./plonky2_verifier/data/dummy_2^14_gates/verifier_only_circuit_data.json") - - zeta := QuadraticExtension{ - NewFieldElementFromString("17377750363769967882"), - NewFieldElementFromString("11921191651424768462"), - } - friChallenges := FriChallenges{ - FriAlpha: QuadraticExtension{ - NewFieldElementFromString("16721004555774385479"), - NewFieldElementFromString("10688151135543754663"), - }, - FriBetas: []QuadraticExtension{ - { - NewFieldElementFromString("3312441922957827805"), - NewFieldElementFromString("15128092514958289671"), - }, - { - NewFieldElementFromString("13630530769060141802"), - NewFieldElementFromString("14559883974933163008"), - }, - { - NewFieldElementFromString("16146508250083930687"), - NewFieldElementFromString("5176346568444408396"), - }, - }, - FriPowResponse: NewFieldElement(4389), - FriQueryIndicies: []F{ - NewFieldElementFromString("16334967868590615051"), - NewFieldElementFromString("2911473540496037915"), - NewFieldElementFromString("14887216056886344225"), - NewFieldElementFromString("7808811227805914295"), - NewFieldElementFromString("2018594961417375749"), - NewFieldElementFromString("3733368398777208435"), - NewFieldElementFromString("2623035669037055104"), - NewFieldElementFromString("299243030573481514"), - NewFieldElementFromString("7189789717962704433"), - NewFieldElementFromString("14566344026886816268"), - NewFieldElementFromString("12555390069003437453"), - NewFieldElementFromString("17225508403199418233"), - NewFieldElementFromString("5088797913879903292"), - NewFieldElementFromString("9715691392773433023"), - NewFieldElementFromString("7565836764713256165"), - NewFieldElementFromString("1500143546029322929"), - NewFieldElementFromString("1245802417104422080"), - NewFieldElementFromString("6831959786661245110"), - NewFieldElementFromString("17271054758535453780"), - NewFieldElementFromString("6225460404576395409"), - NewFieldElementFromString("15932661092896277351"), - NewFieldElementFromString("12452534049198240575"), - NewFieldElementFromString("4225199666055520177"), - NewFieldElementFromString("13235091290587791090"), - NewFieldElementFromString("2562357622728700774"), - NewFieldElementFromString("17676678042980201498"), - NewFieldElementFromString("5837067135702409874"), - NewFieldElementFromString("11238419549114325157"), - }, - } - - initialMerkleCaps := []MerkleCap{ - verifierOnlyCircuitData.ConstantSigmasCap, - proofWithPis.Proof.WiresCap, - proofWithPis.Proof.PlonkZsPartialProductsCap, - proofWithPis.Proof.QuotientPolysCap, - } - - circuit.zeta = zeta - circuit.openings = proofWithPis.Proof.Openings.ToFriOpenings() - circuit.friChallenges = friChallenges - circuit.initialMerkleCaps = initialMerkleCaps - circuit.friProof = proofWithPis.Proof.OpeningProof - - r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) - if err != nil { - fmt.Println("error in building circuit", err) - os.Exit(1) - } - - return r1cs -} - -func createProof(r1cs frontend.CompiledConstraintSystem) groth16.Proof { - proofWithPis := DeserializeProofWithPublicInputs("./plonky2_verifier/data/dummy_2^14_gates/proof_with_public_inputs.json") - verifierOnlyCircuitData := DeserializeVerifierOnlyCircuitData("./plonky2_verifier/data/dummy_2^14_gates/verifier_only_circuit_data.json") - - zeta := QuadraticExtension{ - NewFieldElementFromString("17377750363769967882"), - NewFieldElementFromString("11921191651424768462"), - } - friChallenges := FriChallenges{ - FriAlpha: QuadraticExtension{ - NewFieldElementFromString("16721004555774385479"), - NewFieldElementFromString("10688151135543754663"), - }, - FriBetas: []QuadraticExtension{ - { - NewFieldElementFromString("3312441922957827805"), - NewFieldElementFromString("15128092514958289671"), - }, - { - NewFieldElementFromString("13630530769060141802"), - NewFieldElementFromString("14559883974933163008"), - }, - { - NewFieldElementFromString("16146508250083930687"), - NewFieldElementFromString("5176346568444408396"), - }, - }, - FriPowResponse: NewFieldElement(4389), - FriQueryIndicies: []F{ - NewFieldElementFromString("16334967868590615051"), - NewFieldElementFromString("2911473540496037915"), - NewFieldElementFromString("14887216056886344225"), - NewFieldElementFromString("7808811227805914295"), - NewFieldElementFromString("2018594961417375749"), - NewFieldElementFromString("3733368398777208435"), - NewFieldElementFromString("2623035669037055104"), - NewFieldElementFromString("299243030573481514"), - NewFieldElementFromString("7189789717962704433"), - NewFieldElementFromString("14566344026886816268"), - NewFieldElementFromString("12555390069003437453"), - NewFieldElementFromString("17225508403199418233"), - NewFieldElementFromString("5088797913879903292"), - NewFieldElementFromString("9715691392773433023"), - NewFieldElementFromString("7565836764713256165"), - NewFieldElementFromString("1500143546029322929"), - NewFieldElementFromString("1245802417104422080"), - NewFieldElementFromString("6831959786661245110"), - NewFieldElementFromString("17271054758535453780"), - NewFieldElementFromString("6225460404576395409"), - NewFieldElementFromString("15932661092896277351"), - NewFieldElementFromString("12452534049198240575"), - NewFieldElementFromString("4225199666055520177"), - NewFieldElementFromString("13235091290587791090"), - NewFieldElementFromString("2562357622728700774"), - NewFieldElementFromString("17676678042980201498"), - NewFieldElementFromString("5837067135702409874"), - NewFieldElementFromString("11238419549114325157"), - }, - } - - initialMerkleCaps := []MerkleCap{ - verifierOnlyCircuitData.ConstantSigmasCap, - proofWithPis.Proof.WiresCap, - proofWithPis.Proof.PlonkZsPartialProductsCap, - proofWithPis.Proof.QuotientPolysCap, - } - - // Witness - assignment := &BenchmarkLargeDummyFriCircuit{ - zeta: zeta, - openings: proofWithPis.Proof.Openings.ToFriOpenings(), - friChallenges: friChallenges, - initialMerkleCaps: initialMerkleCaps, - friProof: proofWithPis.Proof.OpeningProof, - } - - fmt.Println("Generating witness", time.Now()) - witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) - publicWitness, _ := witness.Public() - pk, vk, err := groth16.Setup(r1cs) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - fmt.Println("Creating proof", time.Now()) - proof, err := groth16.Prove(r1cs, pk, witness) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - fmt.Println("Verifying proof", time.Now()) - err = groth16.Verify(proof, vk, publicWitness) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - return proof -} - -func main() { - r1cs := compileCircuit() - fi, _ := os.Open("dummy_fri.r1cs") - r1cs.WriteTo(fi) - proof := createProof(r1cs) - fmt.Println(proof.CurveID(), time.Now()) -} diff --git a/go.mod b/go.mod index 58391ba..0ace971 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module gnark-ed25519 +module gnark-plonky2-verifier go 1.19 diff --git a/plonk_benchmark.go b/plonk_benchmark.go deleted file mode 100644 index cf4983e..0000000 --- a/plonk_benchmark.go +++ /dev/null @@ -1,132 +0,0 @@ -package main - -import ( - "fmt" - . "gnark-ed25519/field" - . "gnark-ed25519/plonky2_verifier" - "os" - "time" - - "github.com/consensys/gnark-crypto/ecc" - "github.com/consensys/gnark/backend/groth16" - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/frontend/cs/r1cs" -) - -type BenchmarkPlonkCircuit struct { - proofChallenges ProofChallenges - openings OpeningSet -} - -func (circuit *BenchmarkPlonkCircuit) Define(api frontend.API) error { - commonCircuitData := DeserializeCommonCircuitData("./plonky2_verifier/data/dummy_2^14_gates/common_circuit_data.json") - - field := NewFieldAPI(api) - qeAPI := NewQuadraticExtensionAPI(field, commonCircuitData.DegreeBits) - - plonkChip := NewPlonkChip(api, qeAPI, commonCircuitData) - - plonkChip.Verify(circuit.proofChallenges, circuit.openings) - - return nil -} - -func compileCircuit() frontend.CompiledConstraintSystem { - fmt.Println("compiling circuit", time.Now()) - circuit := BenchmarkPlonkCircuit{} - - proofWithPis := DeserializeProofWithPublicInputs("./plonky2_verifier/data/dummy_2^14_gates/proof_with_public_inputs.json") - - // Challenge associated with the data from "/.data/dummy_2^14_gates/*" - proofChallenges := ProofChallenges{ - PlonkBetas: []F{ - NewFieldElementFromString("4678728155650926271"), - NewFieldElementFromString("13611962404289024887"), - }, - PlonkGammas: []F{ - NewFieldElementFromString("13237663823305715949"), - NewFieldElementFromString("15389314098328235145"), - }, - PlonkAlphas: []F{ - NewFieldElementFromString("14505919539124304197"), - NewFieldElementFromString("1695455639263736117"), - }, - PlonkZeta: QuadraticExtension{ - NewFieldElementFromString("14887793628029982930"), - NewFieldElementFromString("1136137158284059037"), - }, - } - - circuit.proofChallenges = proofChallenges - circuit.openings = proofWithPis.Proof.Openings - - r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) - if err != nil { - fmt.Println("error in building circuit", err) - os.Exit(1) - } - - return r1cs -} - -func createProof(r1cs frontend.CompiledConstraintSystem) groth16.Proof { - proofWithPis := DeserializeProofWithPublicInputs("./plonky2_verifier/data/dummy_2^14_gates/proof_with_public_inputs.json") - - // Challenge associated with the data from "/.data/dummy_2^14_gates/*" - proofChallenges := ProofChallenges{ - PlonkBetas: []F{ - NewFieldElementFromString("4678728155650926271"), - NewFieldElementFromString("13611962404289024887"), - }, - PlonkGammas: []F{ - NewFieldElementFromString("13237663823305715949"), - NewFieldElementFromString("15389314098328235145"), - }, - PlonkAlphas: []F{ - NewFieldElementFromString("14505919539124304197"), - NewFieldElementFromString("1695455639263736117"), - }, - PlonkZeta: QuadraticExtension{ - NewFieldElementFromString("14887793628029982930"), - NewFieldElementFromString("1136137158284059037"), - }, - } - - // Witness - assignment := &BenchmarkPlonkCircuit{ - proofChallenges: proofChallenges, - openings: proofWithPis.Proof.Openings, - } - - fmt.Println("Generating witness", time.Now()) - witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) - publicWitness, _ := witness.Public() - pk, vk, err := groth16.Setup(r1cs) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - fmt.Println("Creating proof", time.Now()) - proof, err := groth16.Prove(r1cs, pk, witness) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - fmt.Println("Verifying proof", time.Now()) - err = groth16.Verify(proof, vk, publicWitness) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - return proof -} - -func main() { - r1cs := compileCircuit() - fi, _ := os.Open("dummy_fri.r1cs") - r1cs.WriteTo(fi) - proof := createProof(r1cs) - fmt.Println(proof.CurveID(), time.Now()) -} diff --git a/plonky2_verifier/challenger.go b/plonky2_verifier/challenger.go index 931db60..cd86ed8 100644 --- a/plonky2_verifier/challenger.go +++ b/plonky2_verifier/challenger.go @@ -2,8 +2,8 @@ package plonky2_verifier import ( "fmt" - . "gnark-ed25519/field" - "gnark-ed25519/poseidon" + . "gnark-plonky2-verifier/field" + "gnark-plonky2-verifier/poseidon" "github.com/consensys/gnark/frontend" ) diff --git a/plonky2_verifier/challenger_test.go b/plonky2_verifier/challenger_test.go index 1ad0ed9..20a86b0 100644 --- a/plonky2_verifier/challenger_test.go +++ b/plonky2_verifier/challenger_test.go @@ -1,10 +1,10 @@ package plonky2_verifier import ( - "gnark-ed25519/field" - . "gnark-ed25519/field" - . "gnark-ed25519/poseidon" - "gnark-ed25519/utils" + "gnark-plonky2-verifier/field" + . "gnark-plonky2-verifier/field" + . "gnark-plonky2-verifier/poseidon" + "gnark-plonky2-verifier/utils" "testing" "github.com/consensys/gnark/frontend" diff --git a/plonky2_verifier/deserialize.go b/plonky2_verifier/deserialize.go index 062d80a..407e167 100644 --- a/plonky2_verifier/deserialize.go +++ b/plonky2_verifier/deserialize.go @@ -2,8 +2,8 @@ package plonky2_verifier import ( "encoding/json" - . "gnark-ed25519/field" - "gnark-ed25519/utils" + . "gnark-plonky2-verifier/field" + "gnark-plonky2-verifier/utils" "io/ioutil" "os" ) diff --git a/plonky2_verifier/fri.go b/plonky2_verifier/fri.go index 0108d15..77bdaf9 100644 --- a/plonky2_verifier/fri.go +++ b/plonky2_verifier/fri.go @@ -2,9 +2,9 @@ package plonky2_verifier import ( "fmt" - "gnark-ed25519/field" - . "gnark-ed25519/field" - "gnark-ed25519/poseidon" + "gnark-plonky2-verifier/field" + . "gnark-plonky2-verifier/field" + "gnark-plonky2-verifier/poseidon" "math" "math/big" "math/bits" diff --git a/plonky2_verifier/fri_test.go b/plonky2_verifier/fri_test.go index 38d1e1e..ef15043 100644 --- a/plonky2_verifier/fri_test.go +++ b/plonky2_verifier/fri_test.go @@ -1,8 +1,8 @@ package plonky2_verifier import ( - . "gnark-ed25519/field" - "gnark-ed25519/poseidon" + . "gnark-plonky2-verifier/field" + "gnark-plonky2-verifier/poseidon" "testing" "github.com/consensys/gnark/frontend" diff --git a/plonky2_verifier/fri_utils.go b/plonky2_verifier/fri_utils.go index e008992..f18eec2 100644 --- a/plonky2_verifier/fri_utils.go +++ b/plonky2_verifier/fri_utils.go @@ -1,8 +1,8 @@ package plonky2_verifier import ( - "gnark-ed25519/field" - . "gnark-ed25519/field" + "gnark-plonky2-verifier/field" + . "gnark-plonky2-verifier/field" ) type FriOpeningBatch struct { diff --git a/plonky2_verifier/hash.go b/plonky2_verifier/hash.go index 47dbc4d..e1c3c4f 100644 --- a/plonky2_verifier/hash.go +++ b/plonky2_verifier/hash.go @@ -2,7 +2,7 @@ package plonky2_verifier import ( "fmt" - . "gnark-ed25519/field" + . "gnark-plonky2-verifier/field" "github.com/consensys/gnark/frontend" ) diff --git a/plonky2_verifier/plonk.go b/plonky2_verifier/plonk.go index acf8e81..fc495dd 100644 --- a/plonky2_verifier/plonk.go +++ b/plonky2_verifier/plonk.go @@ -1,7 +1,7 @@ package plonky2_verifier import ( - . "gnark-ed25519/field" + . "gnark-plonky2-verifier/field" "github.com/consensys/gnark/frontend" ) diff --git a/plonky2_verifier/plonk_test.go b/plonky2_verifier/plonk_test.go index 686f93f..1c75e5a 100644 --- a/plonky2_verifier/plonk_test.go +++ b/plonky2_verifier/plonk_test.go @@ -1,7 +1,7 @@ package plonky2_verifier import ( - . "gnark-ed25519/field" + . "gnark-plonky2-verifier/field" "testing" "github.com/consensys/gnark/frontend" diff --git a/plonky2_verifier/quadratic_extension.go b/plonky2_verifier/quadratic_extension.go index d26e5d2..80fdc1c 100644 --- a/plonky2_verifier/quadratic_extension.go +++ b/plonky2_verifier/quadratic_extension.go @@ -2,7 +2,7 @@ package plonky2_verifier import ( "fmt" - . "gnark-ed25519/field" + . "gnark-plonky2-verifier/field" "math/bits" "github.com/consensys/gnark/frontend" diff --git a/plonky2_verifier/quadratic_extension_test.go b/plonky2_verifier/quadratic_extension_test.go index 2fba976..ca047e6 100644 --- a/plonky2_verifier/quadratic_extension_test.go +++ b/plonky2_verifier/quadratic_extension_test.go @@ -1,8 +1,8 @@ package plonky2_verifier import ( - "gnark-ed25519/field" - . "gnark-ed25519/field" + "gnark-plonky2-verifier/field" + . "gnark-plonky2-verifier/field" "testing" "github.com/consensys/gnark/frontend" diff --git a/plonky2_verifier/structs.go b/plonky2_verifier/structs.go index 2cf02ca..50e1c7b 100644 --- a/plonky2_verifier/structs.go +++ b/plonky2_verifier/structs.go @@ -1,7 +1,7 @@ package plonky2_verifier import ( - . "gnark-ed25519/field" + . "gnark-plonky2-verifier/field" ) type MerkleCap = []Hash diff --git a/plonky2_verifier/verifier.go b/plonky2_verifier/verifier.go index 5a76990..e8daf1e 100644 --- a/plonky2_verifier/verifier.go +++ b/plonky2_verifier/verifier.go @@ -1,8 +1,8 @@ package plonky2_verifier import ( - . "gnark-ed25519/field" - "gnark-ed25519/poseidon" + . "gnark-plonky2-verifier/field" + "gnark-plonky2-verifier/poseidon" "github.com/consensys/gnark/frontend" ) diff --git a/plonky2_verifier/verifier_test.go b/plonky2_verifier/verifier_test.go index 59a1c4a..90bc298 100644 --- a/plonky2_verifier/verifier_test.go +++ b/plonky2_verifier/verifier_test.go @@ -1,8 +1,8 @@ package plonky2_verifier import ( - . "gnark-ed25519/field" - . "gnark-ed25519/poseidon" + . "gnark-plonky2-verifier/field" + . "gnark-plonky2-verifier/poseidon" "testing" "github.com/consensys/gnark/frontend" diff --git a/plonky2_verifier_benchmark.go b/plonky2_verifier_benchmark.go deleted file mode 100644 index d7d8a13..0000000 --- a/plonky2_verifier_benchmark.go +++ /dev/null @@ -1,94 +0,0 @@ -package main - -import ( - "fmt" - . "gnark-ed25519/field" - . "gnark-ed25519/plonky2_verifier" - "gnark-ed25519/poseidon" - "os" - "time" - - "github.com/consensys/gnark-crypto/ecc" - "github.com/consensys/gnark/backend/groth16" - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/frontend/cs/r1cs" -) - -type BenchmarkPlonky2VerifierCircuit struct { - proofWithPis ProofWithPublicInputs - - verifierChip *VerifierChip -} - -func (circuit *BenchmarkPlonky2VerifierCircuit) Define(api frontend.API) error { - proofWithPis := DeserializeProofWithPublicInputs("./plonky2_verifier/data/dummy_2^14_gates/proof_with_public_inputs.json") - commonCircuitData := DeserializeCommonCircuitData("./plonky2_verifier/data/dummy_2^14_gates/common_circuit_data.json") - verifierOnlyCircuitData := DeserializeVerifierOnlyCircuitData("./plonky2_verifier/data/dummy_2^14_gates/verifier_only_circuit_data.json") - - fieldAPI := NewFieldAPI(api) - qeAPI := NewQuadraticExtensionAPI(fieldAPI, commonCircuitData.DegreeBits) - hashAPI := NewHashAPI(fieldAPI) - poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI) - friChip := NewFriChip(api, fieldAPI, qeAPI, hashAPI, poseidonChip, &commonCircuitData.FriParams) - plonkChip := NewPlonkChip(api, qeAPI, commonCircuitData) - circuit.verifierChip = NewVerifierChip(api, fieldAPI, qeAPI, poseidonChip, plonkChip, friChip) - - circuit.verifierChip.Verify(proofWithPis, verifierOnlyCircuitData, commonCircuitData) - - return nil -} - -func compileCircuit() frontend.CompiledConstraintSystem { - circuit := BenchmarkPlonky2VerifierCircuit{} - proofWithPis := DeserializeProofWithPublicInputs("./plonky2_verifier/data/dummy_2^14_gates/proof_with_public_inputs.json") - circuit.proofWithPis = proofWithPis - - r1cs, err := frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &circuit) - if err != nil { - fmt.Println("error in building circuit", err) - os.Exit(1) - } - - return r1cs -} - -func createProof(r1cs frontend.CompiledConstraintSystem) groth16.Proof { - proofWithPis := DeserializeProofWithPublicInputs("./plonky2_verifier/data/dummy_2^14_gates/proof_with_public_inputs.json") - - // Witness - assignment := &BenchmarkPlonky2VerifierCircuit{ - proofWithPis: proofWithPis, - } - - fmt.Println("Generating witness", time.Now()) - witness, _ := frontend.NewWitness(assignment, ecc.BN254.ScalarField()) - publicWitness, _ := witness.Public() - - fmt.Println("Running circuit setup", time.Now()) - pk, vk, err := groth16.Setup(r1cs) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - fmt.Println("Creating proof", time.Now()) - proof, err := groth16.Prove(r1cs, pk, witness) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - fmt.Println("Verifying proof", time.Now()) - err = groth16.Verify(proof, vk, publicWitness) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - return proof -} - -func main() { - r1cs := compileCircuit() - proof := createProof(r1cs) - fmt.Println(proof.CurveID(), time.Now()) -} diff --git a/poseidon/poseidon.go b/poseidon/poseidon.go index 8b9776e..76a83cd 100644 --- a/poseidon/poseidon.go +++ b/poseidon/poseidon.go @@ -1,7 +1,7 @@ package poseidon import ( - . "gnark-ed25519/field" + . "gnark-plonky2-verifier/field" "github.com/consensys/gnark/frontend" ) diff --git a/poseidon/poseidon_test.go b/poseidon/poseidon_test.go index 03137c8..3e41150 100644 --- a/poseidon/poseidon_test.go +++ b/poseidon/poseidon_test.go @@ -1,9 +1,9 @@ package poseidon import ( - "gnark-ed25519/field" - . "gnark-ed25519/field" - "gnark-ed25519/utils" + "gnark-plonky2-verifier/field" + . "gnark-plonky2-verifier/field" + "gnark-plonky2-verifier/utils" "testing" "github.com/consensys/gnark/backend/groth16" diff --git a/poseidon/public_inputs_hash_test.go b/poseidon/public_inputs_hash_test.go index 503b737..7148464 100644 --- a/poseidon/public_inputs_hash_test.go +++ b/poseidon/public_inputs_hash_test.go @@ -1,8 +1,8 @@ package poseidon import ( - . "gnark-ed25519/field" - "gnark-ed25519/utils" + . "gnark-plonky2-verifier/field" + "gnark-plonky2-verifier/utils" "testing" "github.com/consensys/gnark-crypto/ecc" diff --git a/sha512/sha512.go b/sha512/sha512.go deleted file mode 100644 index f76fa85..0000000 --- a/sha512/sha512.go +++ /dev/null @@ -1,293 +0,0 @@ -package sha512 - -/* Based on https://gist.github.com/illia-v/7883be942da5d416521375004cecb68f */ - -import ( - "github.com/consensys/gnark/frontend" -) - -func Sha512(api frontend.API, in []frontend.Variable) [512]frontend.Variable { - _not := func(x [64]frontend.Variable) [64]frontend.Variable { - return not(api, x) - } - _and := func(xs ...[64]frontend.Variable) [64]frontend.Variable { - return and(api, xs...) - } - _add := func(xs ...[64]frontend.Variable) [64]frontend.Variable { - return add(api, xs...) - } - _xor := func(xs ...[64]frontend.Variable) [64]frontend.Variable { - return xor(api, xs...) - } - zip_add := func(a, b Array8_64) Array8_64 { - a0, a1, a2, a3, a4, a5, a6, a7 := unpack8(a) - b0, b1, b2, b3, b4, b5, b6, b7 := unpack8(b) - return Array8_64{ - _add(a0, b0), - _add(a1, b1), - _add(a2, b2), - _add(a3, b3), - _add(a4, b4), - _add(a5, b5), - _add(a6, b6), - _add(a7, b7), - } - } - initial_hash := []uint64{ - 0x6a09e667f3bcc908, - 0xbb67ae8584caa73b, - 0x3c6ef372fe94f82b, - 0xa54ff53a5f1d36f1, - 0x510e527fade682d1, - 0x9b05688c2b3e6c1f, - 0x1f83d9abfb41bd6b, - 0x5be0cd19137e2179, - } - round_constants := []uint64{ - 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, - 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019, - 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, - 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, - 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, - 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, - 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275, - 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, - 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, - 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725, - 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, - 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, - 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, - 0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001, - 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218, - 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, - 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, - 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, - 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, - 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, - 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, - 0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207, - 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, - 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, - 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, - 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, - 0x5fcb6fab3ad6faec, 0x6c44198c4a475817, - } - for _, v := range in { - api.AssertIsBoolean(v) - } - mdi := divChecked(len(in), 8) % 128 - var padding_len int - if mdi < 112 { - padding_len = 119 - mdi - } else { - padding_len = 247 - mdi - } - message_length_bits := uint64ToBits(uint64(len(in))) - in = append(in, 1) - for i := 0; i < 7; i++ { - in = append(in, 0) - } - for i := 0; i < padding_len*8; i++ { - in = append(in, 0) - } - for i := 0; i < 64; i++ { - in = append(in, message_length_bits[i]) - } - - sha512_hash := Array8_64{ - uint64ToBits(initial_hash[0]), - uint64ToBits(initial_hash[1]), - uint64ToBits(initial_hash[2]), - uint64ToBits(initial_hash[3]), - uint64ToBits(initial_hash[4]), - uint64ToBits(initial_hash[5]), - uint64ToBits(initial_hash[6]), - uint64ToBits(initial_hash[7]), - } - for chunk_start := 0; chunk_start < divChecked(len(in), 8); chunk_start += 128 { - chunk := in[chunk_start*8 : (chunk_start+128)*8] - if len(chunk) != 1024 { - panic("bad length") - } - u := make([]frontend.Variable, 80*64) - for i, _ := range u { - u[i] = 0 - } - copy(u, chunk) - - w := reshape(u) - - for i := 16; i < 80; i++ { - s0 := _xor( - _right_rotate(w[i-15], 1), - _right_rotate(w[i-15], 8), - _shr(w[i-15], 7), - ) - s1 := _xor( - _right_rotate(w[i-2], 19), - _right_rotate(w[i-2], 61), - _shr(w[i-2], 6), - ) - w[i] = _add(w[i-16], s0, w[i-7], s1) - } - a, b, c, d, e, f, g, h := unpack8(sha512_hash) - for i := 0; i < 80; i++ { - sum1 := _xor( - _right_rotate(e, 14), - _right_rotate(e, 18), - _right_rotate(e, 41), - ) - ch := _xor(_and(e, f), _and(_not(e), g)) - temp1 := _add(h, sum1, ch, uint64ToBits(round_constants[i]), w[i]) - sum0 := _xor( - _right_rotate(a, 28), - _right_rotate(a, 34), - _right_rotate(a, 39), - ) - maj := _xor(_and(a, b), _and(a, c), _and(b, c)) - temp2 := _add(sum0, maj) - - h = g - g = f - f = e - e = _add(d, temp1) - d = c - c = b - b = a - a = _add(temp1, temp2) - } - sha512_hash = zip_add(sha512_hash, Array8_64{a, b, c, d, e, f, g, h}) - } - return flatten8(sha512_hash) -} - -func _right_rotate(n [64]frontend.Variable, bits int) [64]frontend.Variable { - var result [64]frontend.Variable - for i := 0; i < len(n); i++ { - result[(i+bits)%len(n)] = n[i] - } - return result -} - -func reshape(u []frontend.Variable) [][64]frontend.Variable { - l := divChecked(len(u), 64) - result := make([][64]frontend.Variable, l) - for i := 0; i < l; i++ { - var arr [64]frontend.Variable - for k := 0; k < 64; k++ { - arr[k] = u[i*64+k] - } - result[i] = arr - } - return result -} - -type Array8_64 [8][64]frontend.Variable - -func unpack8(x Array8_64) ([64]frontend.Variable, [64]frontend.Variable, [64]frontend.Variable, [64]frontend.Variable, [64]frontend.Variable, [64]frontend.Variable, [64]frontend.Variable, [64]frontend.Variable) { - return x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7] -} - -func flatten8(x Array8_64) [512]frontend.Variable { - var result [512]frontend.Variable - k := 0 - for i := 0; i < 8; i++ { - for j := 0; j < 64; j++ { - result[k] = x[i][j] - k++ - } - } - return result -} - -func uint64ToBits(value uint64) [64]frontend.Variable { - var result [64]frontend.Variable - for k := 0; k < 64; k++ { - if (value & (1 << (63 - k))) != 0 { - result[k] = 1 - } else { - result[k] = 0 - } - } - return result -} - -func xor(api frontend.API, args ...[64]frontend.Variable) [64]frontend.Variable { - if len(args) == 1 { - return args[0] - } else { - return xor2(api, args[0], xor(api, args[1:]...)) - } -} -func add(api frontend.API, args ...[64]frontend.Variable) [64]frontend.Variable { - if len(args) == 1 { - return args[0] - } else { - return add2(api, args[0], add(api, args[1:]...)) - } -} -func and(api frontend.API, args ...[64]frontend.Variable) [64]frontend.Variable { - if len(args) == 1 { - return args[0] - } else { - return and2(api, args[0], and(api, args[1:]...)) - } -} - -func xor2(api frontend.API, a, b [64]frontend.Variable) [64]frontend.Variable { - var result [64]frontend.Variable - for i := 0; i < 64; i++ { - result[i] = api.Xor(a[i], b[i]) - } - return result -} - -func and2(api frontend.API, a, b [64]frontend.Variable) [64]frontend.Variable { - var result [64]frontend.Variable - for i := 0; i < 64; i++ { - result[i] = api.And(a[i], b[i]) - } - return result -} - -func add2(api frontend.API, a, b [64]frontend.Variable) [64]frontend.Variable { - var result [64]frontend.Variable - var carry frontend.Variable = 0 - for i := 63; i >= 0; i-- { - sum := api.Add(a[i], b[i], carry) - sumBin := api.ToBinary(sum, 2) - if len(sumBin) != 2 { - panic("bad length") - } - result[i] = sumBin[0] - carry = sumBin[1] - } - return result -} - -func _shr(n [64]frontend.Variable, bits int) [64]frontend.Variable { - var result [64]frontend.Variable - for i := 0; i < 64; i++ { - if i < bits { - result[i] = 0 - } else { - result[i] = n[i-bits] - } - } - return result -} - -func not(api frontend.API, n [64]frontend.Variable) [64]frontend.Variable { - var result [64]frontend.Variable - for i := 0; i < 64; i++ { - result[i] = api.Sub(1, n[i]) - } - return result -} - -func divChecked(a, b int) int { - if a%b != 0 { - panic("divChecked: does not divide evenly") - } - return a / b -} diff --git a/sha512/sha512_test.go b/sha512/sha512_test.go deleted file mode 100644 index 4287eca..0000000 --- a/sha512/sha512_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package sha512 - -import ( - "encoding/hex" - "testing" - - "github.com/consensys/gnark-crypto/ecc" - "github.com/consensys/gnark/frontend" - "github.com/consensys/gnark/test" -) - -type TestSha512Circuit struct { - in []frontend.Variable `gnark:"in"` - out []frontend.Variable `gnark:"out"` -} - -func (circuit *TestSha512Circuit) Define(api frontend.API) error { - res := Sha512(api, circuit.in) - if len(res) != 512 { - panic("bad length") - } - for i := 0; i < 512; i++ { - api.AssertIsEqual(res[i], circuit.out[i]) - } - return nil -} - -var testCurve = ecc.BN254 - -func TestSha512Witness(t *testing.T) { - assert := test.NewAssert(t) - - testCase := func(in []byte, output string) { - out, err := hex.DecodeString(output) - if err != nil { - panic(err) - } - if len(out) != 512/8 { - panic("bad output length") - } - - circuit := TestSha512Circuit{ - in: toBits(in), - out: toBits(out), - } - witness := TestSha512Circuit{ - in: toBits(in), - out: toBits(out), - } - err = test.IsSolved(&circuit, &witness, testCurve.ScalarField()) - assert.NoError(err) - } - - testCase([]byte(""), "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e") - testCase([]byte("Succinct Labs"), "503ace098aa03f6feec1b5df0a38aee923f744a775508bc81f2b94ad139be297c2e8cd8c44af527b5d3f017a7fc929892c896604047e52e3f518924f52bff0dc") - testCase(decode("35c323757c20640a294345c89c0bfcebe3d554fdb0c7b7a0bdb72222c531b1ecf7ec1c43f4de9d49556de87b86b26a98942cb078486fdb44de38b80864c3973153756363696e6374204c616273"), "4388243c4452274402673de881b2f942ff5730fd2c7d8ddb94c3e3d789fb3754380cba8faa40554d9506a0730a681e88ab348a04bc5c41d18926f140b59aed39") -} - -func toBits(arr []byte) []frontend.Variable { - result := make([]frontend.Variable, len(arr)*8) - for i, v := range arr { - for j := 0; j < 8; j++ { - if (v & (1 << (7 - j))) != 0 { - result[i*8+j] = 1 - } else { - result[i*8+j] = 0 - } - } - } - return result -} - -func decode(s string) []byte { - result, err := hex.DecodeString(s) - if err != nil { - panic(err) - } - return result -} diff --git a/utils/utils.go b/utils/utils.go index e7b52e3..97952dc 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,7 +1,7 @@ package utils import ( - . "gnark-ed25519/field" + . "gnark-plonky2-verifier/field" "math/big" "github.com/consensys/gnark/frontend"