Search Apps Documentation Source Content File Folder Download Copy Actions Download

merkle.gno

1.06 Kb · 50 lines
 1package merkle
 2
 3import (
 4	"crypto/sha256"
 5)
 6
 7// HashFromByteSlices computes a Merkle tree where the leaves are the byte
 8// slice, in the provided order. It follows RFC-6962.
 9func HashFromByteSlices(items [][]byte) []byte {
10	switch len(items) {
11	case 0:
12		return emptyHash()
13	case 1:
14		return leafHash(items[0])
15	default:
16		// Find the split point (largest power of 2 <= len(items)).
17		length := len(items)
18		var k int
19		for k = 1; k < length; k <<= 1 {
20		}
21		k >>= 1
22
23		left := HashFromByteSlices(items[:k])
24		right := HashFromByteSlices(items[k:])
25		return innerHash(left, right)
26	}
27}
28
29var (
30	leafPrefix  = []byte{0x00}
31	innerPrefix = []byte{0x01}
32)
33
34// emptyHash returns sha256(<empty>)
35func emptyHash() []byte {
36	bz := sha256.Sum256([]byte{})
37	return bz[:]
38}
39
40// leafHash returns sha256(0x00 || leaf)
41func leafHash(leaf []byte) []byte {
42	bz := sha256.Sum256(append(leafPrefix, leaf...))
43	return bz[:]
44}
45
46// innerHash returns sha256(0x01 || left || right)
47func innerHash(left, right []byte) []byte {
48	bz := sha256.Sum256(append(innerPrefix, append(left, right...)...))
49	return bz[:]
50}