-
Notifications
You must be signed in to change notification settings - Fork 10
/
merkletreeparent.go
54 lines (45 loc) · 1.39 KB
/
merkletreeparent.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package bc
import (
"encoding/hex"
"github.com/libsv/go-bk/crypto"
"github.com/libsv/go-bt/v2"
"github.com/libsv/go-p2p/chaincfg/chainhash"
)
// MerkleTreeParentStr returns the Merkle Tree parent of two Merkle
// Tree children using hex strings instead of just bytes.
func MerkleTreeParentStr(leftNode, rightNode string) (string, error) {
l, err := hex.DecodeString(leftNode)
if err != nil {
return "", err
}
r, err := hex.DecodeString(rightNode)
if err != nil {
return "", err
}
return hex.EncodeToString(MerkleTreeParent(l, r)), nil
}
// MerkleTreeParent returns the Merkle Tree parent of two Merkle
// Tree children.
func MerkleTreeParent(leftNode, rightNode []byte) []byte {
// swap endianness before concatenating
l := bt.ReverseBytes(leftNode)
r := bt.ReverseBytes(rightNode)
// concatenate leaves
concat := append(l, r...)
// hash the concatenation
hash := crypto.Sha256d(concat)
// swap endianness at the end and convert to hex string
return bt.ReverseBytes(hash)
}
// MerkleTreeParentBytes returns the Merkle Tree parent of two Merkle Tree children.
// The expectation is that the bytes are not reversed.
func MerkleTreeParentBytes(l *chainhash.Hash, r *chainhash.Hash) *chainhash.Hash {
lb := l.CloneBytes()
rb := r.CloneBytes()
concat := append(lb, rb...)
hash, err := chainhash.NewHash(crypto.Sha256d(concat))
if err != nil {
return &chainhash.Hash{}
}
return hash
}