Browse Source

Cleanup repo for release

main
John Guibas 2 years ago
parent
commit
6e9f1a7c50
33 changed files with 38 additions and 2324 deletions
  1. +4
    -13
      README.md
  2. +0
    -74
      cubic.go
  3. +0
    -277
      ed25519.go
  4. +0
    -297
      edwards_curve/eddsa25519.go
  5. +0
    -65
      edwards_curve/eddsa25519_test.go
  6. +0
    -34
      edwards_curve/edparams.go
  7. +0
    -201
      edwards_curve/edpoint.go
  8. +0
    -230
      edwards_curve/edpoint_test.go
  9. +0
    -94
      fibonacci.go
  10. +0
    -407
      fri_benchmark.go
  11. +1
    -1
      go.mod
  12. +0
    -132
      plonk_benchmark.go
  13. +2
    -2
      plonky2_verifier/challenger.go
  14. +4
    -4
      plonky2_verifier/challenger_test.go
  15. +2
    -2
      plonky2_verifier/deserialize.go
  16. +3
    -3
      plonky2_verifier/fri.go
  17. +2
    -2
      plonky2_verifier/fri_test.go
  18. +2
    -2
      plonky2_verifier/fri_utils.go
  19. +1
    -1
      plonky2_verifier/hash.go
  20. +1
    -1
      plonky2_verifier/plonk.go
  21. +1
    -1
      plonky2_verifier/plonk_test.go
  22. +1
    -1
      plonky2_verifier/quadratic_extension.go
  23. +2
    -2
      plonky2_verifier/quadratic_extension_test.go
  24. +1
    -1
      plonky2_verifier/structs.go
  25. +2
    -2
      plonky2_verifier/verifier.go
  26. +2
    -2
      plonky2_verifier/verifier_test.go
  27. +0
    -94
      plonky2_verifier_benchmark.go
  28. +1
    -1
      poseidon/poseidon.go
  29. +3
    -3
      poseidon/poseidon_test.go
  30. +2
    -2
      poseidon/public_inputs_hash_test.go
  31. +0
    -293
      sha512/sha512.go
  32. +0
    -79
      sha512/sha512_test.go
  33. +1
    -1
      utils/utils.go

+ 4
- 13
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
```

+ 0
- 74
cubic.go

@ -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
// }

+ 0
- 277
ed25519.go

@ -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)
}
}

+ 0
- 297
edwards_curve/eddsa25519.go

@ -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

+ 0
- 65
edwards_curve/eddsa25519_test.go

@ -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
}

+ 0
- 34
edwards_curve/edparams.go

@ -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 }

+ 0
- 201
edwards_curve/edpoint.go

@ -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
}

+ 0
- 230
edwards_curve/edpoint_test.go

@ -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)
// }

+ 0
- 94
fibonacci.go

@ -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())
}

+ 0
- 407
fri_benchmark.go

@ -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())
}

+ 1
- 1
go.mod

@ -1,4 +1,4 @@
module gnark-ed25519
module gnark-plonky2-verifier
go 1.19

+ 0
- 132
plonk_benchmark.go

@ -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())
}

+ 2
- 2
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"
)

+ 4
- 4
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"

+ 2
- 2
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"
)

+ 3
- 3
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"

+ 2
- 2
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"

+ 2
- 2
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 {

+ 1
- 1
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"
)

+ 1
- 1
plonky2_verifier/plonk.go

@ -1,7 +1,7 @@
package plonky2_verifier
import (
. "gnark-ed25519/field"
. "gnark-plonky2-verifier/field"
"github.com/consensys/gnark/frontend"
)

+ 1
- 1
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"

+ 1
- 1
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"

+ 2
- 2
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"

+ 1
- 1
plonky2_verifier/structs.go

@ -1,7 +1,7 @@
package plonky2_verifier
import (
. "gnark-ed25519/field"
. "gnark-plonky2-verifier/field"
)
type MerkleCap = []Hash

+ 2
- 2
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"
)

+ 2
- 2
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"

+ 0
- 94
plonky2_verifier_benchmark.go

@ -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())
}

+ 1
- 1
poseidon/poseidon.go

@ -1,7 +1,7 @@
package poseidon
import (
. "gnark-ed25519/field"
. "gnark-plonky2-verifier/field"
"github.com/consensys/gnark/frontend"
)

+ 3
- 3
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"

+ 2
- 2
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"

+ 0
- 293
sha512/sha512.go

@ -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
}

+ 0
- 79
sha512/sha512_test.go

@ -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
}

+ 1
- 1
utils/utils.go

@ -1,7 +1,7 @@
package utils
import (
. "gnark-ed25519/field"
. "gnark-plonky2-verifier/field"
"math/big"
"github.com/consensys/gnark/frontend"

Loading…
Cancel
Save