github.com/protolambda/zssz@v0.1.5/htr/hash_tree_root.go (about) 1 package htr 2 3 import ( 4 "crypto/sha256" 5 "encoding/binary" 6 "unsafe" 7 ) 8 9 type MerkleFn interface { 10 Combi(a [32]byte, b [32]byte) [32]byte 11 MixIn(a [32]byte, i uint64) [32]byte 12 } 13 14 type HashTreeRootFn func(mfn MerkleFn, pointer unsafe.Pointer) [32]byte 15 16 // Warning, it implements a MerkleFn, but it is preferable to use a cached (Scratchpad) version of the merkle fn. 17 type HashFn func(input []byte) [32]byte 18 19 // Excluding the full zero bytes32 itself 20 const zeroHashesLevels = 64 21 22 var ZeroHashes [][32]byte 23 24 // initialize the zero-hashes pre-computed data with the given hash-function. 25 func InitZeroHashes(hFn HashFn) { 26 ZeroHashes = make([][32]byte, zeroHashesLevels+1) 27 v := [64]byte{} 28 for i := 0; i < zeroHashesLevels; i++ { 29 copy(v[:32], ZeroHashes[i][:]) 30 copy(v[32:], ZeroHashes[i][:]) 31 ZeroHashes[i+1] = hFn(v[:]) 32 } 33 } 34 35 func init() { 36 InitZeroHashes(sha256.Sum256) 37 } 38 39 func (h HashFn) Combi(a [32]byte, b [32]byte) [32]byte { 40 v := [64]byte{} 41 copy(v[:32], a[:]) 42 copy(v[32:], b[:]) 43 return h(v[:]) 44 } 45 46 func (h HashFn) MixIn(a [32]byte, i uint64) [32]byte { 47 v := [64]byte{} 48 copy(v[:32], a[:]) 49 copy(v[32:], make([]byte, 32, 32)) 50 binary.LittleEndian.PutUint64(v[32:], i) 51 return h(v[:]) 52 }