mirror of
https://github.com/arnaucube/go-circom-prover-verifier.git
synced 2026-02-06 19:06:43 +01:00
Update exposed methods, update README.md, add godoc & goreport cards
This commit is contained in:
27
README.md
27
README.md
@@ -1,5 +1,26 @@
|
|||||||
# go-circom-prover
|
# go-circom-prover [](https://godoc.org/github.com/iden3/go-circom-prover) [](https://goreportcard.com/report/github.com/iden3/go-circom-prover)
|
||||||
Experimental Go zkSNARK prover compatible with [circom](https://github.com/iden3/circom).
|
|
||||||
|
Experimental Go implementation of the [Groth16 protocol](https://eprint.iacr.org/2016/260.pdf) zkSNARK prover compatible with [circom](https://github.com/iden3/circom).
|
||||||
|
|
||||||
|
|
||||||
Using [bn256](https://github.com/ethereum/go-ethereum/tree/master/crypto/bn256/cloudflare) (used by [go-ethereum](https://github.com/ethereum/go-ethereum)) for the Pairing.
|
Using [bn256](https://github.com/ethereum/go-ethereum/tree/master/crypto/bn256/cloudflare) (used by [go-ethereum](https://github.com/ethereum/go-ethereum)) for the Pairing curve operations.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```go
|
||||||
|
// read ProvingKey & Witness files
|
||||||
|
provingKeyJson, _ := ioutil.ReadFile("testdata/provingkey.json")
|
||||||
|
witnessJson, _ := ioutil.ReadFile("testdata/witness.json")
|
||||||
|
|
||||||
|
// parse Proving Key
|
||||||
|
pk, _ := circomprover.ParseProvingKey(provingKeyJson)
|
||||||
|
|
||||||
|
// parse Witness
|
||||||
|
w, _ := circomprover.ParseWitness(witnessJson)
|
||||||
|
|
||||||
|
// generate the proof
|
||||||
|
proof, pubSignals, err := circomprover.GenerateProof(pk, w)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
fmt.Println(pubSignals)
|
||||||
|
fmt.Println(proof)
|
||||||
|
```
|
||||||
|
|||||||
@@ -13,35 +13,35 @@ func arrayOfZeroes(n int) []*big.Int {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func FAdd(a, b *big.Int) *big.Int {
|
func fAdd(a, b *big.Int) *big.Int {
|
||||||
ab := new(big.Int).Add(a, b)
|
ab := new(big.Int).Add(a, b)
|
||||||
return new(big.Int).Mod(ab, R)
|
return new(big.Int).Mod(ab, R)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FSub(a, b *big.Int) *big.Int {
|
func fSub(a, b *big.Int) *big.Int {
|
||||||
ab := new(big.Int).Sub(a, b)
|
ab := new(big.Int).Sub(a, b)
|
||||||
return new(big.Int).Mod(ab, R)
|
return new(big.Int).Mod(ab, R)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FMul(a, b *big.Int) *big.Int {
|
func fMul(a, b *big.Int) *big.Int {
|
||||||
ab := new(big.Int).Mul(a, b)
|
ab := new(big.Int).Mul(a, b)
|
||||||
return new(big.Int).Mod(ab, R)
|
return new(big.Int).Mod(ab, R)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FDiv(a, b *big.Int) *big.Int {
|
func fDiv(a, b *big.Int) *big.Int {
|
||||||
ab := new(big.Int).Mul(a, new(big.Int).ModInverse(b, R))
|
ab := new(big.Int).Mul(a, new(big.Int).ModInverse(b, R))
|
||||||
return new(big.Int).Mod(ab, R)
|
return new(big.Int).Mod(ab, R)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FNeg(a *big.Int) *big.Int {
|
func fNeg(a *big.Int) *big.Int {
|
||||||
return new(big.Int).Mod(new(big.Int).Neg(a), R)
|
return new(big.Int).Mod(new(big.Int).Neg(a), R)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FInv(a *big.Int) *big.Int {
|
func fInv(a *big.Int) *big.Int {
|
||||||
return new(big.Int).ModInverse(a, R)
|
return new(big.Int).ModInverse(a, R)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FExp(base *big.Int, e *big.Int) *big.Int {
|
func fExp(base *big.Int, e *big.Int) *big.Int {
|
||||||
res := big.NewInt(1)
|
res := big.NewInt(1)
|
||||||
rem := new(big.Int).Set(e)
|
rem := new(big.Int).Set(e)
|
||||||
exp := base
|
exp := base
|
||||||
@@ -49,9 +49,9 @@ func FExp(base *big.Int, e *big.Int) *big.Int {
|
|||||||
for !bytes.Equal(rem.Bytes(), big.NewInt(int64(0)).Bytes()) {
|
for !bytes.Equal(rem.Bytes(), big.NewInt(int64(0)).Bytes()) {
|
||||||
// if BigIsOdd(rem) {
|
// if BigIsOdd(rem) {
|
||||||
if rem.Bit(0) == 1 { // .Bit(0) returns 1 when is odd
|
if rem.Bit(0) == 1 { // .Bit(0) returns 1 when is odd
|
||||||
res = FMul(res, exp)
|
res = fMul(res, exp)
|
||||||
}
|
}
|
||||||
exp = FMul(exp, exp)
|
exp = fMul(exp, exp)
|
||||||
rem = new(big.Int).Rsh(rem, 1)
|
rem = new(big.Int).Rsh(rem, 1)
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
@@ -64,38 +64,38 @@ func max(a, b int) int {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func PolynomialSub(a, b []*big.Int) []*big.Int {
|
func polynomialSub(a, b []*big.Int) []*big.Int {
|
||||||
r := arrayOfZeroes(max(len(a), len(b)))
|
r := arrayOfZeroes(max(len(a), len(b)))
|
||||||
for i := 0; i < len(a); i++ {
|
for i := 0; i < len(a); i++ {
|
||||||
r[i] = FAdd(r[i], a[i])
|
r[i] = fAdd(r[i], a[i])
|
||||||
}
|
}
|
||||||
for i := 0; i < len(b); i++ {
|
for i := 0; i < len(b); i++ {
|
||||||
r[i] = FSub(r[i], b[i])
|
r[i] = fSub(r[i], b[i])
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func PolynomialMul(a, b []*big.Int) []*big.Int {
|
func polynomialMul(a, b []*big.Int) []*big.Int {
|
||||||
r := arrayOfZeroes(len(a) + len(b) - 1)
|
r := arrayOfZeroes(len(a) + len(b) - 1)
|
||||||
for i := 0; i < len(a); i++ {
|
for i := 0; i < len(a); i++ {
|
||||||
for j := 0; j < len(b); j++ {
|
for j := 0; j < len(b); j++ {
|
||||||
r[i+j] = FAdd(r[i+j], FMul(a[i], b[j]))
|
r[i+j] = fAdd(r[i+j], fMul(a[i], b[j]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func PolynomialDiv(a, b []*big.Int) ([]*big.Int, []*big.Int) {
|
func polynomialDiv(a, b []*big.Int) ([]*big.Int, []*big.Int) {
|
||||||
// https://en.wikipedia.org/wiki/Division_algorithm
|
// https://en.wikipedia.org/wiki/Division_algorithm
|
||||||
r := arrayOfZeroes(len(a) - len(b) + 1)
|
r := arrayOfZeroes(len(a) - len(b) + 1)
|
||||||
rem := a
|
rem := a
|
||||||
for len(rem) >= len(b) {
|
for len(rem) >= len(b) {
|
||||||
l := FDiv(rem[len(rem)-1], b[len(b)-1])
|
l := fDiv(rem[len(rem)-1], b[len(b)-1])
|
||||||
pos := len(rem) - len(b)
|
pos := len(rem) - len(b)
|
||||||
r[pos] = l
|
r[pos] = l
|
||||||
aux := arrayOfZeroes(pos)
|
aux := arrayOfZeroes(pos)
|
||||||
aux1 := append(aux, l)
|
aux1 := append(aux, l)
|
||||||
aux2 := PolynomialSub(rem, PolynomialMul(b, aux1))
|
aux2 := polynomialSub(rem, polynomialMul(b, aux1))
|
||||||
rem = aux2[:len(aux2)-1]
|
rem = aux2[:len(aux2)-1]
|
||||||
}
|
}
|
||||||
return r, rem
|
return r, rem
|
||||||
|
|||||||
6
go.mod
6
go.mod
@@ -1,10 +1,8 @@
|
|||||||
module gocircom
|
module gocircomprover
|
||||||
|
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
replace github.com/ethereum/go-ethereum => ../go-ethereum
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ethereum/go-ethereum v1.9.12
|
github.com/ethereum/go-ethereum v1.9.12
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.5.1
|
||||||
)
|
)
|
||||||
|
|||||||
15
go.sum
15
go.sum
@@ -40,6 +40,8 @@ github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r
|
|||||||
github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA=
|
github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA=
|
||||||
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
|
github.com/ethereum/go-ethereum v1.9.12 h1:EPtimwsp/KGDSiXcNunzsI4kefdsMHZGJntKx3fvbaI=
|
||||||
|
github.com/ethereum/go-ethereum v1.9.12/go.mod h1:PvsVkQmhZFx92Y+h2ylythYlheEDt/uBgFbl61Js/jo=
|
||||||
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
@@ -109,22 +111,26 @@ github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUW
|
|||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||||
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA=
|
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA=
|
||||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
|
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 h1:LepdCS8Gf/MVejFIt8lsiexZATdoGVyp5bcyS+rYoUI=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
|
||||||
|
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@@ -135,7 +141,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
|
|||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|||||||
22
ifft.go
22
ifft.go
@@ -21,30 +21,28 @@ func newRootsT() rootsT {
|
|||||||
rem = new(big.Int).Rsh(rem, 1)
|
rem = new(big.Int).Rsh(rem, 1)
|
||||||
}
|
}
|
||||||
roots.w = make([]*big.Int, s+1)
|
roots.w = make([]*big.Int, s+1)
|
||||||
roots.w[s] = FExp(big.NewInt(5), rem)
|
roots.w[s] = fExp(big.NewInt(5), rem)
|
||||||
|
|
||||||
n := s - 1
|
n := s - 1
|
||||||
for n >= 0 {
|
for n >= 0 {
|
||||||
roots.w[n] = FMul(roots.w[n+1], roots.w[n+1])
|
roots.w[n] = fMul(roots.w[n+1], roots.w[n+1])
|
||||||
n--
|
n--
|
||||||
}
|
}
|
||||||
roots.roots = make([][]*big.Int, 50)
|
roots.roots = make([][]*big.Int, 50) // TODO WIP
|
||||||
|
|
||||||
roots.setRoots(15)
|
roots.setRoots(15)
|
||||||
return roots
|
return roots
|
||||||
}
|
}
|
||||||
|
|
||||||
func (roots rootsT) setRoots(n int) {
|
func (roots rootsT) setRoots(n int) {
|
||||||
// var roots []bool
|
|
||||||
for i := n; i >= 0 && nil == roots.roots[i]; i-- { // TODO tmp i<=len(r)
|
for i := n; i >= 0 && nil == roots.roots[i]; i-- { // TODO tmp i<=len(r)
|
||||||
r := big.NewInt(1)
|
r := big.NewInt(1)
|
||||||
nroots := 1 << i
|
nroots := 1 << i
|
||||||
var rootsi []*big.Int
|
var rootsi []*big.Int
|
||||||
for j := 0; j < nroots; j++ {
|
for j := 0; j < nroots; j++ {
|
||||||
rootsi = append(rootsi, r)
|
rootsi = append(rootsi, r)
|
||||||
r = FMul(r, roots.w[i])
|
r = fMul(r, roots.w[i])
|
||||||
}
|
}
|
||||||
// fmt.Println("rootsi", rootsi)
|
|
||||||
roots.roots[i] = rootsi
|
roots.roots[i] = rootsi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,8 +53,8 @@ func fft(roots rootsT, pall []*big.Int, bits, offset, step int) []*big.Int {
|
|||||||
return []*big.Int{pall[offset]}
|
return []*big.Int{pall[offset]}
|
||||||
} else if n == 2 {
|
} else if n == 2 {
|
||||||
return []*big.Int{
|
return []*big.Int{
|
||||||
FAdd(pall[offset], pall[offset+step]), // TODO tmp
|
fAdd(pall[offset], pall[offset+step]), // TODO tmp
|
||||||
FSub(pall[offset], pall[offset+step]),
|
fSub(pall[offset], pall[offset+step]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,8 +66,8 @@ func fft(roots rootsT, pall []*big.Int, bits, offset, step int) []*big.Int {
|
|||||||
out := make([]*big.Int, n)
|
out := make([]*big.Int, n)
|
||||||
for i := 0; i < ndiv2; i++ {
|
for i := 0; i < ndiv2; i++ {
|
||||||
fmt.Println(i, len(roots.roots))
|
fmt.Println(i, len(roots.roots))
|
||||||
out[i] = FAdd(p1[i], FMul(roots.roots[bits][i], p2[i]))
|
out[i] = fAdd(p1[i], fMul(roots.roots[bits][i], p2[i]))
|
||||||
out[i+ndiv2] = FSub(p1[i], FMul(roots.roots[bits][i], p2[i]))
|
out[i+ndiv2] = fSub(p1[i], fMul(roots.roots[bits][i], p2[i]))
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@@ -85,11 +83,11 @@ func ifft(p []*big.Int) []*big.Int {
|
|||||||
ep := extend(p, m)
|
ep := extend(p, m)
|
||||||
res := fft(roots, ep, int(bits), 0, 1)
|
res := fft(roots, ep, int(bits), 0, 1)
|
||||||
|
|
||||||
twoinvm := FInv(FMul(big.NewInt(1), big.NewInt(int64(m))))
|
twoinvm := fInv(fMul(big.NewInt(1), big.NewInt(int64(m))))
|
||||||
|
|
||||||
var resn []*big.Int
|
var resn []*big.Int
|
||||||
for i := 0; i < m; i++ {
|
for i := 0; i < m; i++ {
|
||||||
resn = append(resn, FMul(res[(m-i)%m], twoinvm))
|
resn = append(resn, fMul(res[(m-i)%m], twoinvm))
|
||||||
}
|
}
|
||||||
|
|
||||||
return resn
|
return resn
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
|
bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ProvingKeyString is the equivalent to the ProvingKey struct in string representation
|
||||||
type ProvingKeyString struct {
|
type ProvingKeyString struct {
|
||||||
A [][]string `json:"A"`
|
A [][]string `json:"A"`
|
||||||
B2 [][][]string `json:"B2"`
|
B2 [][][]string `json:"B2"`
|
||||||
@@ -31,8 +32,10 @@ type ProvingKeyString struct {
|
|||||||
PolsC []map[string]string `json:"polsC"`
|
PolsC []map[string]string `json:"polsC"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WitnessString contains the Witness in string representation
|
||||||
type WitnessString []string
|
type WitnessString []string
|
||||||
|
|
||||||
|
// ParseWitness parses the json []byte data into the Witness struct
|
||||||
func ParseWitness(wJson []byte) (Witness, error) {
|
func ParseWitness(wJson []byte) (Witness, error) {
|
||||||
var ws WitnessString
|
var ws WitnessString
|
||||||
err := json.Unmarshal(wJson, &ws)
|
err := json.Unmarshal(wJson, &ws)
|
||||||
@@ -51,6 +54,7 @@ func ParseWitness(wJson []byte) (Witness, error) {
|
|||||||
return w, nil
|
return w, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseProvingKey parses the json []byte data into the ProvingKey struct
|
||||||
func ParseProvingKey(pkJson []byte) (*ProvingKey, error) {
|
func ParseProvingKey(pkJson []byte) (*ProvingKey, error) {
|
||||||
var pkStr ProvingKeyString
|
var pkStr ProvingKeyString
|
||||||
err := json.Unmarshal(pkJson, &pkStr)
|
err := json.Unmarshal(pkJson, &pkStr)
|
||||||
|
|||||||
@@ -8,22 +8,22 @@ import (
|
|||||||
|
|
||||||
func TestParseArrayG1(t *testing.T) {
|
func TestParseArrayG1(t *testing.T) {
|
||||||
aS := [][]string{
|
aS := [][]string{
|
||||||
[]string{
|
{
|
||||||
"16145916318196730299582072104388453231952213805668281741813587224450782397538",
|
"16145916318196730299582072104388453231952213805668281741813587224450782397538",
|
||||||
"4434505318477484327659527264104806919103674231447634885054368605283938696207",
|
"4434505318477484327659527264104806919103674231447634885054368605283938696207",
|
||||||
"1",
|
"1",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"10618406967550056457559358662746625591602641004174976323307214433994084907915",
|
"10618406967550056457559358662746625591602641004174976323307214433994084907915",
|
||||||
"1843236360452735081347085412539192450068665510574800388201121698908391533923",
|
"1843236360452735081347085412539192450068665510574800388201121698908391533923",
|
||||||
"1",
|
"1",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"1208972877970123411566574123860641832032384890981476033353526096830198333194",
|
"1208972877970123411566574123860641832032384890981476033353526096830198333194",
|
||||||
"777503551507025252294438107100944741641946695980350712141258191590862204805",
|
"777503551507025252294438107100944741641946695980350712141258191590862204805",
|
||||||
"1",
|
"1",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"0",
|
"0",
|
||||||
"1",
|
"1",
|
||||||
"0",
|
"0",
|
||||||
@@ -40,15 +40,15 @@ func TestParseArrayG1(t *testing.T) {
|
|||||||
|
|
||||||
func TestParseG2(t *testing.T) {
|
func TestParseG2(t *testing.T) {
|
||||||
aS := [][]string{
|
aS := [][]string{
|
||||||
[]string{
|
{
|
||||||
"9283666785342556550467669770956850930982548182701254051508520248901282197973",
|
"9283666785342556550467669770956850930982548182701254051508520248901282197973",
|
||||||
"11369378229277445316894458966429873744779877313900506577160370623273013178252",
|
"11369378229277445316894458966429873744779877313900506577160370623273013178252",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"10625777544326349817513295021482494426101347915428005055375725845993157551870",
|
"10625777544326349817513295021482494426101347915428005055375725845993157551870",
|
||||||
"21401790227434807639472120486932615400751346915707967674912972446672152512583",
|
"21401790227434807639472120486932615400751346915707967674912972446672152512583",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"1",
|
"1",
|
||||||
"0",
|
"0",
|
||||||
},
|
},
|
||||||
@@ -59,15 +59,15 @@ func TestParseG2(t *testing.T) {
|
|||||||
assert.Equal(t, "bn256.G2((1922d70c934543aa655ec3277f7fa10a25ec973a4f001a7c54ce4954b4916f8c, 14865e836947c42cf35b47d30e06535fff9dab319c4296e28afde368960671d5), (2f50fbe77925b0a9d718c9ab38638bafa7c65f43f0d09035e518df97ad294847, 177dfa1a3b8627faf0425d9511bcb4c6ca986ea05e3803b5c643c35b94a7e6fe))", a.String())
|
assert.Equal(t, "bn256.G2((1922d70c934543aa655ec3277f7fa10a25ec973a4f001a7c54ce4954b4916f8c, 14865e836947c42cf35b47d30e06535fff9dab319c4296e28afde368960671d5), (2f50fbe77925b0a9d718c9ab38638bafa7c65f43f0d09035e518df97ad294847, 177dfa1a3b8627faf0425d9511bcb4c6ca986ea05e3803b5c643c35b94a7e6fe))", a.String())
|
||||||
|
|
||||||
aS = [][]string{
|
aS = [][]string{
|
||||||
[]string{
|
{
|
||||||
"13973091636763944887728510851169742544309374663995476311690518173988838518856",
|
"13973091636763944887728510851169742544309374663995476311690518173988838518856",
|
||||||
"12903946180439304546475897520537621821375470264150438270817301786763517825250",
|
"12903946180439304546475897520537621821375470264150438270817301786763517825250",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"370374369234123593044872519351942112043402224488849374153134091815693350697",
|
"370374369234123593044872519351942112043402224488849374153134091815693350697",
|
||||||
"17423079115073430837335625309232513526393852743032331213038909731579295753224",
|
"17423079115073430837335625309232513526393852743032331213038909731579295753224",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"1",
|
"1",
|
||||||
"0",
|
"0",
|
||||||
},
|
},
|
||||||
@@ -79,58 +79,58 @@ func TestParseG2(t *testing.T) {
|
|||||||
|
|
||||||
func TestParseArrayG2(t *testing.T) {
|
func TestParseArrayG2(t *testing.T) {
|
||||||
aS := [][][]string{
|
aS := [][][]string{
|
||||||
[][]string{
|
{
|
||||||
[]string{
|
{
|
||||||
"0",
|
"0",
|
||||||
"0",
|
"0",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"1",
|
"1",
|
||||||
"0",
|
"0",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"0",
|
"0",
|
||||||
"0",
|
"0",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[][]string{
|
{
|
||||||
[]string{
|
{
|
||||||
"0",
|
"0",
|
||||||
"0",
|
"0",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"1",
|
"1",
|
||||||
"0",
|
"0",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"0",
|
"0",
|
||||||
"0",
|
"0",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[][]string{
|
{
|
||||||
[]string{
|
{
|
||||||
"0",
|
"0",
|
||||||
"0",
|
"0",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"1",
|
"1",
|
||||||
"0",
|
"0",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"0",
|
"0",
|
||||||
"0",
|
"0",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[][]string{
|
{
|
||||||
[]string{
|
{
|
||||||
"9283666785342556550467669770956850930982548182701254051508520248901282197973",
|
"9283666785342556550467669770956850930982548182701254051508520248901282197973",
|
||||||
"11369378229277445316894458966429873744779877313900506577160370623273013178252",
|
"11369378229277445316894458966429873744779877313900506577160370623273013178252",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"10625777544326349817513295021482494426101347915428005055375725845993157551870",
|
"10625777544326349817513295021482494426101347915428005055375725845993157551870",
|
||||||
"21401790227434807639472120486932615400751346915707967674912972446672152512583",
|
"21401790227434807639472120486932615400751346915707967674912972446672152512583",
|
||||||
},
|
},
|
||||||
[]string{
|
{
|
||||||
"1",
|
"1",
|
||||||
"0",
|
"0",
|
||||||
},
|
},
|
||||||
|
|||||||
31
prover.go
31
prover.go
@@ -8,12 +8,14 @@ import (
|
|||||||
bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
|
bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Proof is the data structure of the Groth16 zkSNARK proof
|
||||||
type Proof struct {
|
type Proof struct {
|
||||||
A *bn256.G1
|
A *bn256.G1
|
||||||
B *bn256.G2
|
B *bn256.G2
|
||||||
C *bn256.G1
|
C *bn256.G1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProvingKey holds the data structure of the provingKey
|
||||||
type ProvingKey struct {
|
type ProvingKey struct {
|
||||||
A []*bn256.G1
|
A []*bn256.G1
|
||||||
B2 []*bn256.G2
|
B2 []*bn256.G2
|
||||||
@@ -33,11 +35,13 @@ type ProvingKey struct {
|
|||||||
PolsC []map[int]*big.Int
|
PolsC []map[int]*big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Witness contains the witness
|
||||||
type Witness []*big.Int
|
type Witness []*big.Int
|
||||||
|
|
||||||
|
// R is the mod of the finite field
|
||||||
var R, _ = new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
|
var R, _ = new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
|
||||||
|
|
||||||
func RandBigInt() (*big.Int, error) {
|
func randBigInt() (*big.Int, error) {
|
||||||
maxbits := R.BitLen()
|
maxbits := R.BitLen()
|
||||||
b := make([]byte, (maxbits/8)-1)
|
b := make([]byte, (maxbits/8)-1)
|
||||||
_, err := rand.Read(b)
|
_, err := rand.Read(b)
|
||||||
@@ -50,14 +54,15 @@ func RandBigInt() (*big.Int, error) {
|
|||||||
return rq, nil
|
return rq, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Prove(pk *ProvingKey, w Witness) (*Proof, []*big.Int, error) {
|
// GenerateProof generates the Groth16 zkSNARK proof
|
||||||
|
func GenerateProof(pk *ProvingKey, w Witness) (*Proof, []*big.Int, error) {
|
||||||
var proof Proof
|
var proof Proof
|
||||||
|
|
||||||
r, err := RandBigInt()
|
r, err := randBigInt()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
s, err := RandBigInt()
|
s, err := randBigInt()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@@ -95,7 +100,7 @@ func Prove(pk *ProvingKey, w Witness) (*Proof, []*big.Int, error) {
|
|||||||
}
|
}
|
||||||
proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(proof.A, s))
|
proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(proof.A, s))
|
||||||
proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(proofBG1, r))
|
proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(proofBG1, r))
|
||||||
rsneg := new(big.Int).Mod(new(big.Int).Neg(new(big.Int).Mul(r, s)), R) // FAdd & FMul
|
rsneg := new(big.Int).Mod(new(big.Int).Neg(new(big.Int).Mul(r, s)), R) // fAdd & fMul
|
||||||
proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(pk.VkDelta1, rsneg))
|
proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(pk.VkDelta1, rsneg))
|
||||||
|
|
||||||
pubSignals := w[1 : pk.NPublic+1]
|
pubSignals := w[1 : pk.NPublic+1]
|
||||||
@@ -110,23 +115,23 @@ func calculateH(pk *ProvingKey, w Witness) []*big.Int {
|
|||||||
polCT := arrayOfZeroes(m)
|
polCT := arrayOfZeroes(m)
|
||||||
|
|
||||||
for i := 0; i < pk.NVars; i++ {
|
for i := 0; i < pk.NVars; i++ {
|
||||||
for j, _ := range pk.PolsA[i] {
|
for j := range pk.PolsA[i] {
|
||||||
polAT[j] = FAdd(polAT[j], FMul(w[i], pk.PolsA[i][j]))
|
polAT[j] = fAdd(polAT[j], fMul(w[i], pk.PolsA[i][j]))
|
||||||
fmt.Println(polAT[j])
|
fmt.Println(polAT[j])
|
||||||
}
|
}
|
||||||
for j, _ := range pk.PolsB[i] {
|
for j := range pk.PolsB[i] {
|
||||||
polBT[j] = FAdd(polBT[j], FMul(w[i], pk.PolsB[i][j]))
|
polBT[j] = fAdd(polBT[j], fMul(w[i], pk.PolsB[i][j]))
|
||||||
}
|
}
|
||||||
for j, _ := range pk.PolsC[i] {
|
for j := range pk.PolsC[i] {
|
||||||
polCT[j] = FAdd(polCT[j], FMul(w[i], pk.PolsC[i][j]))
|
polCT[j] = fAdd(polCT[j], fMul(w[i], pk.PolsC[i][j]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
polAS := ifft(polAT)
|
polAS := ifft(polAT)
|
||||||
polBS := ifft(polBT)
|
polBS := ifft(polBT)
|
||||||
|
|
||||||
polABS := PolynomialMul(polAS, polBS)
|
polABS := polynomialMul(polAS, polBS)
|
||||||
polCS := ifft(polCT)
|
polCS := ifft(polCT)
|
||||||
polABCS := PolynomialSub(polABS, polCS)
|
polABCS := polynomialSub(polABS, polCS)
|
||||||
|
|
||||||
hS := polABCS[m:]
|
hS := polABCS[m:]
|
||||||
return hS
|
return hS
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestProve(t *testing.T) {
|
func TestGenerateProf(t *testing.T) {
|
||||||
provingKeyJson, err := ioutil.ReadFile("testdata/provingkey.json")
|
provingKeyJson, err := ioutil.ReadFile("testdata/provingkey.json")
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
pk, err := ParseProvingKey(provingKeyJson)
|
pk, err := ParseProvingKey(provingKeyJson)
|
||||||
@@ -28,7 +28,7 @@ func TestProve(t *testing.T) {
|
|||||||
fmt.Println("w", w)
|
fmt.Println("w", w)
|
||||||
assert.Equal(t, Witness{big.NewInt(1), big.NewInt(33), big.NewInt(3), big.NewInt(11)}, w)
|
assert.Equal(t, Witness{big.NewInt(1), big.NewInt(33), big.NewInt(3), big.NewInt(11)}, w)
|
||||||
|
|
||||||
proof, pubSignals, err := Prove(pk, w)
|
proof, pubSignals, err := GenerateProof(pk, w)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
fmt.Println("proof", proof)
|
fmt.Println("proof", proof)
|
||||||
fmt.Println("pubSignals", pubSignals)
|
fmt.Println("pubSignals", pubSignals)
|
||||||
|
|||||||
Reference in New Issue
Block a user