github.com/zorawar87/trillian@v1.2.1/merkle/coniks/coniks.go (about) 1 // Copyright 2017 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package coniks provides hashing for maps. 16 package coniks 17 18 import ( 19 "crypto" 20 "encoding/binary" 21 "fmt" 22 23 "github.com/golang/glog" 24 "github.com/google/trillian" 25 "github.com/google/trillian/merkle/hashers" 26 ) 27 28 func init() { 29 hashers.RegisterMapHasher(trillian.HashStrategy_CONIKS_SHA512_256, Default) 30 } 31 32 // Domain separation prefixes 33 var ( 34 leafIdentifier = []byte("L") 35 emptyIdentifier = []byte("E") 36 ) 37 38 // Default is the standard CONIKS hasher. 39 var Default = New(crypto.SHA512_256) 40 41 // hasher implements the sparse merkle tree hashing algorithm specified in the CONIKS paper. 42 type hasher struct { 43 crypto.Hash 44 } 45 46 // New creates a new hashers.TreeHasher using the passed in hash function. 47 func New(h crypto.Hash) hashers.MapHasher { 48 return &hasher{Hash: h} 49 } 50 51 // EmptyRoot returns the root of an empty tree. 52 func (m *hasher) EmptyRoot() []byte { 53 panic("EmptyRoot() not defined for coniks.Hasher") 54 } 55 56 // HashEmpty returns the hash of an empty branch at a given height. 57 // A height of 0 indicates the hash of an empty leaf. 58 // Empty branches within the tree are plain interior nodes e1 = H(e0, e0) etc. 59 func (m *hasher) HashEmpty(treeID int64, index []byte, height int) []byte { 60 depth := m.BitLen() - height 61 62 h := m.New() 63 h.Write(emptyIdentifier) 64 binary.Write(h, binary.BigEndian, uint64(treeID)) 65 h.Write(m.maskIndex(index, depth)) 66 binary.Write(h, binary.BigEndian, uint32(depth)) 67 r := h.Sum(nil) 68 glog.V(5).Infof("HashEmpty(%x, %d): %x", index, depth, r) 69 return r 70 } 71 72 // HashLeaf calculate the merkle tree leaf value: 73 // H(Identifier || treeID || depth || index || dataHash) 74 func (m *hasher) HashLeaf(treeID int64, index []byte, leaf []byte) ([]byte, error) { 75 depth := m.BitLen() 76 h := m.New() 77 h.Write(leafIdentifier) 78 binary.Write(h, binary.BigEndian, uint64(treeID)) 79 h.Write(m.maskIndex(index, depth)) 80 binary.Write(h, binary.BigEndian, uint32(depth)) 81 h.Write(leaf) 82 p := h.Sum(nil) 83 glog.V(5).Infof("HashLeaf(%x, %d, %s): %x", index, depth, leaf, p) 84 return p, nil 85 } 86 87 // HashChildren returns the internal Merkle tree node hash of the the two child nodes l and r. 88 // The hashed structure is H(l || r). 89 func (m *hasher) HashChildren(l, r []byte) []byte { 90 h := m.New() 91 h.Write(l) 92 h.Write(r) 93 p := h.Sum(nil) 94 glog.V(5).Infof("HashChildren(%x, %x): %x", l, r, p) 95 return p 96 } 97 98 // BitLen returns the number of bits in the hash function. 99 func (m *hasher) BitLen() int { 100 return m.Size() * 8 101 } 102 103 // leftmask contains bitmasks indexed such that the left x bits are set. It is 104 // indexed by byte position from 0-7 0 is special cased to 0xFF since 8 mod 8 105 // is 0. leftmask is only used to mask the last byte. 106 var leftmask = [8]byte{0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE} 107 108 // maskIndex returns index with only the left depth bits set. 109 // index must be of size m.Size() and 0 <= depth <= m.BitLen(). 110 // e.g. 111 func (m *hasher) maskIndex(index []byte, depth int) []byte { 112 if got, want := len(index), m.Size(); got != want { 113 panic(fmt.Sprintf("index len: %d, want %d", got, want)) 114 } 115 if got, want := depth, m.BitLen(); got < 0 || got > want { 116 panic(fmt.Sprintf("depth: %d, want <= %d && > 0", got, want)) 117 } 118 119 // Create an empty index Size() bytes long. 120 ret := make([]byte, m.Size()) 121 if depth > 0 { 122 // Copy the first depthBytes. 123 depthBytes := (depth + 7) >> 3 124 copy(ret, index[:depthBytes]) 125 // Mask off unwanted bits in the last byte. 126 ret[depthBytes-1] = ret[depthBytes-1] & leftmask[depth%8] 127 } 128 return ret 129 }