66 lines
1.2 KiB
Go
66 lines
1.2 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
)
|
|
|
|
// MerkleTree represent a Merkle tree
|
|
type MerkleTree struct {
|
|
RootNode *MerkleNode
|
|
}
|
|
|
|
// MerkleNode represent a Merkle tree node
|
|
type MerkleNode struct {
|
|
Left *MerkleNode
|
|
Right *MerkleNode
|
|
Data []byte
|
|
}
|
|
|
|
// NewMerkleTree creates a new Merkle tree from a sequence of data
|
|
func NewMerkleTree(data [][]byte) *MerkleTree {
|
|
var nodes []MerkleNode
|
|
|
|
if len(data)%2 != 0 {
|
|
data = append(data, data[len(data)-1])
|
|
}
|
|
|
|
for _, datum := range data {
|
|
node := NewMerkleNode(nil, nil, datum)
|
|
nodes = append(nodes, *node)
|
|
}
|
|
|
|
for i := 0; i < len(data)/2; i++ {
|
|
var newLevel []MerkleNode
|
|
|
|
for j := 0; j < len(nodes); j += 2 {
|
|
node := NewMerkleNode(&nodes[j], &nodes[j+1], nil)
|
|
newLevel = append(newLevel, *node)
|
|
}
|
|
|
|
nodes = newLevel
|
|
}
|
|
|
|
mTree := MerkleTree{&nodes[0]}
|
|
|
|
return &mTree
|
|
}
|
|
|
|
// NewMerkleNode creates a new Merkle tree node
|
|
func NewMerkleNode(left, right *MerkleNode, data []byte) *MerkleNode {
|
|
mNode := MerkleNode{}
|
|
|
|
if left == nil && right == nil {
|
|
hash := sha256.Sum256(data)
|
|
mNode.Data = hash[:]
|
|
} else {
|
|
prevHashes := append(left.Data, right.Data...)
|
|
hash := sha256.Sum256(prevHashes)
|
|
mNode.Data = hash[:]
|
|
}
|
|
|
|
mNode.Left = left
|
|
mNode.Right = right
|
|
|
|
return &mNode
|
|
}
|