arnaucube
arnaucube/go-merkletree-iden3Public Self-hosted repository
Add SC proof generator (siblings)
arnaucube root@arnaucube.com
Wed, 30 Dec 2020 10:12:14 +0100
commit

48e4633d1249ed756fe24197c48a6552207be32d

parent

8f3905f15f89ee4c165455823619b9fd7e4f8fbb

2 files changed, 50 insertions(+), 1 deletions(-)

jump to
M merkletree.go → merkletree.go

@@ -922,6 +922,20 @@ // key in the MerkleTree. If the rootKey is nil, the current merkletree root

// is used. func (mt *MerkleTree) GenerateCircomVerifierProof(k *big.Int, rootKey *Hash) (*CircomVerifierProof, error) { + cp, err := mt.GenerateSCVerifierProof(k, rootKey) + if err != nil { + return nil, err + } + cp.Siblings = CircomSiblingsFromSiblings(cp.Siblings, mt.maxLevels) + return cp, nil +} + +// GenerateSCVerifierProof returns the CircomVerifierProof for a certain key in +// the MerkleTree with the Siblings without the extra 0 needed at the circom +// circuits, which makes it straight forward to verifiy inside a Smart +// Contract. If the rootKey is nil, the current merkletree root is used. +func (mt *MerkleTree) GenerateSCVerifierProof(k *big.Int, + rootKey *Hash) (*CircomVerifierProof, error) { if rootKey == nil { rootKey = mt.Root() }

@@ -931,7 +945,7 @@ return nil, err

} var cp CircomVerifierProof cp.Root = rootKey - cp.Siblings = CircomSiblingsFromSiblings(p.AllSiblings(), mt.maxLevels) + cp.Siblings = p.AllSiblings() cp.OldKey = &HashZero cp.OldValue = &HashZero cp.Key = NewHashFromBigInt(k)
M merkletree_test.go → merkletree_test.go

@@ -706,6 +706,41 @@ "[19625419... 46910949... 18399594... 20473908... 0 0 0 0 0 0 0]",

fmt.Sprintf("%v", cpp.Siblings)) } +func TestSmtVerifier(t *testing.T) { + mt, err := NewMerkleTree(memory.NewMemoryStorage(), 4) + assert.Nil(t, err) + + err = mt.Add(big.NewInt(1), big.NewInt(11)) + assert.Nil(t, err) + err = mt.Add(big.NewInt(2), big.NewInt(22)) + assert.Nil(t, err) + err = mt.Add(big.NewInt(3), big.NewInt(33)) + assert.Nil(t, err) + err = mt.Add(big.NewInt(4), big.NewInt(44)) + assert.Nil(t, err) + + cvp, err := mt.GenerateCircomVerifierProof(big.NewInt(2), nil) + assert.Nil(t, err) + + jCvp, err := json.Marshal(cvp) + assert.Nil(t, err) + // Test vectors generated using https://github.com/iden3/circomlib smt.js + // Expect siblings with the extra 0 that the circom circuits need + expected := `{"root":"10171140035965439966839815283432442651152991056297946102647688349369299124493","siblings":["12422661758472400223401299094238820777063458096110016599986781158438915645129","4330149052063565277182642012557086942088176847773467265587998154672740895682","0","0","0"],"oldKey":"0","oldValue":"0","isOld0":false,"key":"2","value":"22","fnc":0}` //nolint:lll + assert.Equal(t, expected, string(jCvp)) + + cvp, err = mt.GenerateSCVerifierProof(big.NewInt(2), nil) + assert.Nil(t, err) + + jCvp, err = json.Marshal(cvp) + assert.Nil(t, err) + // Test vectors generated using https://github.com/iden3/circomlib smt.js + // Without the extra 0 that the circom circuits need, but that are not + // needed at a smart contract verification + expected = `{"root":"10171140035965439966839815283432442651152991056297946102647688349369299124493","siblings":["12422661758472400223401299094238820777063458096110016599986781158438915645129","4330149052063565277182642012557086942088176847773467265587998154672740895682"],"oldKey":"0","oldValue":"0","isOld0":false,"key":"2","value":"22","fnc":0}` //nolint:lll + assert.Equal(t, expected, string(jCvp)) +} + func TestTypesMarshalers(t *testing.T) { // test Hash marshalers h, err := NewHashFromString("42")