Merge pull request #22 from iden3/feature/bugfix Fix binary parser bug, make go.bin format deterministic
arnau 17317030+arnaucube@users.noreply.github.com
Fri, 22 May 2020 17:30:11 +0200
4 files changed,
32 insertions(+),
9 deletions(-)
M
cli/cli.go
→
cli/cli.go
@@ -159,7 +159,9 @@ pkGBin, err := parsers.PkToGoBin(pk)
if err != nil { return err } - err = ioutil.WriteFile(provingKeyBinPath, pkGBin, 0644) + if err = ioutil.WriteFile(provingKeyBinPath, pkGBin, 0644); err != nil { + return err + } return nil }
M
parsers/parsers.go
→
parsers/parsers.go
@@ -10,6 +10,7 @@ "fmt"
"io" "math/big" "os" + "sort" "strconv" "strings"@@ -814,9 +815,9 @@ _, err = z.Unmarshal(zb)
if err != nil { return nil, err } - pk.C = append(pk.C, z) // circom behaviour (3x null==["0", "0", "0"]) - pk.C = append(pk.C, z) - pk.C = append(pk.C, z) + for i := 0; i < pk.NPublic+1; i++ { + pk.C = append(pk.C, z) + } for i := pk.NPublic + 1; i < pk.NVars; i++ { b, err = readNBytes(r, 64) if err != nil {@@ -969,6 +970,15 @@ q,
) } +func sortedKeys(m map[int]*big.Int) []int { + keys := make([]int, 0, len(m)) + for k, _ := range m { + keys = append(keys, k) + } + sort.Ints(keys) + return keys +} + // PkToGoBin converts the ProvingKey (*types.Pk) into binary format defined by // go-circom-prover-verifier. PkGoBin is a own go-circom-prover-verifier // binary format that allows to go faster when parsing.@@ -1017,7 +1027,8 @@ for i := 0; i < pk.NVars; i++ {
binary.LittleEndian.PutUint32(b[:], uint32(len(pk.PolsA[i]))) r = append(r, b[:]...) o += 4 - for j, v := range pk.PolsA[i] { + for _, j := range sortedKeys(pk.PolsA[i]) { + v := pk.PolsA[i][j] binary.LittleEndian.PutUint32(b[:], uint32(j)) r = append(r, b[:]...) r = append(r, addPadding32(v.Bytes())...)@@ -1030,7 +1041,8 @@ for i := 0; i < pk.NVars; i++ {
binary.LittleEndian.PutUint32(b[:], uint32(len(pk.PolsB[i]))) r = append(r, b[:]...) o += 4 - for j, v := range pk.PolsB[i] { + for _, j := range sortedKeys(pk.PolsB[i]) { + v := pk.PolsB[i][j] binary.LittleEndian.PutUint32(b[:], uint32(j)) r = append(r, b[:]...) r = append(r, addPadding32(v.Bytes())...)@@ -1279,9 +1291,9 @@ _, err = z.Unmarshal(zb)
if err != nil { return nil, err } - pk.C = append(pk.C, z) - pk.C = append(pk.C, z) - pk.C = append(pk.C, z) + for i := 0; i < pk.NPublic+1; i++ { + pk.C = append(pk.C, z) + } for i := pk.NPublic + 1; i < pk.NVars; i++ { b, err = readNBytes(r, 64) if err != nil {
M
parsers/parsers_test.go
→
parsers/parsers_test.go
@@ -238,6 +238,10 @@ assert.Equal(t, pkJ.B1, pk.B1)
assert.Equal(t, pkJ.B2, pk.B2) assert.Equal(t, pkJ.C, pk.C) assert.Equal(t, pkJ.HExps[:pkJ.DomainSize], pk.HExps[:pk.DomainSize]) // circom behaviour + + assert.Equal(t, pkJ.NVars, pk.NVars) + assert.Equal(t, pkJ.NPublic, pk.NPublic) + assert.Equal(t, pkJ.DomainSize, pk.DomainSize) } func TestParsePkBin(t *testing.T) {@@ -274,6 +278,10 @@ assert.Equal(t, pk.C, pkG.C)
assert.Equal(t, pk.HExps, pkG.HExps) assert.Equal(t, pk.PolsA, pkG.PolsA) assert.Equal(t, pk.PolsB, pkG.PolsB) + + assert.Equal(t, pk.NVars, pkG.NVars) + assert.Equal(t, pk.NPublic, pkG.NPublic) + assert.Equal(t, pk.DomainSize, pkG.DomainSize) } func TestGoCircomPkFormat(t *testing.T) {