@ -0,0 +1,12 @@ |
|||||
|
# go-snark /externalVerif |
||||
|
Utilities to verify zkSNARK proofs generated by other tools. |
||||
|
|
||||
|
## Verify Proof generated from [snarkjs](https://github.com/iden3/snarkjs) |
||||
|
Is possible with `go-snark` to verify proofs generated by `snarkjs` |
||||
|
|
||||
|
Example: |
||||
|
```go |
||||
|
verified, err := VerifyFromCircom("circom-test/verification_key.json", "circom-test/proof.json", "circom-test/public.json") |
||||
|
assert.Nil(t, err) |
||||
|
assert.True(t, verified) |
||||
|
``` |
@ -0,0 +1,8 @@ |
|||||
|
template Multiplier() { |
||||
|
signal private input a; |
||||
|
signal private input b; |
||||
|
signal output c; |
||||
|
c <== a*b; |
||||
|
} |
||||
|
|
||||
|
component main = Multiplier(); |
@ -0,0 +1,74 @@ |
|||||
|
{ |
||||
|
"mainCode": "{\n}\n", |
||||
|
"signalName2Idx": { |
||||
|
"one": 0, |
||||
|
"main.a": 2, |
||||
|
"main.b": 3, |
||||
|
"main.c": 1 |
||||
|
}, |
||||
|
"components": [ |
||||
|
{ |
||||
|
"name": "main", |
||||
|
"params": {}, |
||||
|
"template": "Multiplier", |
||||
|
"inputSignals": 2 |
||||
|
} |
||||
|
], |
||||
|
"componentName2Idx": { |
||||
|
"main": 0 |
||||
|
}, |
||||
|
"signals": [ |
||||
|
{ |
||||
|
"names": [ |
||||
|
"one" |
||||
|
], |
||||
|
"triggerComponents": [] |
||||
|
}, |
||||
|
{ |
||||
|
"names": [ |
||||
|
"main.c" |
||||
|
], |
||||
|
"triggerComponents": [] |
||||
|
}, |
||||
|
{ |
||||
|
"names": [ |
||||
|
"main.a" |
||||
|
], |
||||
|
"triggerComponents": [ |
||||
|
0 |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"names": [ |
||||
|
"main.b" |
||||
|
], |
||||
|
"triggerComponents": [ |
||||
|
0 |
||||
|
] |
||||
|
} |
||||
|
], |
||||
|
"constraints": [ |
||||
|
[ |
||||
|
{ |
||||
|
"2": "21888242871839275222246405745257275088548364400416034343698204186575808495616" |
||||
|
}, |
||||
|
{ |
||||
|
"3": "1" |
||||
|
}, |
||||
|
{ |
||||
|
"1": "21888242871839275222246405745257275088548364400416034343698204186575808495616" |
||||
|
} |
||||
|
] |
||||
|
], |
||||
|
"templates": { |
||||
|
"Multiplier": "function(ctx) {\n ctx.setSignal(\"c\", [], bigInt(ctx.getSignal(\"a\", [])).mul(bigInt(ctx.getSignal(\"b\", []))).mod(__P__));\n ctx.assert(ctx.getSignal(\"c\", []), bigInt(ctx.getSignal(\"a\", [])).mul(bigInt(ctx.getSignal(\"b\", []))).mod(__P__));\n}\n" |
||||
|
}, |
||||
|
"functions": {}, |
||||
|
"nPrvInputs": 2, |
||||
|
"nPubInputs": 0, |
||||
|
"nInputs": 2, |
||||
|
"nOutputs": 1, |
||||
|
"nVars": 4, |
||||
|
"nConstants": 0, |
||||
|
"nSignals": 4 |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
{"a": 3, "b": 11} |
@ -0,0 +1,27 @@ |
|||||
|
{ |
||||
|
"pi_a": [ |
||||
|
"18388960469390566286541775203573681018272060202314500468244373257908579233056", |
||||
|
"7618815753031896296145768956584956596571516464117106968297323458939823682730", |
||||
|
"1" |
||||
|
], |
||||
|
"pi_b": [ |
||||
|
[ |
||||
|
"17050824088966017765399151386329118398626450147519924253020767437783796544260", |
||||
|
"19912572158122217836152914282050675315049542075120224143747749799495268338155" |
||||
|
], |
||||
|
[ |
||||
|
"20465264120227255663865054937863503553147947378051666554617444700075602812731", |
||||
|
"18655251778322805691388473632530173510779859979743695956359151230786651584957" |
||||
|
], |
||||
|
[ |
||||
|
"1", |
||||
|
"0" |
||||
|
] |
||||
|
], |
||||
|
"pi_c": [ |
||||
|
"1422784641124790360586256228365363101120672643204565045434023905594849706813", |
||||
|
"8557716062509065082036904136615813135951258906799509331823365499907603810450", |
||||
|
"1" |
||||
|
], |
||||
|
"protocol": "groth" |
||||
|
} |
@ -0,0 +1,221 @@ |
|||||
|
{ |
||||
|
"protocol": "groth", |
||||
|
"nVars": 4, |
||||
|
"nPublic": 1, |
||||
|
"domainBits": 2, |
||||
|
"domainSize": 4, |
||||
|
"polsA": [ |
||||
|
{ |
||||
|
"1": "1" |
||||
|
}, |
||||
|
{ |
||||
|
"2": "1" |
||||
|
}, |
||||
|
{ |
||||
|
"0": "21888242871839275222246405745257275088548364400416034343698204186575808495616" |
||||
|
}, |
||||
|
{} |
||||
|
], |
||||
|
"polsB": [ |
||||
|
{}, |
||||
|
{}, |
||||
|
{}, |
||||
|
{ |
||||
|
"0": "1" |
||||
|
} |
||||
|
], |
||||
|
"polsC": [ |
||||
|
{}, |
||||
|
{ |
||||
|
"0": "21888242871839275222246405745257275088548364400416034343698204186575808495616" |
||||
|
}, |
||||
|
{}, |
||||
|
{} |
||||
|
], |
||||
|
"A": [ |
||||
|
[ |
||||
|
"16145916318196730299582072104388453231952213805668281741813587224450782397538", |
||||
|
"4434505318477484327659527264104806919103674231447634885054368605283938696207", |
||||
|
"1" |
||||
|
], |
||||
|
[ |
||||
|
"10618406967550056457559358662746625591602641004174976323307214433994084907915", |
||||
|
"1843236360452735081347085412539192450068665510574800388201121698908391533923", |
||||
|
"1" |
||||
|
], |
||||
|
[ |
||||
|
"1208972877970123411566574123860641832032384890981476033353526096830198333194", |
||||
|
"777503551507025252294438107100944741641946695980350712141258191590862204805", |
||||
|
"1" |
||||
|
], |
||||
|
[ |
||||
|
"0", |
||||
|
"1", |
||||
|
"0" |
||||
|
] |
||||
|
], |
||||
|
"B1": [ |
||||
|
[ |
||||
|
"0", |
||||
|
"1", |
||||
|
"0" |
||||
|
], |
||||
|
[ |
||||
|
"0", |
||||
|
"1", |
||||
|
"0" |
||||
|
], |
||||
|
[ |
||||
|
"0", |
||||
|
"1", |
||||
|
"0" |
||||
|
], |
||||
|
[ |
||||
|
"1208972877970123411566574123860641832032384890981476033353526096830198333194", |
||||
|
"21110739320332249969951967638156330347054364461317472950547779703054364003778", |
||||
|
"1" |
||||
|
] |
||||
|
], |
||||
|
"B2": [ |
||||
|
[ |
||||
|
[ |
||||
|
"0", |
||||
|
"0" |
||||
|
], |
||||
|
[ |
||||
|
"1", |
||||
|
"0" |
||||
|
], |
||||
|
[ |
||||
|
"0", |
||||
|
"0" |
||||
|
] |
||||
|
], |
||||
|
[ |
||||
|
[ |
||||
|
"0", |
||||
|
"0" |
||||
|
], |
||||
|
[ |
||||
|
"1", |
||||
|
"0" |
||||
|
], |
||||
|
[ |
||||
|
"0", |
||||
|
"0" |
||||
|
] |
||||
|
], |
||||
|
[ |
||||
|
[ |
||||
|
"0", |
||||
|
"0" |
||||
|
], |
||||
|
[ |
||||
|
"1", |
||||
|
"0" |
||||
|
], |
||||
|
[ |
||||
|
"0", |
||||
|
"0" |
||||
|
] |
||||
|
], |
||||
|
[ |
||||
|
[ |
||||
|
"9283666785342556550467669770956850930982548182701254051508520248901282197973", |
||||
|
"11369378229277445316894458966429873744779877313900506577160370623273013178252" |
||||
|
], |
||||
|
[ |
||||
|
"10625777544326349817513295021482494426101347915428005055375725845993157551870", |
||||
|
"21401790227434807639472120486932615400751346915707967674912972446672152512583" |
||||
|
], |
||||
|
[ |
||||
|
"1", |
||||
|
"0" |
||||
|
] |
||||
|
] |
||||
|
], |
||||
|
"C": [ |
||||
|
null, |
||||
|
null, |
||||
|
[ |
||||
|
"18545397130363256321926549041639729743141431075318462370025152832852939073307", |
||||
|
"2616861286119881509516846668252666108741377487742351180864484963773522850295", |
||||
|
"1" |
||||
|
], |
||||
|
[ |
||||
|
"2525636894222523143142808451978966577881491159416335121257094078801746645235", |
||||
|
"16535861715720884910945782094658684127457731006848459401043529763859412916301", |
||||
|
"1" |
||||
|
] |
||||
|
], |
||||
|
"vk_alfa_1": [ |
||||
|
"16068200068882411629410035093795608526771554471937479213726134794660780102550", |
||||
|
"20501676791339890155108177259376873296876233680064261776170683533526889207340", |
||||
|
"1" |
||||
|
], |
||||
|
"vk_beta_1": [ |
||||
|
"5365573823291502335794132193185274277974617763863996013954364593194136465016", |
||||
|
"11644349101388223784378896360832586557929271772024496470708905460439243894584", |
||||
|
"1" |
||||
|
], |
||||
|
"vk_delta_1": [ |
||||
|
"15680151079584844532489259722917096938769907841931133291928746685613811358733", |
||||
|
"16784279394546603697881462850128771845781623009095957214568117820968443242506", |
||||
|
"1" |
||||
|
], |
||||
|
"vk_beta_2": [ |
||||
|
[ |
||||
|
"13973091636763944887728510851169742544309374663995476311690518173988838518856", |
||||
|
"12903946180439304546475897520537621821375470264150438270817301786763517825250" |
||||
|
], |
||||
|
[ |
||||
|
"370374369234123593044872519351942112043402224488849374153134091815693350697", |
||||
|
"17423079115073430837335625309232513526393852743032331213038909731579295753224" |
||||
|
], |
||||
|
[ |
||||
|
"1", |
||||
|
"0" |
||||
|
] |
||||
|
], |
||||
|
"vk_delta_2": [ |
||||
|
[ |
||||
|
"1192908377564945353343974763532707545526009748811618581810344379529229172159", |
||||
|
"10373868200341234689659697947697825014338252335089936445608341428888724327154" |
||||
|
], |
||||
|
[ |
||||
|
"6258644116885726740914814071115026921733331135830050167672544002787860516536", |
||||
|
"2784479362505735918824286514153638713518597314121639212447411360814573899319" |
||||
|
], |
||||
|
[ |
||||
|
"1", |
||||
|
"0" |
||||
|
] |
||||
|
], |
||||
|
"hExps": [ |
||||
|
[ |
||||
|
"1137454402546542017796495169973321459788661791339116580816039119135416491226", |
||||
|
"10581992627412174102808274058339351114019966039682644500297077873241797449624", |
||||
|
"1" |
||||
|
], |
||||
|
[ |
||||
|
"3253811140290017934039655168718326971539049766532829948316663892796117200680", |
||||
|
"3496418280903365070403555364992889823060908616232765866481366503085657668823", |
||||
|
"1" |
||||
|
], |
||||
|
[ |
||||
|
"7426424892372059053157891943364774187577620238460342150964457392480230669997", |
||||
|
"14261604113665464620229095737623968407326243628348811684313201927885047569756", |
||||
|
"1" |
||||
|
], |
||||
|
[ |
||||
|
"14706800931196014592083141709960980909656368788497354451613143286705158867076", |
||||
|
"8321358240716309588423491516494287064322707776658072083979021495463106099808", |
||||
|
"1" |
||||
|
], |
||||
|
[ |
||||
|
"21560594640856118286219580794351895174554979903538723611152363886530011848778", |
||||
|
"15512645592267656573910252616175869133748229079507420222439452334013754939136", |
||||
|
"1" |
||||
|
] |
||||
|
] |
||||
|
} |
@ -0,0 +1,3 @@ |
|||||
|
[ |
||||
|
"33" |
||||
|
] |
@ -0,0 +1,93 @@ |
|||||
|
{ |
||||
|
"protocol": "groth", |
||||
|
"nPublic": 1, |
||||
|
"IC": [ |
||||
|
[ |
||||
|
"13238385840837109667936052879696151554096578146827286302729161004449442572510", |
||||
|
"7229895880483697230987627368481585486229758623816305076929725978466335833042", |
||||
|
"1" |
||||
|
], |
||||
|
[ |
||||
|
"14970768730171390202518134018231251321095352434740566553215758534237407624223", |
||||
|
"11858341424183782282346697815973277820477089967861765360499368718702428507405", |
||||
|
"1" |
||||
|
] |
||||
|
], |
||||
|
"vk_alfa_1": [ |
||||
|
"16068200068882411629410035093795608526771554471937479213726134794660780102550", |
||||
|
"20501676791339890155108177259376873296876233680064261776170683533526889207340", |
||||
|
"1" |
||||
|
], |
||||
|
"vk_beta_2": [ |
||||
|
[ |
||||
|
"13973091636763944887728510851169742544309374663995476311690518173988838518856", |
||||
|
"12903946180439304546475897520537621821375470264150438270817301786763517825250" |
||||
|
], |
||||
|
[ |
||||
|
"370374369234123593044872519351942112043402224488849374153134091815693350697", |
||||
|
"17423079115073430837335625309232513526393852743032331213038909731579295753224" |
||||
|
], |
||||
|
[ |
||||
|
"1", |
||||
|
"0" |
||||
|
] |
||||
|
], |
||||
|
"vk_gamma_2": [ |
||||
|
[ |
||||
|
"20123714298473938437207866646336289719062614610167653880378271328974655580609", |
||||
|
"13002533616763316572747276872341370962409012236118399865958073576789163874362" |
||||
|
], |
||||
|
[ |
||||
|
"9275552728819724842865155645402980221399400114914205138826048710506018574007", |
||||
|
"9767402488181356088371101345613657976874749415205606884811092820466492903357" |
||||
|
], |
||||
|
[ |
||||
|
"1", |
||||
|
"0" |
||||
|
] |
||||
|
], |
||||
|
"vk_delta_2": [ |
||||
|
[ |
||||
|
"1192908377564945353343974763532707545526009748811618581810344379529229172159", |
||||
|
"10373868200341234689659697947697825014338252335089936445608341428888724327154" |
||||
|
], |
||||
|
[ |
||||
|
"6258644116885726740914814071115026921733331135830050167672544002787860516536", |
||||
|
"2784479362505735918824286514153638713518597314121639212447411360814573899319" |
||||
|
], |
||||
|
[ |
||||
|
"1", |
||||
|
"0" |
||||
|
] |
||||
|
], |
||||
|
"vk_alfabeta_12": [ |
||||
|
[ |
||||
|
[ |
||||
|
"5808968930823264229923553886264093087733079723496081749582815497064726636649", |
||||
|
"15704206953123342065158329174314435955575427797267883688615695147218681260603" |
||||
|
], |
||||
|
[ |
||||
|
"2019376182570496317125733151845779676488434395598091282285101061771413397585", |
||||
|
"5033120379874305142732026662367866621873812132639805141544817513451132976303" |
||||
|
], |
||||
|
[ |
||||
|
"6413062281604814018100947958938305639421600365853645030429871508055751771332", |
||||
|
"16501101898595852943280641675936242756163761586970222679114350546638012990295" |
||||
|
] |
||||
|
], |
||||
|
[ |
||||
|
[ |
||||
|
"7994355756858823685828118366797930607512610071147093396079158087328554257367", |
||||
|
"12608941378902474737301318807093065779176013217938745808277102463837219428790" |
||||
|
], |
||||
|
[ |
||||
|
"7722352178656099663978033703115542396108273285932660670008724291332590018773", |
||||
|
"18402524427751774707431639562944919677540025075739837574780127622149131456184" |
||||
|
], |
||||
|
[ |
||||
|
"8237540863924877742345165686185155147152873047203223764861378545202201950314", |
||||
|
"885942718772685438966081900822373900701293300627890502324305030525329921651" |
||||
|
] |
||||
|
] |
||||
|
] |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
[ |
||||
|
"1", |
||||
|
"33", |
||||
|
"3", |
||||
|
"11" |
||||
|
] |
@ -0,0 +1,90 @@ |
|||||
|
package externalVerif |
||||
|
|
||||
|
import ( |
||||
|
"encoding/json" |
||||
|
"fmt" |
||||
|
"io/ioutil" |
||||
|
|
||||
|
"github.com/arnaucube/go-snark/groth16" |
||||
|
"github.com/arnaucube/go-snark/utils" |
||||
|
) |
||||
|
|
||||
|
type CircomProof struct { |
||||
|
PiA [3]string `json:"pi_a"` |
||||
|
PiB [3][2]string `json:"pi_b"` |
||||
|
PiC [3]string `json:"pi_c"` |
||||
|
} |
||||
|
type CircomVk struct { |
||||
|
IC [][3]string `json:"IC"` |
||||
|
Alpha1 [3]string `json:"vk_alfa_1"` |
||||
|
Beta2 [3][2]string `json:"vk_beta_2"` |
||||
|
Gamma2 [3][2]string `json:"vk_gamma_2"` |
||||
|
Delta2 [3][2]string `json:"vk_delta_2"` |
||||
|
AlphaBeta12 [2][3][2]string `json:"vk_alpfabeta_12"` // not really used, for the moment in go-snarks calculed in verification time
|
||||
|
} |
||||
|
|
||||
|
func VerifyFromCircom(vkPath, proofPath, publicSignalsPath string) (bool, error) { |
||||
|
// open verification_key.json
|
||||
|
vkFile, err := ioutil.ReadFile(vkPath) |
||||
|
if err != nil { |
||||
|
return false, err |
||||
|
} |
||||
|
var circomVk CircomVk |
||||
|
json.Unmarshal([]byte(string(vkFile)), &circomVk) |
||||
|
if err != nil { |
||||
|
return false, err |
||||
|
} |
||||
|
|
||||
|
var strVk utils.GrothVkString |
||||
|
strVk.IC = circomVk.IC |
||||
|
strVk.G1.Alpha = circomVk.Alpha1 |
||||
|
strVk.G2.Beta = circomVk.Beta2 |
||||
|
strVk.G2.Gamma = circomVk.Gamma2 |
||||
|
strVk.G2.Delta = circomVk.Delta2 |
||||
|
vk, err := utils.GrothVkFromString(strVk) |
||||
|
if err != nil { |
||||
|
return false, err |
||||
|
} |
||||
|
fmt.Println("vk parsed:", vk) |
||||
|
|
||||
|
// open proof.json
|
||||
|
proofsFile, err := ioutil.ReadFile(proofPath) |
||||
|
if err != nil { |
||||
|
return false, err |
||||
|
} |
||||
|
var circomProof CircomProof |
||||
|
json.Unmarshal([]byte(string(proofsFile)), &circomProof) |
||||
|
if err != nil { |
||||
|
return false, err |
||||
|
} |
||||
|
|
||||
|
strProof := utils.GrothProofString{ |
||||
|
PiA: circomProof.PiA, |
||||
|
PiB: circomProof.PiB, |
||||
|
PiC: circomProof.PiC, |
||||
|
} |
||||
|
proof, err := utils.GrothProofFromString(strProof) |
||||
|
if err != nil { |
||||
|
return false, err |
||||
|
} |
||||
|
fmt.Println("proof parsed:", proof) |
||||
|
|
||||
|
// open public.json
|
||||
|
publicFile, err := ioutil.ReadFile(publicSignalsPath) |
||||
|
if err != nil { |
||||
|
return false, err |
||||
|
} |
||||
|
var publicStr []string |
||||
|
json.Unmarshal([]byte(string(publicFile)), &publicStr) |
||||
|
if err != nil { |
||||
|
return false, err |
||||
|
} |
||||
|
publicSignals, err := utils.ArrayStringToBigInt(publicStr) |
||||
|
if err != nil { |
||||
|
return false, err |
||||
|
} |
||||
|
fmt.Println("publicSignals parsed:", publicSignals) |
||||
|
|
||||
|
verified := groth16.VerifyProof(vk, proof, publicSignals, true) |
||||
|
return verified, nil |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
package externalVerif |
||||
|
|
||||
|
import ( |
||||
|
"testing" |
||||
|
|
||||
|
"github.com/stretchr/testify/assert" |
||||
|
) |
||||
|
|
||||
|
func TestVerifyFromCircom(t *testing.T) { |
||||
|
verified, err := VerifyFromCircom("circom-test/verification_key.json", "circom-test/proof.json", "circom-test/public.json") |
||||
|
assert.Nil(t, err) |
||||
|
assert.True(t, verified) |
||||
|
} |
@ -0,0 +1,562 @@ |
|||||
|
package utils |
||||
|
|
||||
|
import ( |
||||
|
"errors" |
||||
|
"fmt" |
||||
|
"math/big" |
||||
|
|
||||
|
snark "github.com/arnaucube/go-snark" |
||||
|
"github.com/arnaucube/go-snark/circuitcompiler" |
||||
|
"github.com/arnaucube/go-snark/groth16" |
||||
|
) |
||||
|
|
||||
|
// []*big.Int
|
||||
|
func ArrayBigIntToHex(b []*big.Int) []string { |
||||
|
var o []string |
||||
|
for i := 0; i < len(b); i++ { |
||||
|
o = append(o, fmt.Sprintf("%x", b[i])) |
||||
|
} |
||||
|
return o |
||||
|
} |
||||
|
func ArrayHexToBigInt(s []string) ([]*big.Int, error) { |
||||
|
var px []*big.Int |
||||
|
for i := 0; i < len(s); i++ { |
||||
|
param, ok := new(big.Int).SetString(s[i], 16) |
||||
|
if !ok { |
||||
|
return nil, errors.New("error parsing px from pxHex") |
||||
|
} |
||||
|
px = append(px, param) |
||||
|
} |
||||
|
return px, nil |
||||
|
} |
||||
|
|
||||
|
// [3]*big.Int
|
||||
|
func Hex3ToBigInt(s [3]string) ([3]*big.Int, error) { |
||||
|
var o [3]*big.Int |
||||
|
for i := 0; i < len(s); i++ { |
||||
|
param, ok := new(big.Int).SetString(s[i], 16) |
||||
|
if !ok { |
||||
|
return o, errors.New("error parsing [3]*big.Int from [3]string") |
||||
|
} |
||||
|
o[i] = param |
||||
|
} |
||||
|
return o, nil |
||||
|
} |
||||
|
func BigInt3ToHex(b [3]*big.Int) [3]string { |
||||
|
var o [3]string |
||||
|
o[0] = fmt.Sprintf("%x", b[0]) |
||||
|
o[1] = fmt.Sprintf("%x", b[1]) |
||||
|
o[2] = fmt.Sprintf("%x", b[2]) |
||||
|
return o |
||||
|
} |
||||
|
|
||||
|
// [][3]*big.Int
|
||||
|
func Array3HexToBigInt(s [][3]string) ([][3]*big.Int, error) { |
||||
|
var o [][3]*big.Int |
||||
|
for i := 0; i < len(s); i++ { |
||||
|
parsed, err := Hex3ToBigInt(s[i]) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o = append(o, parsed) |
||||
|
} |
||||
|
return o, nil |
||||
|
} |
||||
|
func Array3BigIntToHex(b [][3]*big.Int) [][3]string { |
||||
|
var o [][3]string |
||||
|
for i := 0; i < len(b); i++ { |
||||
|
o = append(o, BigInt3ToHex(b[i])) |
||||
|
} |
||||
|
return o |
||||
|
} |
||||
|
|
||||
|
func Hex2ToBigInt(s [2]string) ([2]*big.Int, error) { |
||||
|
var o [2]*big.Int |
||||
|
for i := 0; i < len(s); i++ { |
||||
|
param, ok := new(big.Int).SetString(s[i], 16) |
||||
|
if !ok { |
||||
|
return o, errors.New("error parsing [2]*big.Int from [2]string") |
||||
|
} |
||||
|
o[i] = param |
||||
|
} |
||||
|
return o, nil |
||||
|
} |
||||
|
|
||||
|
// [3][2]*big.Int
|
||||
|
func Hex32ToBigInt(s [3][2]string) ([3][2]*big.Int, error) { |
||||
|
var o [3][2]*big.Int |
||||
|
var err error |
||||
|
|
||||
|
o[0], err = Hex2ToBigInt(s[0]) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o[1], err = Hex2ToBigInt(s[1]) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o[2], err = Hex2ToBigInt(s[2]) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
return o, nil |
||||
|
} |
||||
|
func BigInt32ToHex(b [3][2]*big.Int) [3][2]string { |
||||
|
var o [3][2]string |
||||
|
o[0][0] = fmt.Sprintf("%x", b[0][0]) |
||||
|
o[0][1] = fmt.Sprintf("%x", b[0][1]) |
||||
|
o[1][0] = fmt.Sprintf("%x", b[1][0]) |
||||
|
o[1][1] = fmt.Sprintf("%x", b[1][1]) |
||||
|
o[2][0] = fmt.Sprintf("%x", b[2][0]) |
||||
|
o[2][1] = fmt.Sprintf("%x", b[2][1]) |
||||
|
return o |
||||
|
} |
||||
|
|
||||
|
// [][3][2]*big.Int
|
||||
|
func Array32HexToBigInt(s [][3][2]string) ([][3][2]*big.Int, error) { |
||||
|
var o [][3][2]*big.Int |
||||
|
for i := 0; i < len(s); i++ { |
||||
|
parsed, err := Hex32ToBigInt(s[i]) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o = append(o, parsed) |
||||
|
} |
||||
|
return o, nil |
||||
|
} |
||||
|
func Array32BigIntToHex(b [][3][2]*big.Int) [][3][2]string { |
||||
|
var o [][3][2]string |
||||
|
for i := 0; i < len(b); i++ { |
||||
|
o = append(o, BigInt32ToHex(b[i])) |
||||
|
} |
||||
|
return o |
||||
|
} |
||||
|
|
||||
|
// Setup
|
||||
|
type PkHex struct { |
||||
|
G1T [][3]string |
||||
|
A [][3]string |
||||
|
B [][3][2]string |
||||
|
C [][3]string |
||||
|
Kp [][3]string |
||||
|
Ap [][3]string |
||||
|
Bp [][3]string |
||||
|
Cp [][3]string |
||||
|
Z []string |
||||
|
} |
||||
|
type VkHex struct { |
||||
|
Vka [3][2]string |
||||
|
Vkb [3]string |
||||
|
Vkc [3][2]string |
||||
|
IC [][3]string |
||||
|
G1Kbg [3]string |
||||
|
G2Kbg [3][2]string |
||||
|
G2Kg [3][2]string |
||||
|
Vkz [3][2]string |
||||
|
} |
||||
|
type SetupHex struct { |
||||
|
Pk PkHex |
||||
|
Vk VkHex |
||||
|
} |
||||
|
|
||||
|
func SetupToHex(setup snark.Setup) SetupHex { |
||||
|
var s SetupHex |
||||
|
s.Pk.G1T = Array3BigIntToHex(setup.Pk.G1T) |
||||
|
s.Pk.A = Array3BigIntToHex(setup.Pk.A) |
||||
|
s.Pk.B = Array32BigIntToHex(setup.Pk.B) |
||||
|
s.Pk.C = Array3BigIntToHex(setup.Pk.C) |
||||
|
s.Pk.Kp = Array3BigIntToHex(setup.Pk.Kp) |
||||
|
s.Pk.Ap = Array3BigIntToHex(setup.Pk.Ap) |
||||
|
s.Pk.Bp = Array3BigIntToHex(setup.Pk.Bp) |
||||
|
s.Pk.Cp = Array3BigIntToHex(setup.Pk.Cp) |
||||
|
s.Pk.Z = ArrayBigIntToHex(setup.Pk.Z) |
||||
|
s.Vk.Vka = BigInt32ToHex(setup.Vk.Vka) |
||||
|
s.Vk.Vkb = BigInt3ToHex(setup.Vk.Vkb) |
||||
|
s.Vk.Vkc = BigInt32ToHex(setup.Vk.Vkc) |
||||
|
s.Vk.IC = Array3BigIntToHex(setup.Vk.IC) |
||||
|
s.Vk.G1Kbg = BigInt3ToHex(setup.Vk.G1Kbg) |
||||
|
s.Vk.G2Kbg = BigInt32ToHex(setup.Vk.G2Kbg) |
||||
|
s.Vk.G2Kg = BigInt32ToHex(setup.Vk.G2Kg) |
||||
|
s.Vk.Vkz = BigInt32ToHex(setup.Vk.Vkz) |
||||
|
return s |
||||
|
} |
||||
|
func SetupFromHex(s SetupHex) (snark.Setup, error) { |
||||
|
var o snark.Setup |
||||
|
var err error |
||||
|
o.Pk.G1T, err = Array3HexToBigInt(s.Pk.G1T) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.A, err = Array3HexToBigInt(s.Pk.A) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.B, err = Array32HexToBigInt(s.Pk.B) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.C, err = Array3HexToBigInt(s.Pk.C) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.Kp, err = Array3HexToBigInt(s.Pk.Kp) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.Ap, err = Array3HexToBigInt(s.Pk.Ap) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.Bp, err = Array3HexToBigInt(s.Pk.Bp) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.Cp, err = Array3HexToBigInt(s.Pk.Cp) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.Z, err = ArrayHexToBigInt(s.Pk.Z) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
|
||||
|
o.Vk.Vka, err = Hex32ToBigInt(s.Vk.Vka) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Vk.Vkb, err = Hex3ToBigInt(s.Vk.Vkb) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Vk.Vkc, err = Hex32ToBigInt(s.Vk.Vkc) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Vk.IC, err = Array3HexToBigInt(s.Vk.IC) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Vk.G1Kbg, err = Hex3ToBigInt(s.Vk.G1Kbg) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Vk.G2Kbg, err = Hex32ToBigInt(s.Vk.G2Kbg) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Vk.G2Kg, err = Hex32ToBigInt(s.Vk.G2Kg) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Vk.Vkz, err = Hex32ToBigInt(s.Vk.Vkz) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
|
||||
|
return o, nil |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// circuit
|
||||
|
type CircuitHex struct { |
||||
|
NVars int |
||||
|
NPublic int |
||||
|
NSignals int |
||||
|
PrivateInputs []string |
||||
|
PublicInputs []string |
||||
|
Signals []string |
||||
|
Witness []string |
||||
|
Constraints []circuitcompiler.Constraint |
||||
|
R1CS struct { |
||||
|
A [][]string |
||||
|
B [][]string |
||||
|
C [][]string |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func ArrayArrayBigIntToHex(b [][]*big.Int) [][]string { |
||||
|
var o [][]string |
||||
|
for i := 0; i < len(b); i++ { |
||||
|
o = append(o, ArrayBigIntToHex(b[i])) |
||||
|
} |
||||
|
return o |
||||
|
} |
||||
|
func ArrayArrayHexToBigInt(s [][]string) ([][]*big.Int, error) { |
||||
|
var o [][]*big.Int |
||||
|
for i := 0; i < len(s); i++ { |
||||
|
parsed, err := ArrayHexToBigInt(s[i]) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o = append(o, parsed) |
||||
|
} |
||||
|
return o, nil |
||||
|
} |
||||
|
func CircuitToHex(c circuitcompiler.Circuit) CircuitHex { |
||||
|
var cs CircuitHex |
||||
|
cs.NVars = c.NVars |
||||
|
cs.NPublic = c.NPublic |
||||
|
cs.NSignals = c.NSignals |
||||
|
cs.PrivateInputs = c.PrivateInputs |
||||
|
cs.PublicInputs = c.PublicInputs |
||||
|
cs.Signals = c.Signals |
||||
|
cs.Witness = ArrayBigIntToHex(c.Witness) |
||||
|
cs.Constraints = c.Constraints |
||||
|
cs.R1CS.A = ArrayArrayBigIntToHex(c.R1CS.A) |
||||
|
cs.R1CS.B = ArrayArrayBigIntToHex(c.R1CS.B) |
||||
|
cs.R1CS.C = ArrayArrayBigIntToHex(c.R1CS.C) |
||||
|
return cs |
||||
|
} |
||||
|
func CircuitFromHex(cs CircuitHex) (circuitcompiler.Circuit, error) { |
||||
|
var c circuitcompiler.Circuit |
||||
|
var err error |
||||
|
c.NVars = cs.NVars |
||||
|
c.NPublic = cs.NPublic |
||||
|
c.NSignals = cs.NSignals |
||||
|
c.PrivateInputs = cs.PrivateInputs |
||||
|
c.PublicInputs = cs.PublicInputs |
||||
|
c.Signals = cs.Signals |
||||
|
c.Witness, err = ArrayHexToBigInt(cs.Witness) |
||||
|
if err != nil { |
||||
|
return c, err |
||||
|
} |
||||
|
c.Constraints = cs.Constraints |
||||
|
c.R1CS.A, err = ArrayArrayHexToBigInt(cs.R1CS.A) |
||||
|
if err != nil { |
||||
|
return c, err |
||||
|
} |
||||
|
c.R1CS.B, err = ArrayArrayHexToBigInt(cs.R1CS.B) |
||||
|
if err != nil { |
||||
|
return c, err |
||||
|
} |
||||
|
c.R1CS.C, err = ArrayArrayHexToBigInt(cs.R1CS.C) |
||||
|
if err != nil { |
||||
|
return c, err |
||||
|
} |
||||
|
return c, nil |
||||
|
} |
||||
|
|
||||
|
// Proof
|
||||
|
type ProofHex struct { |
||||
|
PiA [3]string |
||||
|
PiAp [3]string |
||||
|
PiB [3][2]string |
||||
|
PiBp [3]string |
||||
|
PiC [3]string |
||||
|
PiCp [3]string |
||||
|
PiH [3]string |
||||
|
PiKp [3]string |
||||
|
} |
||||
|
|
||||
|
func ProofToHex(p snark.Proof) ProofHex { |
||||
|
var s ProofHex |
||||
|
s.PiA = BigInt3ToHex(p.PiA) |
||||
|
s.PiAp = BigInt3ToHex(p.PiAp) |
||||
|
s.PiB = BigInt32ToHex(p.PiB) |
||||
|
s.PiBp = BigInt3ToHex(p.PiBp) |
||||
|
s.PiC = BigInt3ToHex(p.PiC) |
||||
|
s.PiCp = BigInt3ToHex(p.PiCp) |
||||
|
s.PiH = BigInt3ToHex(p.PiH) |
||||
|
s.PiKp = BigInt3ToHex(p.PiKp) |
||||
|
return s |
||||
|
} |
||||
|
func ProofFromHex(s ProofHex) (snark.Proof, error) { |
||||
|
var p snark.Proof |
||||
|
var err error |
||||
|
|
||||
|
p.PiA, err = Hex3ToBigInt(s.PiA) |
||||
|
if err != nil { |
||||
|
return p, err |
||||
|
} |
||||
|
p.PiAp, err = Hex3ToBigInt(s.PiAp) |
||||
|
if err != nil { |
||||
|
return p, err |
||||
|
} |
||||
|
p.PiB, err = Hex32ToBigInt(s.PiB) |
||||
|
if err != nil { |
||||
|
return p, err |
||||
|
} |
||||
|
p.PiBp, err = Hex3ToBigInt(s.PiBp) |
||||
|
if err != nil { |
||||
|
return p, err |
||||
|
} |
||||
|
p.PiC, err = Hex3ToBigInt(s.PiC) |
||||
|
if err != nil { |
||||
|
return p, err |
||||
|
} |
||||
|
p.PiCp, err = Hex3ToBigInt(s.PiCp) |
||||
|
if err != nil { |
||||
|
return p, err |
||||
|
} |
||||
|
p.PiH, err = Hex3ToBigInt(s.PiH) |
||||
|
if err != nil { |
||||
|
return p, err |
||||
|
} |
||||
|
p.PiKp, err = Hex3ToBigInt(s.PiKp) |
||||
|
if err != nil { |
||||
|
return p, err |
||||
|
} |
||||
|
return p, nil |
||||
|
} |
||||
|
|
||||
|
// groth
|
||||
|
type GrothPkHex 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 |
||||
|
} |
||||
|
type GrothVkHex struct { |
||||
|
IC [][3]string |
||||
|
G1 struct { |
||||
|
Alpha [3]string |
||||
|
} |
||||
|
G2 struct { |
||||
|
Beta [3][2]string |
||||
|
Gamma [3][2]string |
||||
|
Delta [3][2]string |
||||
|
} |
||||
|
} |
||||
|
type GrothSetupHex struct { |
||||
|
Pk GrothPkHex |
||||
|
Vk GrothVkHex |
||||
|
} |
||||
|
|
||||
|
func GrothSetupToHex(setup groth16.Setup) GrothSetupHex { |
||||
|
var s GrothSetupHex |
||||
|
s.Pk.BACDelta = Array3BigIntToHex(setup.Pk.BACDelta) |
||||
|
s.Pk.Z = ArrayBigIntToHex(setup.Pk.Z) |
||||
|
s.Pk.G1.Alpha = BigInt3ToHex(setup.Pk.G1.Alpha) |
||||
|
s.Pk.G1.Beta = BigInt3ToHex(setup.Pk.G1.Beta) |
||||
|
s.Pk.G1.Delta = BigInt3ToHex(setup.Pk.G1.Delta) |
||||
|
s.Pk.G1.At = Array3BigIntToHex(setup.Pk.G1.At) |
||||
|
s.Pk.G1.BACGamma = Array3BigIntToHex(setup.Pk.G1.BACGamma) |
||||
|
s.Pk.G2.Beta = BigInt32ToHex(setup.Pk.G2.Beta) |
||||
|
s.Pk.G2.Gamma = BigInt32ToHex(setup.Pk.G2.Gamma) |
||||
|
s.Pk.G2.Delta = BigInt32ToHex(setup.Pk.G2.Delta) |
||||
|
s.Pk.G2.BACGamma = Array32BigIntToHex(setup.Pk.G2.BACGamma) |
||||
|
s.Pk.PowersTauDelta = Array3BigIntToHex(setup.Pk.PowersTauDelta) |
||||
|
s.Vk.IC = Array3BigIntToHex(setup.Vk.IC) |
||||
|
s.Vk.G1.Alpha = BigInt3ToHex(setup.Vk.G1.Alpha) |
||||
|
s.Vk.G2.Beta = BigInt32ToHex(setup.Vk.G2.Beta) |
||||
|
s.Vk.G2.Gamma = BigInt32ToHex(setup.Vk.G2.Gamma) |
||||
|
s.Vk.G2.Delta = BigInt32ToHex(setup.Vk.G2.Delta) |
||||
|
return s |
||||
|
} |
||||
|
func GrothSetupFromHex(s GrothSetupHex) (groth16.Setup, error) { |
||||
|
var o groth16.Setup |
||||
|
var err error |
||||
|
o.Pk.BACDelta, err = Array3HexToBigInt(s.Pk.BACDelta) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.Z, err = ArrayHexToBigInt(s.Pk.Z) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.G1.Alpha, err = Hex3ToBigInt(s.Pk.G1.Alpha) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.G1.Beta, err = Hex3ToBigInt(s.Pk.G1.Beta) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.G1.Delta, err = Hex3ToBigInt(s.Pk.G1.Delta) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.G1.At, err = Array3HexToBigInt(s.Pk.G1.At) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.G1.BACGamma, err = Array3HexToBigInt(s.Pk.G1.BACGamma) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.G2.Beta, err = Hex32ToBigInt(s.Pk.G2.Beta) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.G2.Gamma, err = Hex32ToBigInt(s.Pk.G2.Gamma) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.G2.Delta, err = Hex32ToBigInt(s.Pk.G2.Delta) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.G2.BACGamma, err = Array32HexToBigInt(s.Pk.G2.BACGamma) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Pk.PowersTauDelta, err = Array3HexToBigInt(s.Pk.PowersTauDelta) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Vk.IC, err = Array3HexToBigInt(s.Vk.IC) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Vk.G1.Alpha, err = Hex3ToBigInt(s.Vk.G1.Alpha) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Vk.G2.Beta, err = Hex32ToBigInt(s.Vk.G2.Beta) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Vk.G2.Gamma, err = Hex32ToBigInt(s.Vk.G2.Gamma) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
o.Vk.G2.Delta, err = Hex32ToBigInt(s.Vk.G2.Delta) |
||||
|
if err != nil { |
||||
|
return o, err |
||||
|
} |
||||
|
return o, nil |
||||
|
} |
||||
|
|
||||
|
type GrothProofHex struct { |
||||
|
PiA [3]string |
||||
|
PiB [3][2]string |
||||
|
PiC [3]string |
||||
|
} |
||||
|
|
||||
|
func GrothProofToHex(p groth16.Proof) GrothProofHex { |
||||
|
var s GrothProofHex |
||||
|
s.PiA = BigInt3ToHex(p.PiA) |
||||
|
s.PiB = BigInt32ToHex(p.PiB) |
||||
|
s.PiC = BigInt3ToHex(p.PiC) |
||||
|
return s |
||||
|
} |
||||
|
func GrothProofFromHex(s GrothProofHex) (groth16.Proof, error) { |
||||
|
var p groth16.Proof |
||||
|
var err error |
||||
|
|
||||
|
p.PiA, err = Hex3ToBigInt(s.PiA) |
||||
|
if err != nil { |
||||
|
return p, err |
||||
|
} |
||||
|
p.PiB, err = Hex32ToBigInt(s.PiB) |
||||
|
if err != nil { |
||||
|
return p, err |
||||
|
} |
||||
|
p.PiC, err = Hex3ToBigInt(s.PiC) |
||||
|
if err != nil { |
||||
|
return p, err |
||||
|
} |
||||
|
return p, nil |
||||
|
} |