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,4 +1,4 @@
|
|||||||
func test(private a, private b, public c):
|
func main(private a, private b, public c):
|
||||||
d = a * b
|
d = a * b
|
||||||
equals(c, d)
|
equals(c, d)
|
||||||
out = 1 * 1
|
out = 1 * 1
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
func test(private s0, public s1):
|
func main(private s0, public s1):
|
||||||
s2 = s0 * s0
|
s2 = s0 * s0
|
||||||
s3 = s2 * s0
|
s3 = s2 * s0
|
||||||
s4 = s3 + s0
|
s4 = s3 + s0
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# go-snark wasm
|
# go-snark wasm
|
||||||
*Warning: this is an ongoing experimentation*
|
*Warning: this is an ongoing experimentation*
|
||||||
|
|
||||||
|
WASM wrappers for zkSNARK Pinocchio & Groth16 protocols.
|
||||||
|
|
||||||
## Wasm usage
|
## Wasm usage
|
||||||
To compile to wasm, inside the `wasm` directory, execute:
|
To compile to wasm, inside the `wasm` directory, execute:
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/arnaucube/go-snark"
|
"github.com/arnaucube/go-snark"
|
||||||
"github.com/arnaucube/go-snark/circuitcompiler"
|
"github.com/arnaucube/go-snark/circuitcompiler"
|
||||||
|
"github.com/arnaucube/go-snark/groth16"
|
||||||
"github.com/arnaucube/go-snark/wasm/utils"
|
"github.com/arnaucube/go-snark/wasm/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,6 +21,8 @@ func main() {
|
|||||||
func registerCallbacks() {
|
func registerCallbacks() {
|
||||||
js.Global().Set("generateProofs", js.FuncOf(generateProofs))
|
js.Global().Set("generateProofs", js.FuncOf(generateProofs))
|
||||||
js.Global().Set("verifyProofs", js.FuncOf(verifyProofs))
|
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{} {
|
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))
|
println("verifiedJson", string(verifiedJson))
|
||||||
return js.ValueOf(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"
|
snark "github.com/arnaucube/go-snark"
|
||||||
"github.com/arnaucube/go-snark/circuitcompiler"
|
"github.com/arnaucube/go-snark/circuitcompiler"
|
||||||
|
"github.com/arnaucube/go-snark/groth16"
|
||||||
)
|
)
|
||||||
|
|
||||||
// []*big.Int
|
// []*big.Int
|
||||||
@@ -401,3 +402,163 @@ func ProofFromString(s ProofString) (snark.Proof, error) {
|
|||||||
}
|
}
|
||||||
return p, nil
|
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