Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/google/trillian"
"github.com/google/trillian/client/backoff"
"github.com/google/trillian/merkle"
"github.com/google/trillian/merkle/hashers"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
Expand All @@ -40,7 +41,7 @@ type LogClient struct {
}

// New returns a new LogClient.
func New(logID int64, client trillian.TrillianLogClient, hasher merkle.LogHasher, pubKey crypto.PublicKey) *LogClient {
func New(logID int64, client trillian.TrillianLogClient, hasher hashers.LogHasher, pubKey crypto.PublicKey) *LogClient {
return &LogClient{
LogID: logID,
client: client,
Expand Down
5 changes: 3 additions & 2 deletions client/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@ import (
"github.com/google/trillian"
tcrypto "github.com/google/trillian/crypto"
"github.com/google/trillian/merkle"
"github.com/google/trillian/merkle/hashers"
)

// logVerifier contains state needed to verify output from Trillian Logs.
type logVerifier struct {
hasher merkle.LogHasher
hasher hashers.LogHasher
pubKey crypto.PublicKey
v merkle.LogVerifier
}

// NewLogVerifier returns an object that can verify output from Trillian Logs.
func NewLogVerifier(hasher merkle.LogHasher, pubKey crypto.PublicKey) LogVerifier {
func NewLogVerifier(hasher hashers.LogHasher, pubKey crypto.PublicKey) LogVerifier {
return &logVerifier{
hasher: hasher,
pubKey: pubKey,
Expand Down
5 changes: 3 additions & 2 deletions log/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/google/trillian/crypto"
"github.com/google/trillian/crypto/sigpb"
"github.com/google/trillian/merkle"
"github.com/google/trillian/merkle/hashers"
"github.com/google/trillian/monitoring"
"github.com/google/trillian/quota"
"github.com/google/trillian/storage"
Expand Down Expand Up @@ -78,7 +79,7 @@ func createMetrics(mf monitoring.MetricFactory) {
// There is no strong ordering guarantee but in general entries will be processed
// in order of submission to the log.
type Sequencer struct {
hasher merkle.LogHasher
hasher hashers.LogHasher
timeSource util.TimeSource
logStorage storage.LogStorage
signer *crypto.Signer
Expand All @@ -93,7 +94,7 @@ const maxTreeDepth = 64

// NewSequencer creates a new Sequencer instance for the specified inputs.
func NewSequencer(
hasher merkle.LogHasher,
hasher hashers.LogHasher,
timeSource util.TimeSource,
logStorage storage.LogStorage,
signer *crypto.Signer,
Expand Down
7 changes: 4 additions & 3 deletions merkle/compact_merkle_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"

log "github.com/golang/glog"
"github.com/google/trillian/merkle/hashers"
)

// RootHashMismatchError indicates a unexpected root hash value.
Expand All @@ -36,7 +37,7 @@ func (r RootHashMismatchError) Error() string {
// CompactMerkleTree is a compact Merkle tree representation.
// Uses log(n) nodes to represent the current on-disk tree.
type CompactMerkleTree struct {
hasher LogHasher
hasher hashers.LogHasher
root []byte
// the list of "dangling" left-hand nodes, NOTE: index 0 is the leaf, not the root.
nodes [][]byte
Expand Down Expand Up @@ -66,7 +67,7 @@ type GetNodeFunc func(depth int, index int64) ([]byte, error)
// |f| will be called a number of times with the co-ordinates of internal MerkleTree nodes whose hash values are
// required to initialize the internal state of the CompactMerkleTree. |expectedRoot| is the known-good tree root
// of the tree at |size|, and is used to verify the correct initial state of the CompactMerkleTree after initialisation.
func NewCompactMerkleTreeWithState(hasher LogHasher, size int64, f GetNodeFunc, expectedRoot []byte) (*CompactMerkleTree, error) {
func NewCompactMerkleTreeWithState(hasher hashers.LogHasher, size int64, f GetNodeFunc, expectedRoot []byte) (*CompactMerkleTree, error) {
sizeBits := bitLen(size)

r := CompactMerkleTree{
Expand Down Expand Up @@ -108,7 +109,7 @@ func NewCompactMerkleTreeWithState(hasher LogHasher, size int64, f GetNodeFunc,
}

// NewCompactMerkleTree creates a new CompactMerkleTree with size zero. This always succeeds.
func NewCompactMerkleTree(hasher LogHasher) *CompactMerkleTree {
func NewCompactMerkleTree(hasher hashers.LogHasher) *CompactMerkleTree {
r := CompactMerkleTree{
hasher: hasher,
root: hasher.EmptyRoot(),
Expand Down
53 changes: 52 additions & 1 deletion merkle/tree_hasher.go → merkle/hashers/tree_hasher.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package merkle
package hashers

import (
"fmt"

"github.com/google/trillian"
)

// LogHasher provides the hash functions needed to compute dense merkele trees.
type LogHasher interface {
Expand Down Expand Up @@ -42,3 +48,48 @@ type MapHasher interface {
// TODO(gbelvin): Replace Size() with BitLength().
Size() int
}

var (
logHashers = make(map[trillian.HashStrategy]LogHasher)
mapHashers = make(map[trillian.HashStrategy]MapHasher)
)

// RegisterLogHasher registers a hasher for use.
func RegisterLogHasher(h trillian.HashStrategy, f LogHasher) {
if h == trillian.HashStrategy_UNKNOWN_HASH_STRATEGY {
panic(fmt.Sprintf("RegisterLogHasher(%s) of unknown hasher", h))
}
if logHashers[h] != nil {
panic(fmt.Sprintf("%v already registered as a LogHasher", h))
}
logHashers[h] = f
}

// RegisterMapHasher registers a hasher for use.
func RegisterMapHasher(h trillian.HashStrategy, f MapHasher) {
if h == trillian.HashStrategy_UNKNOWN_HASH_STRATEGY {
panic(fmt.Sprintf("RegisterMapHasher(%s) of unknown hasher", h))
}
if mapHashers[h] != nil {
panic(fmt.Sprintf("%v already registered as a MapHasher", h))
}
mapHashers[h] = f
}

// NewLogHasher returns a LogHasher.
func NewLogHasher(h trillian.HashStrategy) (LogHasher, error) {
f := logHashers[h]
if f != nil {
return f, nil
}
return nil, fmt.Errorf("LogHasher(%s) is an unknown hasher", h)
}

// NewMapHasher returns a MapHasher.
func NewMapHasher(h trillian.HashStrategy) (MapHasher, error) {
f := mapHashers[h]
if f != nil {
return f, nil
}
return nil, fmt.Errorf("MapHasher(%s) is an unknown hasher", h)
}
6 changes: 4 additions & 2 deletions merkle/hstar2.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"fmt"
"math/big"
"sort"

"github.com/google/trillian/merkle/hashers"
)

var (
Expand All @@ -37,11 +39,11 @@ type HStar2LeafHash struct {
// HStar2 is a recursive implementation for calculating the root hash of a sparse
// Merkle tree.
type HStar2 struct {
hasher MapHasher
hasher hashers.MapHasher
}

// NewHStar2 creates a new HStar2 tree calculator based on the passed in MapHasher.
func NewHStar2(hasher MapHasher) HStar2 {
func NewHStar2(hasher hashers.MapHasher) HStar2 {
return HStar2{
hasher: hasher,
}
Expand Down
3 changes: 2 additions & 1 deletion merkle/hstar2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"math/big"
"testing"

"github.com/google/trillian/merkle/hashers"
"github.com/google/trillian/merkle/maphasher"
"github.com/google/trillian/testonly"
)
Expand All @@ -34,7 +35,7 @@ var sparseEmptyRootHashB64 = testonly.MustDecodeBase64("xmifEIEqCYCXbZUz2Dh1KCFm
// passing into a the HStar2 sparse Merkle tree implementation.
// The map keys will be SHA256 hashed before being added to the returned
// structs.
func createHStar2Leaves(hasher MapHasher, values map[string]string) []HStar2LeafHash {
func createHStar2Leaves(hasher hashers.MapHasher, values map[string]string) []HStar2LeafHash {
r := []HStar2LeafHash{}
for k := range values {
khash := sha256.Sum256([]byte(k))
Expand Down
6 changes: 4 additions & 2 deletions merkle/log_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"bytes"
"errors"
"fmt"

"github.com/google/trillian/merkle/hashers"
)

// RootMismatchError occurs when an inclusion proof fails.
Expand All @@ -32,11 +34,11 @@ func (e RootMismatchError) Error() string {

// LogVerifier verifies inclusion and consistency proofs for append only logs.
type LogVerifier struct {
hasher LogHasher
hasher hashers.LogHasher
}

// NewLogVerifier returns a new LogVerifier for a tree.
func NewLogVerifier(hasher LogHasher) LogVerifier {
func NewLogVerifier(hasher hashers.LogHasher) LogVerifier {
return LogVerifier{
hasher: hasher,
}
Expand Down
3 changes: 2 additions & 1 deletion merkle/map_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"bytes"
"fmt"

"github.com/google/trillian/merkle/hashers"
"github.com/google/trillian/storage"
)

Expand All @@ -28,7 +29,7 @@ import (
// append-only logs, but adds support for nil/"default" proof nodes.
//
// Returns nil on a successful verification, and an error otherwise.
func VerifyMapInclusionProof(index, leafHash, expectedRoot []byte, proof [][]byte, h MapHasher) error {
func VerifyMapInclusionProof(index, leafHash, expectedRoot []byte, proof [][]byte, h hashers.MapHasher) error {
hBits := h.Size() * 8

if got, want := len(proof), hBits; got != want {
Expand Down
9 changes: 8 additions & 1 deletion merkle/maphasher/maphasher.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,15 @@ package maphasher
import (
"crypto"
"fmt"

"github.com/google/trillian"
"github.com/google/trillian/merkle/hashers"
)

func init() {
hashers.RegisterMapHasher(trillian.HashStrategy_TEST_MAP_HASHER, Default)
}

// Domain separation prefixes
const (
leafHashPrefix = 0
Expand All @@ -38,7 +45,7 @@ type MapHasher struct {
}

// New creates a new merkel.MapHasher using the passed in hash function.
func New(h crypto.Hash) *MapHasher {
func New(h crypto.Hash) hashers.MapHasher {
m := &MapHasher{Hash: h}
m.initNullHashes()
return m
Expand Down
4 changes: 2 additions & 2 deletions merkle/maphasher/maphasher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"encoding/base64"
"testing"

"github.com/google/trillian/merkle"
"github.com/google/trillian/merkle/hashers"
)

const (
Expand Down Expand Up @@ -58,7 +58,7 @@ func TestHStar2Equivalence(t *testing.T) {

// Old hstar2 empty cache algorithm.
type hstar struct {
hasher merkle.MapHasher
hasher hashers.MapHasher
hStarEmptyCache [][]byte
}

Expand Down
6 changes: 4 additions & 2 deletions merkle/memory_merkle_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ package merkle
import (
"errors"
"fmt"

"github.com/google/trillian/merkle/hashers"
)

// TreeEntry is used for nodes in the tree for better readability. Just holds a hash but could be extended
Expand Down Expand Up @@ -99,7 +101,7 @@ type InMemoryMerkleTree struct {
tree [][]TreeEntry
leavesProcessed int64
levelCount int64
hasher LogHasher
hasher hashers.LogHasher
}

// isPowerOfTwoPlusOne tests whether a number is (2^x)-1 for some x. From MerkleTreeMath in C++
Expand All @@ -125,7 +127,7 @@ func sibling(leaf int64) int64 {
}

// NewInMemoryMerkleTree creates a new empty Merkle Tree using the specified Hasher
func NewInMemoryMerkleTree(hasher LogHasher) *InMemoryMerkleTree {
func NewInMemoryMerkleTree(hasher hashers.LogHasher) *InMemoryMerkleTree {
mt := InMemoryMerkleTree{}

mt.hasher = hasher
Expand Down
7 changes: 4 additions & 3 deletions merkle/memory_merkle_tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"math/rand"
"testing"

"github.com/google/trillian/merkle/hashers"
"github.com/google/trillian/testonly"
)

Expand Down Expand Up @@ -167,7 +168,7 @@ func downToPowerOfTwo(i int64) int64 {
}

// Reference implementation of Merkle hash, for cross-checking.
func referenceMerkleTreeHash(inputs [][]byte, treehasher LogHasher) []byte {
func referenceMerkleTreeHash(inputs [][]byte, treehasher hashers.LogHasher) []byte {
if len(inputs) == 0 {
return treehasher.EmptyRoot()
}
Expand All @@ -186,7 +187,7 @@ func referenceMerkleTreeHash(inputs [][]byte, treehasher LogHasher) []byte {

// Reference implementation of Merkle paths. Path from leaf to root,
// excluding the leaf and root themselves.
func referenceMerklePath(inputs [][]byte, leaf int64, treehasher LogHasher) [][]byte {
func referenceMerklePath(inputs [][]byte, leaf int64, treehasher hashers.LogHasher) [][]byte {
var path [][]byte

inputLen := int64(len(inputs))
Expand Down Expand Up @@ -218,7 +219,7 @@ func referenceMerklePath(inputs [][]byte, leaf int64, treehasher LogHasher) [][]
// Reference implementation of snapshot consistency.
// Call with haveRoot1 = true.
func referenceSnapshotConsistency(inputs [][]byte, snapshot2 int64,
snapshot1 int64, treehasher LogHasher, haveRoot1 bool) [][]byte {
snapshot1 int64, treehasher hashers.LogHasher, haveRoot1 bool) [][]byte {

var proof [][]byte

Expand Down
10 changes: 5 additions & 5 deletions merkle/objhasher/objhasher.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,26 @@ package objhasher

import (
"github.com/benlaurie/objecthash/go/objecthash"
"github.com/google/trillian/merkle"
"github.com/google/trillian/merkle/hashers"
)

type objmaphasher struct {
merkle.MapHasher
hashers.MapHasher
}

type objloghasher struct {
merkle.LogHasher
hashers.LogHasher
}

// NewMapHasher returns a new ObjectHasher based on the passed in MapHasher
func NewMapHasher(baseHasher merkle.MapHasher) merkle.MapHasher {
func NewMapHasher(baseHasher hashers.MapHasher) hashers.MapHasher {
return &objmaphasher{
MapHasher: baseHasher,
}
}

// NewLogHasher returns a new ObjectHasher based on the passed in MapHasher
func NewLogHasher(baseHasher merkle.LogHasher) merkle.LogHasher {
func NewLogHasher(baseHasher hashers.LogHasher) hashers.LogHasher {
return &objloghasher{
LogHasher: baseHasher,
}
Expand Down
7 changes: 7 additions & 0 deletions merkle/rfc6962/rfc6962.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,15 @@ package rfc6962
import (
"crypto"
_ "crypto/sha256" // SHA256 is the default algorithm.

"github.com/google/trillian"
"github.com/google/trillian/merkle/hashers"
)

func init() {
hashers.RegisterLogHasher(trillian.HashStrategy_RFC6962_SHA256, New(crypto.SHA256))
}

// Domain separation prefixes
const (
RFC6962LeafHashPrefix = 0
Expand Down
Loading