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 }