mirror of
https://github.com/arnaucube/go-snark-study.git
synced 2026-02-02 17:26:41 +01:00
add wasm for Groth16 proof generation & verification
This commit is contained in:
@@ -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:
|
||||
```
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user