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  }