github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/merkletree2/tree.go (about)

     1  package merkletree2
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"sort"
     7  	"sync"
     8  
     9  	"github.com/keybase/client/go/logger"
    10  	"github.com/keybase/go-codec/codec"
    11  )
    12  
    13  // Tree is the MerkleTree class; it needs an engine and a configuration
    14  // to run
    15  type Tree struct {
    16  	sync.RWMutex
    17  
    18  	cfg Config
    19  	eng StorageEngine
    20  
    21  	newRootVersion RootVersion
    22  
    23  	// step is an optimization parameter for GetKeyValuePairWithProof that
    24  	// controls how many path positions at a time the tree requests from the
    25  	// storage engine. Lower values result in more storage engine requests, but
    26  	// less of the (somewhat expensive) bit fiddling operations.  Values higher
    27  	// than 63 are not recommended as the bit operations (in the best case)
    28  	// cannot be done using a single 64 bit word and become more expensive. This
    29  	// is unnecessary if the tree has random keys (as such a tree should be
    30  	// approximately balanced and have short-ish paths).
    31  	step int
    32  
    33  	// these two fields are used as buffers during tree building to avoid making
    34  	// many short lived memory allocations
    35  	bufKss  KeySpecificSecret
    36  	bufLeaf Node
    37  }
    38  
    39  // NewTree makes a new tree
    40  func NewTree(c Config, step int, e StorageEngine, v RootVersion) (*Tree, error) {
    41  	if c.UseBlindedValueHashes {
    42  		_, ok := e.(StorageEngineWithBlinding)
    43  		if !ok {
    44  			return nil, fmt.Errorf("The config requires a StorageEngineWithBlinding implementation as a StorageEngine")
    45  		}
    46  	}
    47  	if step < 1 {
    48  		return nil, fmt.Errorf("step must be a positive integer")
    49  	}
    50  
    51  	return &Tree{cfg: c, eng: e, step: step, newRootVersion: v}, nil
    52  }
    53  
    54  // Hash is a byte-array, used to represent a full collision-resistant hash.
    55  type Hash []byte
    56  
    57  // Equal compares two hashes byte by byte
    58  func (h Hash) Equal(h2 Hash) bool {
    59  	return bytes.Equal(h, h2)
    60  }
    61  
    62  // Key is a byte-array, and it is the type of the keys in the KeyValuePairs that
    63  // the tree can store.
    64  type Key []byte
    65  
    66  // Equal compares two keys byte by byte
    67  func (k Key) Equal(k2 Key) bool {
    68  	return bytes.Equal(k, k2)
    69  }
    70  
    71  // Cmp compares two keys lexicographically as byte slices
    72  func (k Key) Cmp(k2 Key) int {
    73  	return bytes.Compare(k, k2)
    74  }
    75  
    76  // Seqno is an integer used to differentiate different versions of a merkle tree.
    77  type Seqno int64
    78  
    79  type SeqnoSortedAsInt []Seqno
    80  
    81  func (d SeqnoSortedAsInt) Len() int {
    82  	return len(d)
    83  }
    84  
    85  func (d SeqnoSortedAsInt) Swap(i, j int) {
    86  	d[i], d[j] = d[j], d[i]
    87  }
    88  
    89  func (d SeqnoSortedAsInt) Less(i, j int) bool {
    90  	return d[i] < d[j]
    91  }
    92  
    93  // ChildIndex specifies one of an iNode's child nodes.
    94  type ChildIndex int
    95  
    96  // KeyValuePair is something the merkle tree can store. The key can be something
    97  // like a UID or a TLF ID.  The Value is a generic interface, so you can store
    98  // anything there, as long as it obeys Msgpack-decoding behavior. The Value must
    99  // be of the same type returned by ValueConstructor in the TreeConfig, otherwise
   100  // the behavior is undefined.
   101  type KeyValuePair struct {
   102  	_struct struct{}    `codec:",toarray"` //nolint
   103  	Key     Key         `codec:"k"`
   104  	Value   interface{} `codec:"v"`
   105  }
   106  
   107  type EncodedValue []byte
   108  
   109  func (e EncodedValue) Equal(e2 EncodedValue) bool {
   110  	return bytes.Equal(e, e2)
   111  }
   112  
   113  // KeyEncodedValuePair is similar to a KeyValuePair, but the values is encoded
   114  // as a byte slice.
   115  type KeyEncodedValuePair struct {
   116  	_struct struct{}     `codec:",toarray"` //nolint
   117  	Key     Key          `codec:"k"`
   118  	Value   EncodedValue `codec:"v"`
   119  }
   120  
   121  type KeyHashPair struct {
   122  	_struct struct{} `codec:",toarray"` //nolint
   123  	Key     Key      `codec:"k"`
   124  	Hash    Hash     `codec:"h"`
   125  }
   126  
   127  // NodeType is used to distinguish serialized internal nodes from leaves in the tree
   128  type NodeType uint8
   129  
   130  const (
   131  	NodeTypeNone  NodeType = 0
   132  	NodeTypeINode NodeType = 1
   133  	NodeTypeLeaf  NodeType = 2
   134  )
   135  
   136  // A Node is either an internal node or a leaf: INodes and LeafHashes cannot
   137  // both have length > 0 (else msgpack encoding will fail).
   138  type Node struct {
   139  	INodes     []Hash
   140  	LeafHashes []KeyHashPair
   141  }
   142  
   143  var _ codec.Selfer = &Node{}
   144  
   145  func (n *Node) CodecEncodeSelf(e *codec.Encoder) {
   146  	if n.INodes != nil && n.LeafHashes != nil && len(n.INodes) > 0 && len(n.LeafHashes) > 0 {
   147  		panic("Cannot Encode a node with both Inodes and LeafHashes")
   148  	}
   149  
   150  	if n.INodes != nil && len(n.INodes) > 0 {
   151  		e.MustEncode(NodeTypeINode)
   152  		e.MustEncode(n.INodes)
   153  		return
   154  	}
   155  
   156  	// Note: we encode empty nodes (with empty or nil LeafHashes) as leaf nodes.
   157  	// This is so we can represent a tree with no values as a single (empty)
   158  	// leaf node.
   159  	e.MustEncode(NodeTypeLeaf)
   160  	// encode empty slices and nil slices equally
   161  	if len(n.LeafHashes) == 0 {
   162  		e.MustEncode([]KeyHashPair(nil))
   163  	} else {
   164  		e.MustEncode(n.LeafHashes)
   165  	}
   166  }
   167  
   168  func (n *Node) CodecDecodeSelf(d *codec.Decoder) {
   169  	var nodeType NodeType
   170  	d.MustDecode(&nodeType)
   171  	switch nodeType {
   172  	case NodeTypeINode:
   173  		d.MustDecode(&n.INodes)
   174  	case NodeTypeLeaf:
   175  		d.MustDecode(&n.LeafHashes)
   176  	default:
   177  		panic("Unrecognized NodeType")
   178  	}
   179  }
   180  
   181  type PositionHashPair struct {
   182  	_struct  struct{} `codec:",toarray"` //nolint
   183  	Position Position `codec:"p"`
   184  	Hash     Hash     `codec:"h"`
   185  }
   186  
   187  type RootVersion uint8
   188  
   189  const (
   190  	RootVersionV1      RootVersion = 1
   191  	CurrentRootVersion RootVersion = RootVersionV1
   192  )
   193  
   194  type RootMetadata struct {
   195  	_struct          struct{} `codec:",toarray"` //nolint
   196  	RootVersion      RootVersion
   197  	EncodingType     EncodingType
   198  	Seqno            Seqno
   199  	BareRootHash     Hash
   200  	SkipPointersHash Hash
   201  
   202  	//  AddOnsHash is the (currently empty) hash of a (not yet defined) data
   203  	//  structure which will contain a map[string]Hash (or even
   204  	//  map[string]interface{}) which can contain arbitrary values. This AddOn
   205  	//  struct is not used in verifying proofs, and new elements can be added to
   206  	//  this map without bumping the RootVersion. Clients are expected to ignore
   207  	//  fields in this map which they do not understand.
   208  	AddOnsHash Hash
   209  }
   210  
   211  func (t *Tree) makeNextRootMetadata(ctx logger.ContextInterface, tr Transaction, curr *RootMetadata, newRootHash Hash, addOnsHash Hash) (RootMetadata, error) {
   212  	root := RootMetadata{
   213  		RootVersion:  t.newRootVersion,
   214  		EncodingType: t.cfg.Encoder.GetEncodingType(),
   215  		BareRootHash: newRootHash,
   216  		AddOnsHash:   addOnsHash,
   217  	}
   218  
   219  	// If there is no previous root, we do not need to include any skips, so
   220  	// return early.
   221  	if curr == nil || curr.Seqno == 0 {
   222  		root.Seqno = 1
   223  		return root, nil
   224  	}
   225  
   226  	newSeqno := curr.Seqno + 1
   227  	skipSeqnos := SkipPointersForSeqno(newSeqno)
   228  
   229  	skips, err := t.eng.LookupRootHashes(ctx, tr, skipSeqnos)
   230  	if err != nil {
   231  		return RootMetadata{}, fmt.Errorf("makeNextRootMetadata: error retrieving previous hashes %+v: %v", skipSeqnos, err)
   232  	}
   233  
   234  	_, skipsHash, err := t.cfg.Encoder.EncodeAndHashGeneric(skips)
   235  	if err != nil {
   236  		return RootMetadata{}, fmt.Errorf("makeNextRootMetadata: error encoding %+v, err: %v", skips, err)
   237  	}
   238  
   239  	root.Seqno = curr.Seqno + 1
   240  	root.SkipPointersHash = skipsHash
   241  
   242  	return root, nil
   243  }
   244  
   245  func (t *Tree) GenerateAndStoreMasterSecret(
   246  	ctx logger.ContextInterface, tr Transaction, s Seqno) (ms MasterSecret, err error) {
   247  	ms, err = t.cfg.Encoder.GenerateMasterSecret(s)
   248  	if err != nil {
   249  		return nil, err
   250  	}
   251  	err = t.eng.(StorageEngineWithBlinding).StoreMasterSecret(ctx, tr, s, ms)
   252  	if err != nil {
   253  		return nil, err
   254  	}
   255  	return ms, nil
   256  }
   257  
   258  func (t *Tree) encodeKVPairs(sortedKVPairs []KeyValuePair) (kevPairs []KeyEncodedValuePair, err error) {
   259  	kevPairs = make([]KeyEncodedValuePair, len(sortedKVPairs))
   260  	for i, kvp := range sortedKVPairs {
   261  		v, err := t.cfg.Encoder.Encode(kvp.Value)
   262  		if err != nil {
   263  			return nil, err
   264  		}
   265  		kevPairs[i].Key = kvp.Key
   266  		kevPairs[i].Value = EncodedValue(v)
   267  	}
   268  	return kevPairs, nil
   269  }
   270  
   271  // Build builds a new tree version, taking a batch input. The
   272  // sortedKeyValuePairs must be sorted (lexicographically) by Key.
   273  //
   274  // NOTE: The input to this function should contain at least all the keys which
   275  // were inserted in previous versions of the tree, and each key should only
   276  // appear once, otherwise this procedure will put the tree into an inconsistent
   277  // state. This function does not check the condition is true for efficiency
   278  // reasons.
   279  func (t *Tree) Build(
   280  	ctx logger.ContextInterface, tr Transaction, sortedKVPairs []KeyValuePair, addOnsHash Hash) (s Seqno, rootHash Hash, err error) {
   281  	t.Lock()
   282  	defer t.Unlock()
   283  
   284  	latestSeqNo, rootMetadata, err := t.eng.LookupLatestRoot(ctx, tr)
   285  	switch err.(type) {
   286  	case nil:
   287  	case NoLatestRootFoundError:
   288  		ctx.Debug("No root found. Starting a new merkle tree.")
   289  		latestSeqNo = 0
   290  		rootMetadata = RootMetadata{}
   291  	default:
   292  		return 0, nil, err
   293  	}
   294  
   295  	newSeqno := latestSeqNo + 1
   296  
   297  	sortedKEVPairs, err := t.encodeKVPairs(sortedKVPairs)
   298  	if err != nil {
   299  		return 0, nil, err
   300  	}
   301  
   302  	if len(sortedKEVPairs) > 0 {
   303  		if err = t.eng.StoreKEVPairs(ctx, tr, newSeqno, sortedKEVPairs); err != nil {
   304  			return 0, nil, err
   305  		}
   306  	}
   307  
   308  	var ms MasterSecret
   309  	if t.cfg.UseBlindedValueHashes {
   310  		ms, err = t.GenerateAndStoreMasterSecret(ctx, tr, newSeqno)
   311  		if err != nil {
   312  			return 0, nil, err
   313  		}
   314  	} else {
   315  		ms = nil
   316  	}
   317  
   318  	var newBareRootHash Hash
   319  	if newBareRootHash, err = t.hashTreeRecursive(ctx, tr, newSeqno, ms,
   320  		t.cfg.GetRootPosition(), sortedKEVPairs); err != nil {
   321  		return 0, nil, err
   322  	}
   323  
   324  	newRootMetadata, err := t.makeNextRootMetadata(ctx, tr, &rootMetadata, newBareRootHash, addOnsHash)
   325  	if err != nil {
   326  		return 0, nil, err
   327  	}
   328  
   329  	_, newRootHash, err := t.cfg.Encoder.EncodeAndHashGeneric(newRootMetadata)
   330  	if err != nil {
   331  		return 0, nil, err
   332  	}
   333  
   334  	if err = t.eng.StoreRootMetadata(ctx, tr, newRootMetadata, newRootHash); err != nil {
   335  		return 0, nil, err
   336  	}
   337  
   338  	_, hash, err := t.cfg.Encoder.EncodeAndHashGeneric(newRootMetadata)
   339  
   340  	return newSeqno, hash, err
   341  }
   342  
   343  func (t *Tree) hashTreeRecursive(ctx logger.ContextInterface, tr Transaction, s Seqno, ms MasterSecret,
   344  	p *Position, sortedKEVPairs []KeyEncodedValuePair) (ret Hash, err error) {
   345  	select {
   346  	case <-ctx.Ctx().Done():
   347  		return nil, ctx.Ctx().Err()
   348  	default:
   349  	}
   350  
   351  	if len(sortedKEVPairs) <= t.cfg.MaxValuesPerLeaf {
   352  		err = t.makeAndStoreLeaf(ctx, tr, s, ms, p, sortedKEVPairs, &ret)
   353  		return ret, err
   354  	}
   355  
   356  	node := Node{INodes: make([]Hash, t.cfg.ChildrenPerNode)}
   357  
   358  	pairsNotYetSelected := sortedKEVPairs
   359  	var nextChild *Position
   360  	for i, child := ChildIndex(0), t.cfg.GetChild(p, ChildIndex(0)); i < ChildIndex(t.cfg.ChildrenPerNode); i++ {
   361  		var end int
   362  		if i+1 < ChildIndex(t.cfg.ChildrenPerNode) {
   363  			nextChild = t.cfg.GetChild(p, i+1)
   364  			maxKey := t.cfg.getMinKey(nextChild)
   365  
   366  			end = sort.Search(len(pairsNotYetSelected), func(n int) bool {
   367  				return pairsNotYetSelected[n].Key.Cmp(maxKey) >= 0
   368  			})
   369  		} else {
   370  			end = len(pairsNotYetSelected)
   371  		}
   372  
   373  		if end > 0 {
   374  			pairsSelected := pairsNotYetSelected[0:end]
   375  			pairsNotYetSelected = pairsNotYetSelected[end:]
   376  			node.INodes[i], err = t.hashTreeRecursive(ctx, tr, s, ms, child, pairsSelected)
   377  			if err != nil {
   378  				return nil, err
   379  			}
   380  		}
   381  		child = nextChild
   382  	}
   383  	if err = t.cfg.Encoder.HashGeneric(node, &ret); err != nil {
   384  		return nil, err
   385  	}
   386  	err = t.eng.StoreNode(ctx, tr, s, p, ret)
   387  	return ret, err
   388  }
   389  
   390  // makeKeyHashPairsFromKeyValuePairs preserves ordering
   391  func (t *Tree) makeKeyHashPairsFromKeyValuePairs(ms MasterSecret, unhashed []KeyEncodedValuePair, node *Node) (err error) {
   392  	if cap(node.LeafHashes) < len(unhashed) {
   393  		node.LeafHashes = make([]KeyHashPair, len(unhashed))
   394  	}
   395  	node.LeafHashes = node.LeafHashes[:len(unhashed)]
   396  
   397  	for i, kevp := range unhashed {
   398  		t.cfg.Encoder.ComputeKeySpecificSecretTo(ms, kevp.Key, &t.bufKss)
   399  		err = t.cfg.Encoder.HashKeyEncodedValuePairWithKeySpecificSecretTo(kevp, t.bufKss, &node.LeafHashes[i].Hash)
   400  		if err != nil {
   401  			return err
   402  		}
   403  		node.LeafHashes[i].Key = kevp.Key
   404  	}
   405  	return nil
   406  }
   407  
   408  func (t *Tree) makeAndStoreLeaf(ctx logger.ContextInterface, tr Transaction, s Seqno, ms MasterSecret, p *Position, sortedKEVPairs []KeyEncodedValuePair, ret *Hash) (err error) {
   409  
   410  	err = t.makeKeyHashPairsFromKeyValuePairs(ms, sortedKEVPairs, &t.bufLeaf)
   411  	if err != nil {
   412  		return err
   413  	}
   414  
   415  	if err = t.cfg.Encoder.HashGeneric(t.bufLeaf, ret); err != nil {
   416  		return err
   417  	}
   418  	if err = t.eng.StoreNode(ctx, tr, s, p, *ret); err != nil {
   419  		return err
   420  	}
   421  	return nil
   422  }
   423  
   424  // Retrieves a KeyValuePair from the tree. Note that if the root at Seqno s was
   425  // not committed yet, there might be no proof for this pair yet (hence it is
   426  // unsafe).
   427  func (t *Tree) GetKeyValuePairUnsafe(ctx logger.ContextInterface, tr Transaction, s Seqno, k Key) (kvp KeyValuePair, err error) {
   428  	if s == 0 {
   429  		return KeyValuePair{}, NewInvalidSeqnoError(0, fmt.Errorf("No keys stored at Seqno 0"))
   430  	}
   431  	if len(k) != t.cfg.KeysByteLength {
   432  		return KeyValuePair{}, NewInvalidKeyError()
   433  	}
   434  	val, _, err := t.eng.LookupKEVPair(ctx, tr, s, k)
   435  	if err != nil {
   436  		return KeyValuePair{}, err
   437  	}
   438  	valContainer := t.cfg.ConstructValueContainer()
   439  	err = t.cfg.Encoder.Decode(&valContainer, val)
   440  	if err != nil {
   441  		return KeyValuePair{}, err
   442  	}
   443  	return KeyValuePair{Key: k, Value: valContainer}, nil
   444  }
   445  
   446  // Retrieves a KeyValuePair from the tree. Note that if the root at Seqno s was
   447  // not committed yet, an InvalidSeqnoError is returned.
   448  func (t *Tree) GetKeyValuePair(ctx logger.ContextInterface, tr Transaction, s Seqno, k Key) (KeyValuePair, error) {
   449  	// Checking the Seqno was committed.
   450  	_, err := t.eng.LookupRoot(ctx, tr, s)
   451  	if err != nil {
   452  		return KeyValuePair{}, err
   453  	}
   454  
   455  	return t.GetKeyValuePairUnsafe(ctx, tr, s, k)
   456  }
   457  
   458  // A MerkleInclusionProof proves that a specific key value pair is stored in a
   459  // merkle tree, given the RootMetadata hash of such tree. It can also be used to
   460  // prove that a specific key is not part of the tree (we call this an exclusion
   461  // or absence proof)
   462  type MerkleInclusionProof struct {
   463  	_struct           struct{}          `codec:",toarray"` //nolint
   464  	KeySpecificSecret KeySpecificSecret `codec:"k"`
   465  	// When this struct is used as an exclusion proof, OtherPairsInLeaf is set
   466  	// to nil if the proof ends at an internal node, and set to a slice of
   467  	// length 0 or more if the proof ends at a (possibly empty) leaf node. In
   468  	// particular, a tree with no keys is encoded with the root being the only
   469  	// (empty leaf) node.
   470  	OtherPairsInLeaf []KeyHashPair `codec:"l"`
   471  	// SiblingHashesOnPath are ordered by level from the farthest to the closest
   472  	// to the root, and lexicographically within each level.
   473  	SiblingHashesOnPath []Hash       `codec:"s"`
   474  	RootMetadataNoHash  RootMetadata `codec:"e"`
   475  }
   476  
   477  // A MerkleExtensionProof proves, given the RootMetadata hashes of two merkle
   478  // trees and their respective Seqno values, that: - the two merkle trees have
   479  // the expected Seqno values, - the most recent merkle tree "points back" to the
   480  // least recent one through a chain of SkipPointers that refer to merkle trees
   481  // at intermediate Seqnos.
   482  type MerkleExtensionProof struct {
   483  	_struct              struct{}       `codec:",toarray"` //nolint
   484  	RootHashes           []Hash         `codec:"h"`
   485  	PreviousRootsNoSkips []RootMetadata `codec:"k"`
   486  }
   487  
   488  // An MerkleInclusionExtensionProof combines a MerkleInclusionProof and a
   489  // MerkleExtensionProof. The redundant fields are deleted so that sending a
   490  // combined proof is more efficient than sending both of them individually.
   491  type MerkleInclusionExtensionProof struct {
   492  	_struct              struct{} `codec:",toarray"` //nolint
   493  	MerkleInclusionProof MerkleInclusionProof
   494  	MerkleExtensionProof MerkleExtensionProof
   495  }
   496  
   497  // This type orders positionHashPairs by position, more specificelly first by
   498  // level descending (nodes with higher level first) and then within each level
   499  // in ascending order. This is the order required by the merkle proof verifier
   500  // to easily reconstruct a path.
   501  type PosHashPairsInMerkleProofOrder []PositionHashPair
   502  
   503  func (p PosHashPairsInMerkleProofOrder) Len() int {
   504  	return len(p)
   505  }
   506  
   507  func (p PosHashPairsInMerkleProofOrder) Less(i, j int) bool {
   508  	return p[i].Position.CmpInMerkleProofOrder(&(p[j].Position)) < 0
   509  }
   510  
   511  func (p PosHashPairsInMerkleProofOrder) Swap(i, j int) {
   512  	p[i], p[j] = p[j], p[i]
   513  }
   514  
   515  var _ sort.Interface = PosHashPairsInMerkleProofOrder{}
   516  
   517  // If the key is not in the tree at the root with the specified hash, this function returns a nil value, a proof
   518  // which certifies that and no error.
   519  func (t *Tree) GetEncodedValueWithInclusionOrExclusionProofFromRootHash(ctx logger.ContextInterface, tr Transaction, rootHash Hash, k Key) (val EncodedValue, proof MerkleInclusionProof, err error) {
   520  	// Lookup the appropriate root.
   521  	rootMetadata, err := t.eng.LookupRootFromHash(ctx, tr, rootHash)
   522  	if err != nil {
   523  		return nil, MerkleInclusionProof{}, err
   524  	}
   525  	return t.getEncodedValueWithInclusionProofOrExclusionProof(ctx, tr, rootMetadata, k)
   526  }
   527  
   528  // If the key is not in the tree at seqno s, this function returns a KeyNotFoundError and no absence proof.
   529  func (t *Tree) GetEncodedValueWithInclusionProof(ctx logger.ContextInterface, tr Transaction, s Seqno, k Key) (val EncodedValue, proof MerkleInclusionProof, err error) {
   530  	// Lookup the appropriate root.
   531  	rootMetadata, err := t.eng.LookupRoot(ctx, tr, s)
   532  	if err != nil {
   533  		return nil, MerkleInclusionProof{}, err
   534  	}
   535  	val, proof, err = t.getEncodedValueWithInclusionProofOrExclusionProof(ctx, tr, rootMetadata, k)
   536  	if err != nil {
   537  		return nil, MerkleInclusionProof{}, err
   538  	}
   539  	if val == nil {
   540  		return nil, MerkleInclusionProof{}, NewKeyNotFoundError()
   541  	}
   542  	return val, proof, nil
   543  }
   544  
   545  // if the key is not in the tree, this function returns a nil value, a proof
   546  // which certifies that and no error.
   547  func (t *Tree) getEncodedValueWithInclusionProofOrExclusionProof(ctx logger.ContextInterface, tr Transaction, rootMetadata RootMetadata, k Key) (val EncodedValue, proof MerkleInclusionProof, err error) {
   548  	if len(k) != t.cfg.KeysByteLength {
   549  		return nil, MerkleInclusionProof{}, fmt.Errorf("The supplied key has the wrong length: exp %v, got %v", t.cfg.KeysByteLength, len(k))
   550  	}
   551  
   552  	s := rootMetadata.Seqno
   553  	proof.RootMetadataNoHash = rootMetadata
   554  	// clear up hash to make the proof smaller.
   555  	proof.RootMetadataNoHash.BareRootHash = nil
   556  
   557  	var siblingPosHashPairs []PositionHashPair
   558  	needMore := true
   559  	for curr := 1; needMore && curr <= t.cfg.MaxDepth; curr += t.step + 1 {
   560  		// The first element is the position at level curr+step on the path from
   561  		// the root to k (on a complete tree). The next ones are all the
   562  		// necessary siblings at levels from curr+step to curr (both included)
   563  		// on such path.
   564  		deepestAndCurrSiblingPositions := t.cfg.getDeepestPositionAtLevelAndSiblingsOnPathToKey(k, curr+t.step, curr)
   565  		deepestAndCurrSiblings, err := t.eng.LookupNodes(ctx, tr, s, deepestAndCurrSiblingPositions)
   566  		if err != nil {
   567  			return nil, MerkleInclusionProof{}, err
   568  		}
   569  
   570  		sort.Sort(PosHashPairsInMerkleProofOrder(deepestAndCurrSiblings))
   571  
   572  		var currSiblings []PositionHashPair
   573  		// if we found a PositionHashPair corrisponding to the first element in
   574  		// deepestAndCurrSiblingPositions, it means the path might be deeper and we
   575  		// need to fetch more siblings.
   576  		candidateDeepest := len(deepestAndCurrSiblings)
   577  		if len(deepestAndCurrSiblings) > 0 {
   578  			candidateDeepest = sort.Search(len(deepestAndCurrSiblings), func(i int) bool {
   579  				return deepestAndCurrSiblings[i].Position.CmpInMerkleProofOrder(&deepestAndCurrSiblingPositions[0]) >= 0
   580  			})
   581  		}
   582  		if candidateDeepest < len(deepestAndCurrSiblings) && deepestAndCurrSiblings[candidateDeepest].Position.Equals(&deepestAndCurrSiblingPositions[0]) {
   583  			currSiblings = deepestAndCurrSiblings[:candidateDeepest]
   584  			currSiblings = append(currSiblings, deepestAndCurrSiblings[candidateDeepest+1:]...)
   585  		} else {
   586  			currSiblings = deepestAndCurrSiblings
   587  			needMore = false
   588  		}
   589  		siblingPosHashPairs = append(currSiblings, siblingPosHashPairs...)
   590  	}
   591  
   592  	var leafLevel int
   593  	if len(siblingPosHashPairs) == 0 {
   594  		// If there are no siblings, the key must be stored on the root
   595  		leafLevel = 0
   596  	} else {
   597  		// The level of the first sibling equals the level of the leaf node for the
   598  		// key we are producing the proof for.
   599  		leafLevel = t.cfg.getLevel(&(siblingPosHashPairs[0].Position))
   600  	}
   601  
   602  	deepestPosition, err := t.cfg.getDeepestPositionForKey(k)
   603  	if err != nil {
   604  		return nil, MerkleInclusionProof{}, err
   605  	}
   606  	leafPos := t.cfg.getParentAtLevel(deepestPosition, uint(leafLevel))
   607  
   608  	proof.SiblingHashesOnPath = make([]Hash, leafLevel*(t.cfg.ChildrenPerNode-1))
   609  	leafChildIndexes := t.cfg.positionToChildIndexPath(leafPos)
   610  	// Flatten the siblingPosHashPairs Hashes into a []Hash.
   611  	for _, pos := range siblingPosHashPairs {
   612  		if t.cfg.getDeepestChildIndex(&pos.Position) < leafChildIndexes[leafLevel-t.cfg.getLevel(&pos.Position)] {
   613  			proof.SiblingHashesOnPath[(leafLevel-t.cfg.getLevel(&pos.Position))*(t.cfg.ChildrenPerNode-1)+int(t.cfg.getDeepestChildIndex(&pos.Position))] = pos.Hash
   614  		} else {
   615  			proof.SiblingHashesOnPath[(leafLevel-t.cfg.getLevel(&pos.Position))*(t.cfg.ChildrenPerNode-1)+int(t.cfg.getDeepestChildIndex(&pos.Position))-1] = pos.Hash
   616  		}
   617  	}
   618  
   619  	var kevps []KeyEncodedValuePair
   620  
   621  	// We have two cases: either the node at leafPos is actually a leaf
   622  	// (which might or not contain the key which we are trying to look up),
   623  	// or such node does not exists at all (which happens only if the key we
   624  	// are looking up is not part of the tree at that seqno).
   625  	_, err = t.eng.LookupNode(ctx, tr, s, leafPos)
   626  	if err != nil {
   627  		// NodeNotFoundError is ignored as the inclusion proof we
   628  		// produce will prove that the key is not in the tree.
   629  		if _, nodeNotFound := err.(NodeNotFoundError); !nodeNotFound {
   630  			return nil, MerkleInclusionProof{}, err
   631  		}
   632  	} else {
   633  		if t.cfg.MaxValuesPerLeaf == 1 {
   634  			// Try to avoid LookupKEVPairsUnderPosition if possible as it is a range
   635  			// query and thus more expensive.
   636  			kevp, _, err := t.eng.LookupKEVPair(ctx, tr, s, k)
   637  			if err != nil {
   638  				// KeyNotFoundError is ignored as the inclusion proof we
   639  				// produce will prove that the key is not in the tree.
   640  				if _, keyNotFound := err.(KeyNotFoundError); !keyNotFound {
   641  					return nil, MerkleInclusionProof{}, err
   642  				}
   643  			} else {
   644  				kevps = append(kevps, KeyEncodedValuePair{Key: k, Value: kevp})
   645  			}
   646  		}
   647  
   648  		// if len(kevps)>0, then MaxValuesPerLeaf == 1 and we found the key we
   649  		// are looking for, so there is no need to look for other keys under
   650  		// leafPos.
   651  		if len(kevps) == 0 {
   652  			// Lookup hashes of key value pairs stored at the same leaf.
   653  			// These pairs are ordered by key.
   654  			kevps, _, err = t.eng.LookupKEVPairsUnderPosition(ctx, tr, s, leafPos)
   655  			if err != nil {
   656  				// KeyNotFoundError is ignored. This would happen when we are
   657  				// trying to produce an absence proof on an empty tree: there
   658  				// would be a leaf node containing no keys.
   659  				if _, keyNotFound := err.(KeyNotFoundError); !keyNotFound {
   660  					return nil, MerkleInclusionProof{}, err
   661  				}
   662  				kevps = make([]KeyEncodedValuePair, 0)
   663  			}
   664  		}
   665  	}
   666  
   667  	var ms MasterSecret
   668  	if t.cfg.UseBlindedValueHashes && len(kevps) > 0 {
   669  		msMap, err := t.eng.(StorageEngineWithBlinding).LookupMasterSecrets(ctx, tr, []Seqno{s})
   670  		if err != nil {
   671  			return nil, MerkleInclusionProof{}, err
   672  		}
   673  		ms = msMap[s]
   674  	}
   675  
   676  	// OtherPairsInLeaf will have length equal to kevps - 1  in an inclusion
   677  	// proof, and kevps in an absence proof.
   678  	if kevps != nil {
   679  		proof.OtherPairsInLeaf = make([]KeyHashPair, 0, len(kevps))
   680  	}
   681  	for _, kevpi := range kevps {
   682  		if kevpi.Key.Equal(k) {
   683  			val = kevpi.Value
   684  			if t.cfg.UseBlindedValueHashes {
   685  				proof.KeySpecificSecret = t.cfg.Encoder.ComputeKeySpecificSecret(ms, k)
   686  			} else {
   687  				proof.KeySpecificSecret = nil
   688  			}
   689  			continue
   690  		}
   691  
   692  		var hash Hash
   693  		hash, err = t.cfg.Encoder.HashKeyEncodedValuePairWithKeySpecificSecret(kevpi, t.cfg.Encoder.ComputeKeySpecificSecret(ms, kevpi.Key))
   694  		if err != nil {
   695  			return nil, MerkleInclusionProof{}, err
   696  		}
   697  		proof.OtherPairsInLeaf = append(proof.OtherPairsInLeaf, KeyHashPair{Key: kevpi.Key, Hash: hash})
   698  	}
   699  
   700  	return val, proof, nil
   701  }
   702  
   703  func (t *Tree) GetKeyValuePairWithProof(ctx logger.ContextInterface, tr Transaction, s Seqno, k Key) (kvp KeyValuePair, proof MerkleInclusionProof, err error) {
   704  	val, proof, err := t.GetEncodedValueWithInclusionProof(ctx, tr, s, k)
   705  	if err != nil {
   706  		return KeyValuePair{}, MerkleInclusionProof{}, err
   707  	}
   708  
   709  	valContainer := t.cfg.ConstructValueContainer()
   710  	err = t.cfg.Encoder.Decode(&valContainer, val)
   711  	if err != nil {
   712  		return KeyValuePair{}, MerkleInclusionProof{}, err
   713  	}
   714  	kvp = KeyValuePair{Key: k, Value: valContainer}
   715  
   716  	return kvp, proof, nil
   717  }
   718  
   719  func (t *Tree) getExtensionProof(ctx logger.ContextInterface, tr Transaction, fromSeqno, toSeqno Seqno, isPartOfIncExtProof bool) (proof MerkleExtensionProof, err error) {
   720  	// Optimization: no proof is required to show something extends itself.
   721  	if fromSeqno == toSeqno {
   722  		return MerkleExtensionProof{}, nil
   723  	}
   724  
   725  	seqnos, err := ComputeRootHashSeqnosNeededInExtensionProof(fromSeqno, toSeqno)
   726  	if err != nil {
   727  		return MerkleExtensionProof{}, err
   728  	}
   729  	hashes, err := t.eng.LookupRootHashes(ctx, tr, seqnos)
   730  	if err != nil {
   731  		return MerkleExtensionProof{}, err
   732  	}
   733  
   734  	seqnos, err = ComputeRootMetadataSeqnosNeededInExtensionProof(fromSeqno, toSeqno, isPartOfIncExtProof)
   735  	if err != nil {
   736  		return MerkleExtensionProof{}, err
   737  	}
   738  	roots, err := t.eng.LookupRoots(ctx, tr, seqnos)
   739  	if err != nil {
   740  		return MerkleExtensionProof{}, err
   741  	}
   742  
   743  	proof.RootHashes = hashes
   744  	proof.PreviousRootsNoSkips = roots
   745  
   746  	return proof, nil
   747  }
   748  
   749  func (t *Tree) GetExtensionProof(ctx logger.ContextInterface, tr Transaction, fromSeqno, toSeqno Seqno) (proof MerkleExtensionProof, err error) {
   750  	return t.getExtensionProof(ctx, tr, fromSeqno, toSeqno, false)
   751  }
   752  
   753  func (t *Tree) GetEncodedValueWithInclusionExtensionProof(ctx logger.ContextInterface, tr Transaction, haveSeqno, wantSeqno Seqno, k Key) (val EncodedValue, proof MerkleInclusionExtensionProof, err error) {
   754  	val, incProof, err := t.GetEncodedValueWithInclusionProof(ctx, tr, wantSeqno, k)
   755  	if err != nil {
   756  		return nil, MerkleInclusionExtensionProof{}, err
   757  	}
   758  	proof.MerkleInclusionProof = incProof
   759  
   760  	if haveSeqno != wantSeqno {
   761  		// clear these fields to save bandwidth, they are redundant when an
   762  		// inclusion proof is paired with an extension proof. Note that if
   763  		// haveSeqno == wantSeqno, we don't do this optimization as the
   764  		// extension proof is skipped.
   765  		proof.MerkleInclusionProof.RootMetadataNoHash.SkipPointersHash = nil
   766  		proof.MerkleInclusionProof.RootMetadataNoHash.Seqno = Seqno(0)
   767  	}
   768  
   769  	extProof, err := t.getExtensionProof(ctx, tr, haveSeqno, wantSeqno, true)
   770  	if err != nil {
   771  		return nil, MerkleInclusionExtensionProof{}, err
   772  	}
   773  
   774  	// clear these fields to save bandwidth
   775  	for i := range extProof.PreviousRootsNoSkips {
   776  		extProof.PreviousRootsNoSkips[i].SkipPointersHash = nil
   777  	}
   778  
   779  	proof.MerkleExtensionProof = extProof
   780  	return val, proof, err
   781  }
   782  
   783  func (t *Tree) GetKeyValuePairWithInclusionExtensionProof(ctx logger.ContextInterface, tr Transaction, haveSeqno, wantSeqno Seqno, k Key) (kvp KeyValuePair, proof MerkleInclusionExtensionProof, err error) {
   784  	val, proof, err := t.GetEncodedValueWithInclusionExtensionProof(ctx, tr, haveSeqno, wantSeqno, k)
   785  	if err != nil {
   786  		return KeyValuePair{}, MerkleInclusionExtensionProof{}, err
   787  	}
   788  
   789  	valContainer := t.cfg.ConstructValueContainer()
   790  	err = t.cfg.Encoder.Decode(&valContainer, val)
   791  	if err != nil {
   792  		return KeyValuePair{}, MerkleInclusionExtensionProof{}, err
   793  	}
   794  	kvp = KeyValuePair{Key: k, Value: valContainer}
   795  
   796  	return kvp, proof, nil
   797  }
   798  
   799  func (t *Tree) ExecTransaction(ctx logger.ContextInterface, txFn func(logger.ContextInterface, Transaction) error) error {
   800  	return t.eng.ExecTransaction(ctx, txFn)
   801  }
   802  
   803  // GetLatestRoot returns the latest RootMetadata which was stored in the
   804  // tree (and its Hash and Seqno). If no such record was stored yet,
   805  // GetLatestRoot returns 0 as a Seqno and a NoLatestRootFound error.
   806  func (t *Tree) GetLatestRoot(ctx logger.ContextInterface, tr Transaction) (s Seqno, root RootMetadata, rootHash Hash, err error) {
   807  	s, root, err = t.eng.LookupLatestRoot(ctx, tr)
   808  	if err != nil || s == 0 {
   809  		return 0, RootMetadata{}, nil, err
   810  	}
   811  	_, rootHash, err = t.cfg.Encoder.EncodeAndHashGeneric(root)
   812  	if err != nil {
   813  		return 0, RootMetadata{}, nil, err
   814  	}
   815  
   816  	return s, root, rootHash, nil
   817  }