mirror of
https://github.com/arnaucube/go-merkletree-iden3.git
synced 2026-02-07 03:26:46 +01:00
Add Proof verification
This commit is contained in:
@@ -3,6 +3,7 @@ package merkletree
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@@ -430,3 +431,63 @@ func (mt *MerkleTree) GenerateProof(k *big.Int, rootKey *Hash) (*Proof, error) {
|
|||||||
}
|
}
|
||||||
return nil, ErrEntryIndexNotFound
|
return nil, ErrEntryIndexNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VerifyProof verifies the Merkle Proof for the entry and root.
|
||||||
|
func VerifyProof(rootKey *Hash, proof *Proof, k, v *big.Int) bool {
|
||||||
|
rootFromProof, err := RootFromProof(proof, k, v)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return bytes.Equal(rootKey[:], rootFromProof[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// RootFromProof calculates the root that would correspond to a tree whose
|
||||||
|
// siblings are the ones in the proof with the claim hashing to hIndex and
|
||||||
|
// hValue.
|
||||||
|
func RootFromProof(proof *Proof, k, v *big.Int) (*Hash, error) {
|
||||||
|
kHash := NewHashFromBigInt(k)
|
||||||
|
vHash := NewHashFromBigInt(v)
|
||||||
|
sibIdx := len(proof.Siblings) - 1
|
||||||
|
var err error
|
||||||
|
var midKey *Hash
|
||||||
|
if proof.Existence {
|
||||||
|
midKey, err = LeafKey(kHash, vHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if proof.NodeAux == nil {
|
||||||
|
midKey = &HashZero
|
||||||
|
} else {
|
||||||
|
if bytes.Equal(kHash[:], proof.NodeAux.Key[:]) {
|
||||||
|
return nil, fmt.Errorf("Non-existence proof being checked against hIndex equal to nodeAux")
|
||||||
|
}
|
||||||
|
midKey, err = LeafKey(proof.NodeAux.Key, proof.NodeAux.Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path := getPath(int(proof.depth), kHash[:])
|
||||||
|
var siblingKey *Hash
|
||||||
|
for lvl := int(proof.depth) - 1; lvl >= 0; lvl-- {
|
||||||
|
if common.TestBitBigEndian(proof.notempties[:], uint(lvl)) {
|
||||||
|
siblingKey = proof.Siblings[sibIdx]
|
||||||
|
sibIdx--
|
||||||
|
} else {
|
||||||
|
siblingKey = &HashZero
|
||||||
|
}
|
||||||
|
if path[lvl] {
|
||||||
|
midKey, err = NewNodeMiddle(siblingKey, midKey).Key()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
midKey, err = NewNodeMiddle(midKey, siblingKey).Key()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return midKey, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,4 +25,10 @@ func TestNewTree(t *testing.T) {
|
|||||||
err = mt.Add(big.NewInt(1234), big.NewInt(9876))
|
err = mt.Add(big.NewInt(1234), big.NewInt(9876))
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "16970503620176669663662021947486532860010370357132361783766545149750777353066", mt.Root().BigInt().String())
|
assert.Equal(t, "16970503620176669663662021947486532860010370357132361783766545149750777353066", mt.Root().BigInt().String())
|
||||||
|
|
||||||
|
proof, err := mt.GenerateProof(big.NewInt(33), nil)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
assert.True(t, VerifyProof(mt.Root(), proof, big.NewInt(33), big.NewInt(44)))
|
||||||
|
assert.True(t, !VerifyProof(mt.Root(), proof, big.NewInt(33), big.NewInt(45)))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user