|
@ -10,7 +10,6 @@ import ( |
|
|
"strings" |
|
|
"strings" |
|
|
"sync" |
|
|
"sync" |
|
|
|
|
|
|
|
|
"github.com/iden3/go-iden3-core/common" |
|
|
|
|
|
cryptoUtils "github.com/iden3/go-iden3-crypto/utils" |
|
|
cryptoUtils "github.com/iden3/go-iden3-crypto/utils" |
|
|
"github.com/iden3/go-merkletree/db" |
|
|
"github.com/iden3/go-merkletree/db" |
|
|
) |
|
|
) |
|
@ -88,16 +87,16 @@ func (h Hash) Hex() string { |
|
|
// alternatively equivalent, but with too extra steps:
|
|
|
// alternatively equivalent, but with too extra steps:
|
|
|
// bRaw := h.BigInt().Bytes()
|
|
|
// bRaw := h.BigInt().Bytes()
|
|
|
// b := [32]byte{}
|
|
|
// b := [32]byte{}
|
|
|
// copy(b[:], common.SwapEndianness(bRaw[:]))
|
|
|
|
|
|
|
|
|
// copy(b[:], SwapEndianness(bRaw[:]))
|
|
|
// return hex.EncodeToString(b[:])
|
|
|
// return hex.EncodeToString(b[:])
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// BigInt returns the *big.Int representation of the *Hash
|
|
|
// BigInt returns the *big.Int representation of the *Hash
|
|
|
func (h *Hash) BigInt() *big.Int { |
|
|
func (h *Hash) BigInt() *big.Int { |
|
|
if new(big.Int).SetBytes(common.SwapEndianness(h[:])) == nil { |
|
|
|
|
|
|
|
|
if new(big.Int).SetBytes(SwapEndianness(h[:])) == nil { |
|
|
return big.NewInt(0) |
|
|
return big.NewInt(0) |
|
|
} |
|
|
} |
|
|
return new(big.Int).SetBytes(common.SwapEndianness(h[:])) |
|
|
|
|
|
|
|
|
return new(big.Int).SetBytes(SwapEndianness(h[:])) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Bytes returns the []byte representation of the *Hash, which always is 32
|
|
|
// Bytes returns the []byte representation of the *Hash, which always is 32
|
|
@ -105,7 +104,7 @@ func (h *Hash) BigInt() *big.Int { |
|
|
func (h *Hash) Bytes() []byte { |
|
|
func (h *Hash) Bytes() []byte { |
|
|
bi := new(big.Int).SetBytes(h[:]).Bytes() |
|
|
bi := new(big.Int).SetBytes(h[:]).Bytes() |
|
|
b := [32]byte{} |
|
|
b := [32]byte{} |
|
|
copy(b[:], common.SwapEndianness(bi[:])) |
|
|
|
|
|
|
|
|
copy(b[:], SwapEndianness(bi[:])) |
|
|
return b[:] |
|
|
return b[:] |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -115,13 +114,11 @@ func (h *Hash) Bytes() []byte { |
|
|
// method.
|
|
|
// method.
|
|
|
func NewBigIntFromHashBytes(b []byte) (*big.Int, error) { |
|
|
func NewBigIntFromHashBytes(b []byte) (*big.Int, error) { |
|
|
if len(b) != ElemBytesLen { |
|
|
if len(b) != ElemBytesLen { |
|
|
return nil, fmt.Errorf("Expected 32 bytes, found %d bytes", |
|
|
|
|
|
len(b)) |
|
|
|
|
|
|
|
|
return nil, fmt.Errorf("Expected 32 bytes, found %d bytes", len(b)) |
|
|
} |
|
|
} |
|
|
bi := new(big.Int).SetBytes(b[:ElemBytesLen]) |
|
|
bi := new(big.Int).SetBytes(b[:ElemBytesLen]) |
|
|
if !cryptoUtils.CheckBigIntInField(bi) { |
|
|
if !cryptoUtils.CheckBigIntInField(bi) { |
|
|
return nil, |
|
|
|
|
|
fmt.Errorf("NewBigIntFromHashBytes: Value not inside the Finite Field") |
|
|
|
|
|
|
|
|
return nil, fmt.Errorf("NewBigIntFromHashBytes: Value not inside the Finite Field") |
|
|
} |
|
|
} |
|
|
return bi, nil |
|
|
return bi, nil |
|
|
} |
|
|
} |
|
@ -129,7 +126,7 @@ func NewBigIntFromHashBytes(b []byte) (*big.Int, error) { |
|
|
// NewHashFromBigInt returns a *Hash representation of the given *big.Int
|
|
|
// NewHashFromBigInt returns a *Hash representation of the given *big.Int
|
|
|
func NewHashFromBigInt(b *big.Int) *Hash { |
|
|
func NewHashFromBigInt(b *big.Int) *Hash { |
|
|
r := &Hash{} |
|
|
r := &Hash{} |
|
|
copy(r[:], common.SwapEndianness(b.Bytes())) |
|
|
|
|
|
|
|
|
copy(r[:], SwapEndianness(b.Bytes())) |
|
|
return r |
|
|
return r |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -138,11 +135,10 @@ func NewHashFromBigInt(b *big.Int) *Hash { |
|
|
// that previously has ben generated by the Hash.Bytes() method.
|
|
|
// that previously has ben generated by the Hash.Bytes() method.
|
|
|
func NewHashFromBytes(b []byte) (*Hash, error) { |
|
|
func NewHashFromBytes(b []byte) (*Hash, error) { |
|
|
if len(b) != ElemBytesLen { |
|
|
if len(b) != ElemBytesLen { |
|
|
return nil, fmt.Errorf("Expected 32 bytes, found %d bytes", |
|
|
|
|
|
len(b)) |
|
|
|
|
|
|
|
|
return nil, fmt.Errorf("Expected 32 bytes, found %d bytes", len(b)) |
|
|
} |
|
|
} |
|
|
var h Hash |
|
|
var h Hash |
|
|
copy(h[:], common.SwapEndianness(b)) |
|
|
|
|
|
|
|
|
copy(h[:], SwapEndianness(b)) |
|
|
return &h, nil |
|
|
return &h, nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -153,7 +149,7 @@ func NewHashFromHex(h string) (*Hash, error) { |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
return nil, err |
|
|
return nil, err |
|
|
} |
|
|
} |
|
|
return NewHashFromBytes(common.SwapEndianness(b[:])) |
|
|
|
|
|
|
|
|
return NewHashFromBytes(SwapEndianness(b[:])) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// NewHashFromString returns a *Hash representation of the given decimal string
|
|
|
// NewHashFromString returns a *Hash representation of the given decimal string
|
|
@ -327,8 +323,7 @@ func (mt *MerkleTree) pushLeaf(tx db.Tx, newLeaf *Node, oldLeaf *Node, lvl int, |
|
|
} |
|
|
} |
|
|
var newNodeMiddle *Node |
|
|
var newNodeMiddle *Node |
|
|
if pathNewLeaf[lvl] == pathOldLeaf[lvl] { // We need to go deeper!
|
|
|
if pathNewLeaf[lvl] == pathOldLeaf[lvl] { // We need to go deeper!
|
|
|
nextKey, err := mt.pushLeaf(tx, newLeaf, oldLeaf, lvl+1, |
|
|
|
|
|
pathNewLeaf, pathOldLeaf) |
|
|
|
|
|
|
|
|
nextKey, err := mt.pushLeaf(tx, newLeaf, oldLeaf, lvl+1, pathNewLeaf, pathOldLeaf) |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
return nil, err |
|
|
return nil, err |
|
|
} |
|
|
} |
|
@ -395,12 +390,10 @@ func (mt *MerkleTree) addLeaf(tx db.Tx, newLeaf *Node, key *Hash, |
|
|
// right depending on path
|
|
|
// right depending on path
|
|
|
var newNodeMiddle *Node |
|
|
var newNodeMiddle *Node |
|
|
if path[lvl] { // go right
|
|
|
if path[lvl] { // go right
|
|
|
nextKey, err = mt.addLeaf(tx, newLeaf, n.ChildR, lvl+1, |
|
|
|
|
|
path) |
|
|
|
|
|
|
|
|
nextKey, err = mt.addLeaf(tx, newLeaf, n.ChildR, lvl+1, path) |
|
|
newNodeMiddle = NewNodeMiddle(n.ChildL, nextKey) |
|
|
newNodeMiddle = NewNodeMiddle(n.ChildL, nextKey) |
|
|
} else { // go left
|
|
|
} else { // go left
|
|
|
nextKey, err = mt.addLeaf(tx, newLeaf, n.ChildL, lvl+1, |
|
|
|
|
|
path) |
|
|
|
|
|
|
|
|
nextKey, err = mt.addLeaf(tx, newLeaf, n.ChildL, lvl+1, path) |
|
|
newNodeMiddle = NewNodeMiddle(nextKey, n.ChildR) |
|
|
newNodeMiddle = NewNodeMiddle(nextKey, n.ChildR) |
|
|
} |
|
|
} |
|
|
if err != nil { |
|
|
if err != nil { |
|
@ -459,8 +452,7 @@ func (mt *MerkleTree) updateNode(tx db.Tx, n *Node) (*Hash, error) { |
|
|
func (mt *MerkleTree) Get(k *big.Int) (*big.Int, *big.Int, []*Hash, error) { |
|
|
func (mt *MerkleTree) Get(k *big.Int) (*big.Int, *big.Int, []*Hash, error) { |
|
|
// verfy that k is valid and fit inside the Finite Field.
|
|
|
// verfy that k is valid and fit inside the Finite Field.
|
|
|
if !cryptoUtils.CheckBigIntInField(k) { |
|
|
if !cryptoUtils.CheckBigIntInField(k) { |
|
|
return nil, nil, nil, |
|
|
|
|
|
errors.New("Key not inside the Finite Field") |
|
|
|
|
|
|
|
|
return nil, nil, nil, errors.New("Key not inside the Finite Field") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
kHash := NewHashFromBigInt(k) |
|
|
kHash := NewHashFromBigInt(k) |
|
@ -759,7 +751,7 @@ func (mt *MerkleTree) GetNode(key *Hash) (*Node, error) { |
|
|
func getPath(numLevels int, k []byte) []bool { |
|
|
func getPath(numLevels int, k []byte) []bool { |
|
|
path := make([]bool, numLevels) |
|
|
path := make([]bool, numLevels) |
|
|
for n := 0; n < numLevels; n++ { |
|
|
for n := 0; n < numLevels; n++ { |
|
|
path[n] = common.TestBit(k[:], uint(n)) |
|
|
|
|
|
|
|
|
path[n] = TestBit(k[:], uint(n)) |
|
|
} |
|
|
} |
|
|
return path |
|
|
return path |
|
|
} |
|
|
} |
|
@ -799,7 +791,7 @@ func NewProofFromBytes(bs []byte) (*Proof, error) { |
|
|
siblingBytes := bs[ElemBytesLen:] |
|
|
siblingBytes := bs[ElemBytesLen:] |
|
|
sibIdx := 0 |
|
|
sibIdx := 0 |
|
|
for i := uint(0); i < p.depth; i++ { |
|
|
for i := uint(0); i < p.depth; i++ { |
|
|
if common.TestBitBigEndian(p.notempties[:], i) { |
|
|
|
|
|
|
|
|
if TestBitBigEndian(p.notempties[:], i) { |
|
|
if len(siblingBytes) < (sibIdx+1)*ElemBytesLen { |
|
|
if len(siblingBytes) < (sibIdx+1)*ElemBytesLen { |
|
|
return nil, ErrInvalidProofBytes |
|
|
return nil, ErrInvalidProofBytes |
|
|
} |
|
|
} |
|
@ -852,7 +844,7 @@ func SiblingsFromProof(proof *Proof) []*Hash { |
|
|
sibIdx := 0 |
|
|
sibIdx := 0 |
|
|
var siblings []*Hash |
|
|
var siblings []*Hash |
|
|
for lvl := 0; lvl < int(proof.depth); lvl++ { |
|
|
for lvl := 0; lvl < int(proof.depth); lvl++ { |
|
|
if common.TestBitBigEndian(proof.notempties[:], uint(lvl)) { |
|
|
|
|
|
|
|
|
if TestBitBigEndian(proof.notempties[:], uint(lvl)) { |
|
|
siblings = append(siblings, proof.Siblings[sibIdx]) |
|
|
siblings = append(siblings, proof.Siblings[sibIdx]) |
|
|
sibIdx++ |
|
|
sibIdx++ |
|
|
} else { |
|
|
} else { |
|
@ -995,7 +987,7 @@ func (mt *MerkleTree) GenerateProof(k *big.Int, rootKey *Hash) (*Proof, |
|
|
return nil, nil, ErrInvalidNodeFound |
|
|
return nil, nil, ErrInvalidNodeFound |
|
|
} |
|
|
} |
|
|
if !bytes.Equal(siblingKey[:], HashZero[:]) { |
|
|
if !bytes.Equal(siblingKey[:], HashZero[:]) { |
|
|
common.SetBitBigEndian(p.notempties[:], uint(p.depth)) |
|
|
|
|
|
|
|
|
SetBitBigEndian(p.notempties[:], uint(p.depth)) |
|
|
p.Siblings = append(p.Siblings, siblingKey) |
|
|
p.Siblings = append(p.Siblings, siblingKey) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -1042,7 +1034,7 @@ func RootFromProof(proof *Proof, k, v *big.Int) (*Hash, error) { |
|
|
path := getPath(int(proof.depth), kHash[:]) |
|
|
path := getPath(int(proof.depth), kHash[:]) |
|
|
var siblingKey *Hash |
|
|
var siblingKey *Hash |
|
|
for lvl := int(proof.depth) - 1; lvl >= 0; lvl-- { |
|
|
for lvl := int(proof.depth) - 1; lvl >= 0; lvl-- { |
|
|
if common.TestBitBigEndian(proof.notempties[:], uint(lvl)) { |
|
|
|
|
|
|
|
|
if TestBitBigEndian(proof.notempties[:], uint(lvl)) { |
|
|
siblingKey = proof.Siblings[sibIdx] |
|
|
siblingKey = proof.Siblings[sibIdx] |
|
|
sibIdx-- |
|
|
sibIdx-- |
|
|
} else { |
|
|
} else { |
|
|