github.com/letsencrypt/trillian@v1.1.2-0.20180615153820-ae375a99d36a/merkle/hstar2.go (about) 1 // Copyright 2016 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 merkle 16 17 import ( 18 "errors" 19 "fmt" 20 "math/big" 21 "sort" 22 23 "github.com/golang/glog" 24 "github.com/google/trillian/merkle/hashers" 25 "github.com/google/trillian/storage" 26 ) 27 28 var ( 29 // ErrSubtreeOverrun indicates that a subtree exceeds the maximum tree depth. 30 ErrSubtreeOverrun = errors.New("subtree with prefix exceeds maximum tree size") 31 smtOne = big.NewInt(1) 32 smtZero = big.NewInt(0) 33 ) 34 35 // HStar2LeafHash represents a leaf for the HStar2 sparse Merkle tree 36 // implementation. 37 type HStar2LeafHash struct { 38 // TODO(al): remove big.Int 39 Index *big.Int 40 LeafHash []byte 41 } 42 43 // HStar2 is a recursive implementation for calculating the root hash of a sparse 44 // Merkle tree. 45 type HStar2 struct { 46 treeID int64 47 hasher hashers.MapHasher 48 } 49 50 // NewHStar2 creates a new HStar2 tree calculator based on the passed in MapHasher. 51 func NewHStar2(treeID int64, hasher hashers.MapHasher) HStar2 { 52 return HStar2{ 53 treeID: treeID, 54 hasher: hasher, 55 } 56 } 57 58 // HStar2Root calculates the root of a sparse Merkle tree of a given depth 59 // which contains the given set of non-null leaves. 60 func (s *HStar2) HStar2Root(depth int, values []HStar2LeafHash) ([]byte, error) { 61 sort.Sort(ByIndex{values}) 62 return s.hStar2b(0, depth, values, smtZero, nil, nil) 63 } 64 65 // SparseGetNodeFunc should return any pre-existing node hash for the node address. 66 type SparseGetNodeFunc func(depth int, index *big.Int) ([]byte, error) 67 68 // SparseSetNodeFunc should store the passed node hash, associating it with the address. 69 type SparseSetNodeFunc func(depth int, index *big.Int, hash []byte) error 70 71 // HStar2Nodes calculates the root hash of a pre-existing sparse Merkle tree 72 // plus the extra values passed in. Get and set are used to fetch and store 73 // internal node values. Values must not contain multiple leaves for the same 74 // index. 75 // 76 // prefix is the location of this subtree within the larger tree. Root is at nil. 77 // subtreeDepth is the number of levels in this subtree. 78 func (s *HStar2) HStar2Nodes(prefix []byte, subtreeDepth int, values []HStar2LeafHash, 79 get SparseGetNodeFunc, set SparseSetNodeFunc) ([]byte, error) { 80 if glog.V(3) { 81 glog.Infof("HStar2Nodes(%x, %v, %v)", prefix, subtreeDepth, len(values)) 82 for _, v := range values { 83 glog.Infof(" %x: %x", v.Index.Bytes(), v.LeafHash) 84 } 85 } 86 depth := len(prefix) * 8 87 totalDepth := depth + subtreeDepth 88 if totalDepth > s.hasher.BitLen() { 89 return nil, ErrSubtreeOverrun 90 } 91 sort.Sort(ByIndex{values}) 92 offset := storage.NewNodeIDFromPrefixSuffix(prefix, storage.Suffix{}, s.hasher.BitLen()).BigInt() 93 return s.hStar2b(depth, totalDepth, values, offset, get, set) 94 } 95 96 // hStar2b computes a sparse Merkle tree root value recursively. 97 func (s *HStar2) hStar2b(depth, maxDepth int, values []HStar2LeafHash, offset *big.Int, 98 get SparseGetNodeFunc, set SparseSetNodeFunc) ([]byte, error) { 99 if depth == maxDepth { 100 switch { 101 case len(values) == 0: 102 return s.get(offset, depth, get) 103 case len(values) == 1: 104 return values[0].LeafHash, nil 105 default: 106 return nil, fmt.Errorf("hStar2b base case: len(values): %d, want 1", len(values)) 107 } 108 } 109 if len(values) == 0 { 110 return s.get(offset, depth, get) 111 } 112 113 bitsLeft := s.hasher.BitLen() - depth 114 split := new(big.Int).Lsh(smtOne, uint(bitsLeft-1)) 115 split.Add(split, offset) 116 i := sort.Search(len(values), func(i int) bool { return values[i].Index.Cmp(split) >= 0 }) 117 lhs, err := s.hStar2b(depth+1, maxDepth, values[:i], offset, get, set) 118 if err != nil { 119 return nil, err 120 } 121 rhs, err := s.hStar2b(depth+1, maxDepth, values[i:], split, get, set) 122 if err != nil { 123 return nil, err 124 } 125 h := s.hasher.HashChildren(lhs, rhs) 126 s.set(offset, depth, h, set) 127 return h, nil 128 } 129 130 // get attempts to use getter. If getter fails, returns the HashEmpty value. 131 func (s *HStar2) get(index *big.Int, depth int, getter SparseGetNodeFunc) ([]byte, error) { 132 // if we've got a function for getting existing node values, try it: 133 if getter != nil { 134 h, err := getter(depth, index) 135 if err != nil { 136 return nil, err 137 } 138 // if we got a value then we'll use that 139 if h != nil { 140 return h, nil 141 } 142 } 143 // TODO(gdbelvin): Hashers should accept depth as their main argument. 144 height := s.hasher.BitLen() - depth 145 nodeID := storage.NewNodeIDFromBigInt(index.BitLen(), index, s.hasher.BitLen()) 146 return s.hasher.HashEmpty(s.treeID, nodeID.Path, height), nil 147 } 148 149 // set attempts to use setter if it not nil. 150 func (s *HStar2) set(index *big.Int, depth int, hash []byte, setter SparseSetNodeFunc) error { 151 if setter != nil { 152 return setter(depth, index, hash) 153 } 154 return nil 155 } 156 157 // HStar2LeafHash sorting boilerplate below. 158 159 // Leaves is a slice of HStar2LeafHash 160 type Leaves []HStar2LeafHash 161 162 // Len returns the number of leaves. 163 func (s Leaves) Len() int { return len(s) } 164 165 // Swap swaps two leaf locations. 166 func (s Leaves) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 167 168 // ByIndex implements sort.Interface by providing Less and using Len and Swap methods from the embedded Leaves value. 169 type ByIndex struct{ Leaves } 170 171 // Less returns true if i.Index < j.Index 172 func (s ByIndex) Less(i, j int) bool { return s.Leaves[i].Index.Cmp(s.Leaves[j].Index) < 0 }