Browse Source

add wasm for Groth16 proof generation & verification

pull/14/head
arnaucube 4 years ago
parent
commit
e98a97e9fe
6 changed files with 289 additions and 2 deletions
  1. +1
    -1
      circuitexamples/factor.circuit
  2. +1
    -1
      circuitexamples/function.circuit
  3. +2
    -0
      wasm/README.md
  4. +124
    -0
      wasm/go-snark-wasm-wrapper.go
  5. BIN
      wasm/go-snark.wasm
  6. +161
    -0
      wasm/utils/utils.go

+ 1
- 1
circuitexamples/factor.circuit

@ -1,4 +1,4 @@
func test(private a, private b, public c):
func main(private a, private b, public c):
d = a * b
equals(c, d)
out = 1 * 1

+ 1
- 1
circuitexamples/function.circuit

@ -1,4 +1,4 @@
func test(private s0, public s1):
func main(private s0, public s1):
s2 = s0 * s0
s3 = s2 * s0
s4 = s3 + s0

+ 2
- 0
wasm/README.md

@ -1,6 +1,8 @@
# go-snark wasm
*Warning: this is an ongoing experimentation*
WASM wrappers for zkSNARK Pinocchio & Groth16 protocols.
## Wasm usage
To compile to wasm, inside the `wasm` directory, execute:
```

+ 124
- 0
wasm/go-snark-wasm-wrapper.go

@ -7,6 +7,7 @@ import (
"github.com/arnaucube/go-snark"
"github.com/arnaucube/go-snark/circuitcompiler"
"github.com/arnaucube/go-snark/groth16"
"github.com/arnaucube/go-snark/wasm/utils"
)
@ -20,6 +21,8 @@ func main() {
func registerCallbacks() {
js.Global().Set("generateProofs", js.FuncOf(generateProofs))
js.Global().Set("verifyProofs", js.FuncOf(verifyProofs))
js.Global().Set("grothGenerateProofs", js.FuncOf(grothGenerateProofs))
js.Global().Set("grothVerifyProofs", js.FuncOf(grothVerifyProofs))
}
func generateProofs(this js.Value, i []js.Value) interface{} {
@ -142,3 +145,124 @@ func verifyProofs(this js.Value, i []js.Value) interface{} {
println("verifiedJson", string(verifiedJson))
return js.ValueOf(string(verifiedJson))
}
func grothGenerateProofs(this js.Value, i []js.Value) interface{} {
var circuitStr utils.CircuitString
err := json.Unmarshal([]byte(i[0].String()), &circuitStr)
if err != nil {
println(i[0].String())
println("error parsing circuit from stringified json")
}
circuit, err := utils.CircuitFromString(circuitStr)
if err != nil {
println("error " + err.Error())
}
sj, err := json.Marshal(circuit)
if err != nil {
println("error " + err.Error())
}
println("circuit", string(sj))
var setupStr utils.GrothSetupString
println(i[1].String())
err = json.Unmarshal([]byte(i[1].String()), &setupStr)
if err != nil {
println("error parsing setup from stringified json")
}
setup, err := utils.GrothSetupFromString(setupStr)
if err != nil {
println("error " + err.Error())
}
sj, err = json.Marshal(setup)
if err != nil {
println("error " + err.Error())
}
println("set", string(sj))
var pxStr []string
err = json.Unmarshal([]byte(i[2].String()), &pxStr)
if err != nil {
println("error parsing pxStr from stringified json")
}
px, err := utils.ArrayStringToBigInt(pxStr)
if err != nil {
println(err.Error())
}
sj, err = json.Marshal(px)
if err != nil {
println("error " + err.Error())
}
println("px", string(sj))
var inputs circuitcompiler.Inputs
err = json.Unmarshal([]byte(i[3].String()), &inputs)
if err != nil {
println("error parsing inputs from stringified json")
}
w, err := circuit.CalculateWitness(inputs.Private, inputs.Public)
proof, err := groth16.GenerateProofs(circuit, setup, w, px)
if err != nil {
println("error generating proof", err)
}
proofString := utils.GrothProofToString(proof)
proofJson, err := json.Marshal(proofString)
if err != nil {
println("error marshal proof to json", err)
}
println("proofJson", string(proofJson))
return js.ValueOf(string(proofJson))
}
func grothVerifyProofs(this js.Value, i []js.Value) interface{} {
var circuitStr utils.CircuitString
err := json.Unmarshal([]byte(i[0].String()), &circuitStr)
if err != nil {
println(i[0].String())
println("error parsing circuit from stringified json")
}
circuit, err := utils.CircuitFromString(circuitStr)
if err != nil {
println("error " + err.Error())
}
var setupStr utils.GrothSetupString
println(i[1].String())
err = json.Unmarshal([]byte(i[1].String()), &setupStr)
if err != nil {
println("error parsing setup from stringified json")
}
setup, err := utils.GrothSetupFromString(setupStr)
if err != nil {
println("error " + err.Error())
}
var proofStr utils.GrothProofString
err = json.Unmarshal([]byte(i[2].String()), &proofStr)
if err != nil {
println(i[0].String())
println("error parsing proof from stringified json")
}
proof, err := utils.GrothProofFromString(proofStr)
if err != nil {
println("error " + err.Error())
}
var publicInputs []*big.Int
err = json.Unmarshal([]byte(i[3].String()), &publicInputs)
if err != nil {
println(i[0].String())
println("error parsing publicInputs from stringified json")
}
verified := groth16.VerifyProof(circuit, setup, proof, publicInputs, false)
if err != nil {
println("error verifiyng proof", err)
}
verifiedJson, err := json.Marshal(verified)
if err != nil {
println("error marshal verified to json", err)
}
println("verifiedJson", string(verifiedJson))
return js.ValueOf(string(verifiedJson))
}

BIN
wasm/go-snark.wasm


+ 161
- 0
wasm/utils/utils.go

@ -6,6 +6,7 @@ import (
snark "github.com/arnaucube/go-snark"
"github.com/arnaucube/go-snark/circuitcompiler"
"github.com/arnaucube/go-snark/groth16"
)
// []*big.Int
@ -401,3 +402,163 @@ func ProofFromString(s ProofString) (snark.Proof, error) {
}
return p, nil
}
// groth
type GrothSetupString struct {
Pk struct { // Proving Key
BACDelta [][3]string
Z []string
G1 struct {
Alpha [3]string
Beta [3]string
Delta [3]string
At [][3]string
BACGamma [][3]string
}
G2 struct {
Beta [3][2]string
Gamma [3][2]string
Delta [3][2]string
BACGamma [][3][2]string
}
PowersTauDelta [][3]string
}
Vk struct {
IC [][3]string
G1 struct {
Alpha [3]string
}
G2 struct {
Beta [3][2]string
Gamma [3][2]string
Delta [3][2]string
}
}
}
func GrothSetupToString(setup groth16.Setup) GrothSetupString {
var s GrothSetupString
s.Pk.BACDelta = Array3BigIntToString(setup.Pk.BACDelta)
s.Pk.Z = ArrayBigIntToString(setup.Pk.Z)
s.Pk.G1.Alpha = BigInt3ToString(setup.Pk.G1.Alpha)
s.Pk.G1.Beta = BigInt3ToString(setup.Pk.G1.Beta)
s.Pk.G1.Delta = BigInt3ToString(setup.Pk.G1.Delta)
s.Pk.G1.At = Array3BigIntToString(setup.Pk.G1.At)
s.Pk.G1.BACGamma = Array3BigIntToString(setup.Pk.G1.BACGamma)
s.Pk.G2.Beta = BigInt32ToString(setup.Pk.G2.Beta)
s.Pk.G2.Gamma = BigInt32ToString(setup.Pk.G2.Gamma)
s.Pk.G2.Delta = BigInt32ToString(setup.Pk.G2.Delta)
s.Pk.G2.BACGamma = Array32BigIntToString(setup.Pk.G2.BACGamma)
s.Pk.PowersTauDelta = Array3BigIntToString(setup.Pk.PowersTauDelta)
s.Vk.IC = Array3BigIntToString(setup.Vk.IC)
s.Vk.G1.Alpha = BigInt3ToString(setup.Vk.G1.Alpha)
s.Vk.G2.Beta = BigInt32ToString(setup.Vk.G2.Beta)
s.Vk.G2.Gamma = BigInt32ToString(setup.Vk.G2.Gamma)
s.Vk.G2.Delta = BigInt32ToString(setup.Vk.G2.Delta)
return s
}
func GrothSetupFromString(s GrothSetupString) (groth16.Setup, error) {
var o groth16.Setup
var err error
o.Pk.BACDelta, err = Array3StringToBigInt(s.Pk.BACDelta)
if err != nil {
return o, err
}
o.Pk.Z, err = ArrayStringToBigInt(s.Pk.Z)
if err != nil {
return o, err
}
o.Pk.G1.Alpha, err = String3ToBigInt(s.Pk.G1.Alpha)
if err != nil {
return o, err
}
o.Pk.G1.Beta, err = String3ToBigInt(s.Pk.G1.Beta)
if err != nil {
return o, err
}
o.Pk.G1.Delta, err = String3ToBigInt(s.Pk.G1.Delta)
if err != nil {
return o, err
}
o.Pk.G1.At, err = Array3StringToBigInt(s.Pk.G1.At)
if err != nil {
return o, err
}
o.Pk.G1.BACGamma, err = Array3StringToBigInt(s.Pk.G1.BACGamma)
if err != nil {
return o, err
}
o.Pk.G2.Beta, err = String32ToBigInt(s.Pk.G2.Beta)
if err != nil {
return o, err
}
o.Pk.G2.Gamma, err = String32ToBigInt(s.Pk.G2.Gamma)
if err != nil {
return o, err
}
o.Pk.G2.Delta, err = String32ToBigInt(s.Pk.G2.Delta)
if err != nil {
return o, err
}
o.Pk.G2.BACGamma, err = Array32StringToBigInt(s.Pk.G2.BACGamma)
if err != nil {
return o, err
}
o.Pk.PowersTauDelta, err = Array3StringToBigInt(s.Pk.PowersTauDelta)
if err != nil {
return o, err
}
o.Vk.IC, err = Array3StringToBigInt(s.Vk.IC)
if err != nil {
return o, err
}
o.Vk.G1.Alpha, err = String3ToBigInt(s.Vk.G1.Alpha)
if err != nil {
return o, err
}
o.Vk.G2.Beta, err = String32ToBigInt(s.Vk.G2.Beta)
if err != nil {
return o, err
}
o.Vk.G2.Gamma, err = String32ToBigInt(s.Vk.G2.Gamma)
if err != nil {
return o, err
}
o.Vk.G2.Delta, err = String32ToBigInt(s.Vk.G2.Delta)
if err != nil {
return o, err
}
return o, nil
}
type GrothProofString struct {
PiA [3]string
PiB [3][2]string
PiC [3]string
}
func GrothProofToString(p groth16.Proof) GrothProofString {
var s GrothProofString
s.PiA = BigInt3ToString(p.PiA)
s.PiB = BigInt32ToString(p.PiB)
s.PiC = BigInt3ToString(p.PiC)
return s
}
func GrothProofFromString(s GrothProofString) (groth16.Proof, error) {
var p groth16.Proof
var err error
p.PiA, err = String3ToBigInt(s.PiA)
if err != nil {
return p, err
}
p.PiB, err = String32ToBigInt(s.PiB)
if err != nil {
return p, err
}
p.PiC, err = String3ToBigInt(s.PiC)
if err != nil {
return p, err
}
return p, nil
}

Loading…
Cancel
Save