From 1224f565a27155c3abef3ecf4d86cf6f472b1374 Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Sat, 21 May 2022 20:32:17 +0200 Subject: pick-up merkle package TODO(ln5): upgrade sigsum-go dependency in go.mod file --- cmd/sigsum_log_go/main.go | 7 ++++--- pkg/db/trillian.go | 15 +++++++------- pkg/db/trillian_test.go | 47 ++++++++++++++++++++++---------------------- pkg/instance/handler_test.go | 43 ++++++++++++++++++++-------------------- pkg/instance/instance.go | 5 +++-- pkg/state/single.go | 13 ++++++------ pkg/state/single_test.go | 13 ++++++------ pkg/state/state_manager.go | 3 ++- 8 files changed, 77 insertions(+), 69 deletions(-) diff --git a/cmd/sigsum_log_go/main.go b/cmd/sigsum_log_go/main.go index b64da1a..37404da 100644 --- a/cmd/sigsum_log_go/main.go +++ b/cmd/sigsum_log_go/main.go @@ -22,6 +22,7 @@ import ( "google.golang.org/grpc" "git.sigsum.org/sigsum-go/pkg/log" + "git.sigsum.org/sigsum-go/pkg/merkle" "git.sigsum.org/sigsum-go/pkg/types" "git.sigsum.org/sigsum-go/pkg/dns" "git.sigsum.org/log-go/pkg/db" @@ -191,8 +192,8 @@ func newLogIdentity(keyFile string) (crypto.Signer, string, error) { } // newWitnessMap creates a new map of trusted witnesses -func newWitnessMap(witnesses string) (map[types.Hash]types.PublicKey, error) { - w := make(map[types.Hash]types.PublicKey) +func newWitnessMap(witnesses string) (map[merkle.Hash]types.PublicKey, error) { + w := make(map[merkle.Hash]types.PublicKey) if len(witnesses) > 0 { for _, witness := range strings.Split(witnesses, ",") { b, err := hex.DecodeString(witness) @@ -204,7 +205,7 @@ func newWitnessMap(witnesses string) (map[types.Hash]types.PublicKey, error) { if n := copy(vk[:], b); n != types.PublicKeySize { return nil, fmt.Errorf("Invalid public key size: %v", n) } - w[*types.HashFn(vk[:])] = vk + w[*merkle.HashFn(vk[:])] = vk } } return w, nil diff --git a/pkg/db/trillian.go b/pkg/db/trillian.go index 3147c8d..ccb5334 100644 --- a/pkg/db/trillian.go +++ b/pkg/db/trillian.go @@ -7,6 +7,7 @@ import ( "git.sigsum.org/sigsum-go/pkg/log" "git.sigsum.org/sigsum-go/pkg/requests" + "git.sigsum.org/sigsum-go/pkg/merkle" "git.sigsum.org/sigsum-go/pkg/types" "github.com/google/trillian" trillianTypes "github.com/google/trillian/types" @@ -26,14 +27,14 @@ func (c *TrillianClient) AddLeaf(ctx context.Context, req *requests.Leaf) error leaf := types.Leaf{ Statement: types.Statement{ ShardHint: req.ShardHint, - Checksum: *types.HashFn(req.Message[:]), + Checksum: *merkle.HashFn(req.Message[:]), }, Signature: req.Signature, - KeyHash: *types.HashFn(req.PublicKey[:]), + KeyHash: *merkle.HashFn(req.PublicKey[:]), } serialized := leaf.ToBinary() - log.Debug("queueing leaf request: %x", types.LeafHash(serialized)) + log.Debug("queueing leaf request: %x", merkle.HashLeafNode(serialized)) rsp, err := c.GRPC.QueueLeaf(ctx, &trillian.QueueLeafRequest{ LogId: c.TreeID, Leaf: &trillian.LogLeaf{ @@ -75,7 +76,7 @@ func (c *TrillianClient) GetTreeHead(ctx context.Context) (*types.TreeHead, erro if err := r.UnmarshalBinary(rsp.SignedLogRoot.LogRoot); err != nil { return nil, fmt.Errorf("no log root: unmarshal failed: %v", err) } - if len(r.RootHash) != types.HashSize { + if len(r.RootHash) != merkle.HashSize { return nil, fmt.Errorf("unexpected hash length: %d", len(r.RootHash)) } return treeHeadFromLogRoot(&r), nil @@ -181,10 +182,10 @@ func treeHeadFromLogRoot(lr *trillianTypes.LogRootV1) *types.TreeHead { return &th } -func nodePathFromHashes(hashes [][]byte) ([]types.Hash, error) { - path := make([]types.Hash, len(hashes)) +func nodePathFromHashes(hashes [][]byte) ([]merkle.Hash, error) { + path := make([]merkle.Hash, len(hashes)) for i := 0; i < len(hashes); i++ { - if len(hashes[i]) != types.HashSize { + if len(hashes[i]) != merkle.HashSize { return nil, fmt.Errorf("unexpected hash length: %v", len(hashes[i])) } diff --git a/pkg/db/trillian_test.go b/pkg/db/trillian_test.go index 2b19096..cff23da 100644 --- a/pkg/db/trillian_test.go +++ b/pkg/db/trillian_test.go @@ -9,6 +9,7 @@ import ( "time" "git.sigsum.org/log-go/pkg/db/mocks" + "git.sigsum.org/sigsum-go/pkg/merkle" "git.sigsum.org/sigsum-go/pkg/requests" "git.sigsum.org/sigsum-go/pkg/types" "github.com/golang/mock/gomock" @@ -21,7 +22,7 @@ import ( func TestAddLeaf(t *testing.T) { req := &requests.Leaf{ ShardHint: 0, - Message: types.Hash{}, + Message: merkle.Hash{}, Signature: types.Signature{}, PublicKey: types.PublicKey{}, DomainHint: "example.com", @@ -96,7 +97,7 @@ func TestGetTreeHead(t *testing.T) { // valid root root := &ttypes.LogRootV1{ TreeSize: 0, - RootHash: make([]byte, types.HashSize), + RootHash: make([]byte, merkle.HashSize), TimestampNanos: 1622585623133599429, } buf, err := root.MarshalBinary() @@ -104,7 +105,7 @@ func TestGetTreeHead(t *testing.T) { t.Fatalf("must marshal log root: %v", err) } // invalid root - root.RootHash = make([]byte, types.HashSize+1) + root.RootHash = make([]byte, merkle.HashSize+1) bufBadHash, err := root.MarshalBinary() if err != nil { t.Fatalf("must marshal log root: %v", err) @@ -166,7 +167,7 @@ func TestGetTreeHead(t *testing.T) { wantTh: &types.TreeHead{ Timestamp: 1622585623, TreeSize: 0, - RootHash: types.Hash{}, + RootHash: merkle.Hash{}, }, }, } { @@ -248,8 +249,8 @@ func TestGetConsistencyProof(t *testing.T) { rsp: &trillian.GetConsistencyProofResponse{ Proof: &trillian.Proof{ Hashes: [][]byte{ - make([]byte, types.HashSize), - make([]byte, types.HashSize+1), + make([]byte, merkle.HashSize), + make([]byte, merkle.HashSize+1), }, }, }, @@ -261,17 +262,17 @@ func TestGetConsistencyProof(t *testing.T) { rsp: &trillian.GetConsistencyProofResponse{ Proof: &trillian.Proof{ Hashes: [][]byte{ - make([]byte, types.HashSize), - make([]byte, types.HashSize), + make([]byte, merkle.HashSize), + make([]byte, merkle.HashSize), }, }, }, wantProof: &types.ConsistencyProof{ OldSize: 1, NewSize: 3, - Path: []types.Hash{ - types.Hash{}, - types.Hash{}, + Path: []merkle.Hash{ + merkle.Hash{}, + merkle.Hash{}, }, }, }, @@ -301,7 +302,7 @@ func TestGetConsistencyProof(t *testing.T) { func TestGetInclusionProof(t *testing.T) { req := &requests.InclusionProof{ TreeSize: 4, - LeafHash: types.Hash{}, + LeafHash: merkle.Hash{}, } for _, table := range []struct { description string @@ -354,8 +355,8 @@ func TestGetInclusionProof(t *testing.T) { &trillian.Proof{ LeafIndex: 1, Hashes: [][]byte{ - make([]byte, types.HashSize), - make([]byte, types.HashSize+1), + make([]byte, merkle.HashSize), + make([]byte, merkle.HashSize+1), }, }, }, @@ -370,8 +371,8 @@ func TestGetInclusionProof(t *testing.T) { &trillian.Proof{ LeafIndex: 1, Hashes: [][]byte{ - make([]byte, types.HashSize), - make([]byte, types.HashSize), + make([]byte, merkle.HashSize), + make([]byte, merkle.HashSize), }, }, }, @@ -379,9 +380,9 @@ func TestGetInclusionProof(t *testing.T) { wantProof: &types.InclusionProof{ TreeSize: 4, LeafIndex: 1, - Path: []types.Hash{ - types.Hash{}, - types.Hash{}, + Path: []merkle.Hash{ + merkle.Hash{}, + merkle.Hash{}, }, }, }, @@ -416,18 +417,18 @@ func TestGetLeaves(t *testing.T) { firstLeaf := &types.Leaf{ Statement: types.Statement{ ShardHint: 0, - Checksum: types.Hash{}, + Checksum: merkle.Hash{}, }, Signature: types.Signature{}, - KeyHash: types.Hash{}, + KeyHash: merkle.Hash{}, } secondLeaf := &types.Leaf{ Statement: types.Statement{ ShardHint: 0, - Checksum: types.Hash{}, + Checksum: merkle.Hash{}, }, Signature: types.Signature{}, - KeyHash: types.Hash{}, + KeyHash: merkle.Hash{}, } for _, table := range []struct { diff --git a/pkg/instance/handler_test.go b/pkg/instance/handler_test.go index c7539b7..12802f6 100644 --- a/pkg/instance/handler_test.go +++ b/pkg/instance/handler_test.go @@ -15,6 +15,7 @@ import ( mocksDB "git.sigsum.org/log-go/pkg/db/mocks" mocksDNS "git.sigsum.org/log-go/internal/mocks/dns" mocksState "git.sigsum.org/log-go/pkg/state/mocks" + "git.sigsum.org/sigsum-go/pkg/merkle" "git.sigsum.org/sigsum-go/pkg/types" "github.com/golang/mock/gomock" ) @@ -22,29 +23,29 @@ import ( var ( testWitVK = types.PublicKey{} testConfig = Config{ - LogID: fmt.Sprintf("%x", types.HashFn([]byte("logid"))[:]), + LogID: fmt.Sprintf("%x", merkle.HashFn([]byte("logid"))[:]), TreeID: 0, Prefix: "testonly", MaxRange: 3, Deadline: 10, Interval: 10, ShardStart: 10, - Witnesses: map[types.Hash]types.PublicKey{ - *types.HashFn(testWitVK[:]): testWitVK, + Witnesses: map[merkle.Hash]types.PublicKey{ + *merkle.HashFn(testWitVK[:]): testWitVK, }, } testSTH = &types.SignedTreeHead{ TreeHead: types.TreeHead{ Timestamp: 0, TreeSize: 0, - RootHash: *types.HashFn([]byte("root hash")), + RootHash: *merkle.HashFn([]byte("root hash")), }, Signature: types.Signature{}, } testCTH = &types.CosignedTreeHead{ SignedTreeHead: *testSTH, Cosignature: []types.Signature{types.Signature{}}, - KeyHash: []types.Hash{types.Hash{}}, + KeyHash: []merkle.Hash{merkle.Hash{}}, } ) @@ -175,29 +176,29 @@ func TestAddLeaf(t *testing.T) { }, { description: "invalid: bad request (signature error)", - ascii: mustLeafBuffer(t, 10, types.Hash{}, false), + ascii: mustLeafBuffer(t, 10, merkle.Hash{}, false), wantCode: http.StatusBadRequest, }, { description: "invalid: bad request (shard hint is before shard start)", - ascii: mustLeafBuffer(t, 9, types.Hash{}, true), + ascii: mustLeafBuffer(t, 9, merkle.Hash{}, true), wantCode: http.StatusBadRequest, }, { description: "invalid: bad request (shard hint is after shard end)", - ascii: mustLeafBuffer(t, uint64(time.Now().Unix())+1024, types.Hash{}, true), + ascii: mustLeafBuffer(t, uint64(time.Now().Unix())+1024, merkle.Hash{}, true), wantCode: http.StatusBadRequest, }, { description: "invalid: failed verifying domain hint", - ascii: mustLeafBuffer(t, 10, types.Hash{}, true), + ascii: mustLeafBuffer(t, 10, merkle.Hash{}, true), expectDNS: true, errDNS: fmt.Errorf("something went wrong"), wantCode: http.StatusBadRequest, }, { description: "invalid: backend failure", - ascii: mustLeafBuffer(t, 10, types.Hash{}, true), + ascii: mustLeafBuffer(t, 10, merkle.Hash{}, true), expectDNS: true, expectTrillian: true, errTrillian: fmt.Errorf("something went wrong"), @@ -205,7 +206,7 @@ func TestAddLeaf(t *testing.T) { }, { description: "valid", - ascii: mustLeafBuffer(t, 10, types.Hash{}, true), + ascii: mustLeafBuffer(t, 10, merkle.Hash{}, true), expectDNS: true, expectTrillian: true, wantCode: http.StatusOK, @@ -250,7 +251,7 @@ func TestAddCosignature(t *testing.T) { buf := func() io.Reader { return bytes.NewBufferString(fmt.Sprintf("%s=%x\n%s=%x\n", "cosignature", types.Signature{}, - "key_hash", *types.HashFn(testWitVK[:]), + "key_hash", *merkle.HashFn(testWitVK[:]), )) } for _, table := range []struct { @@ -269,7 +270,7 @@ func TestAddCosignature(t *testing.T) { description: "invalid: bad request (unknown witness)", ascii: bytes.NewBufferString(fmt.Sprintf("%s=%x\n%s=%x\n", "cosignature", types.Signature{}, - "key_hash", *types.HashFn(testWitVK[1:]), + "key_hash", *merkle.HashFn(testWitVK[1:]), )), wantCode: http.StatusBadRequest, }, @@ -457,8 +458,8 @@ func TestGetConsistencyProof(t *testing.T) { rsp: &types.ConsistencyProof{ OldSize: 1, NewSize: 2, - Path: []types.Hash{ - *types.HashFn([]byte{}), + Path: []merkle.Hash{ + *merkle.HashFn([]byte{}), }, }, wantCode: http.StatusOK, @@ -527,8 +528,8 @@ func TestGetInclusionProof(t *testing.T) { rsp: &types.InclusionProof{ TreeSize: 2, LeafIndex: 0, - Path: []types.Hash{ - *types.HashFn([]byte{}), + Path: []merkle.Hash{ + *merkle.HashFn([]byte{}), }, }, wantCode: http.StatusOK, @@ -600,10 +601,10 @@ func TestGetLeaves(t *testing.T) { list = append(list[:], types.Leaf{ Statement: types.Statement{ ShardHint: 0, - Checksum: types.Hash{}, + Checksum: merkle.Hash{}, }, Signature: types.Signature{}, - KeyHash: types.Hash{}, + KeyHash: merkle.Hash{}, }) } return &list @@ -662,7 +663,7 @@ func mustHandle(t *testing.T, i Instance, e types.Endpoint) Handler { return Handler{} } -func mustLeafBuffer(t *testing.T, shardHint uint64, message types.Hash, wantSig bool) io.Reader { +func mustLeafBuffer(t *testing.T, shardHint uint64, message merkle.Hash, wantSig bool) io.Reader { t.Helper() vk, sk, err := ed25519.GenerateKey(rand.Reader) @@ -671,7 +672,7 @@ func mustLeafBuffer(t *testing.T, shardHint uint64, message types.Hash, wantSig } msg := types.Statement{ ShardHint: shardHint, - Checksum: *types.HashFn(message[:]), + Checksum: *merkle.HashFn(message[:]), } sig := ed25519.Sign(sk, msg.ToBinary()) if !wantSig { diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go index 7f84bbb..35e24f7 100644 --- a/pkg/instance/instance.go +++ b/pkg/instance/instance.go @@ -10,6 +10,7 @@ import ( "git.sigsum.org/log-go/pkg/db" "git.sigsum.org/log-go/pkg/state" "git.sigsum.org/sigsum-go/pkg/dns" + "git.sigsum.org/sigsum-go/pkg/merkle" "git.sigsum.org/sigsum-go/pkg/requests" "git.sigsum.org/sigsum-go/pkg/types" ) @@ -25,7 +26,7 @@ type Config struct { ShardStart uint64 // Shard interval start (num seconds since UNIX epoch) // Witnesses map trusted witness identifiers to public keys - Witnesses map[types.Hash]types.PublicKey + Witnesses map[merkle.Hash]types.PublicKey } // Instance is an instance of the log's front-end @@ -63,7 +64,7 @@ func (i *Instance) leafRequestFromHTTP(ctx context.Context, r *http.Request) (*r } stmt := types.Statement{ ShardHint: req.ShardHint, - Checksum: *types.HashFn(req.Message[:]), + Checksum: *merkle.HashFn(req.Message[:]), } if !stmt.Verify(&req.PublicKey, &req.Signature) { return nil, fmt.Errorf("invalid signature") diff --git a/pkg/state/single.go b/pkg/state/single.go index 695f0e3..7e7c804 100644 --- a/pkg/state/single.go +++ b/pkg/state/single.go @@ -10,6 +10,7 @@ import ( "git.sigsum.org/log-go/pkg/db" "git.sigsum.org/sigsum-go/pkg/log" + "git.sigsum.org/sigsum-go/pkg/merkle" "git.sigsum.org/sigsum-go/pkg/types" ) @@ -17,7 +18,7 @@ import ( type StateManagerSingle struct { client db.Client signer crypto.Signer - namespace types.Hash + namespace merkle.Hash interval time.Duration deadline time.Duration @@ -29,14 +30,14 @@ type StateManagerSingle struct { // Syncronized and deduplicated witness cosignatures for signedTreeHead events chan *event - cosignatures map[types.Hash]*types.Signature + cosignatures map[merkle.Hash]*types.Signature } func NewStateManagerSingle(client db.Client, signer crypto.Signer, interval, deadline time.Duration) (*StateManagerSingle, error) { sm := &StateManagerSingle{ client: client, signer: signer, - namespace: *types.HashFn(signer.Public().(ed25519.PublicKey)), + namespace: *merkle.HashFn(signer.Public().(ed25519.PublicKey)), interval: interval, deadline: deadline, } @@ -97,7 +98,7 @@ func (sm *StateManagerSingle) AddCosignature(ctx context.Context, pub *types.Pub return fmt.Errorf("invalid cosignature") } select { - case sm.events <- &event{types.HashFn(pub[:]), sig}: + case sm.events <- &event{merkle.HashFn(pub[:]), sig}: return nil case <-ctx.Done(): return fmt.Errorf("request timeout") @@ -136,7 +137,7 @@ func (sm *StateManagerSingle) setCosignedTreeHead() { var cth types.CosignedTreeHead cth.SignedTreeHead = *sm.signedTreeHead cth.Cosignature = make([]types.Signature, 0, n) - cth.KeyHash = make([]types.Hash, 0, n) + cth.KeyHash = make([]merkle.Hash, 0, n) for keyHash, cosignature := range sm.cosignatures { cth.KeyHash = append(cth.KeyHash, keyHash) cth.Cosignature = append(cth.Cosignature, *cosignature) @@ -145,7 +146,7 @@ func (sm *StateManagerSingle) setCosignedTreeHead() { } func (sm *StateManagerSingle) setToCosignTreeHead(nextSTH *types.SignedTreeHead) { - sm.cosignatures = make(map[types.Hash]*types.Signature) + sm.cosignatures = make(map[merkle.Hash]*types.Signature) sm.signedTreeHead = nextSTH } diff --git a/pkg/state/single_test.go b/pkg/state/single_test.go index 8e89020..c859603 100644 --- a/pkg/state/single_test.go +++ b/pkg/state/single_test.go @@ -12,6 +12,7 @@ import ( db "git.sigsum.org/log-go/pkg/db/mocks" "git.sigsum.org/log-go/pkg/state/mocks" + "git.sigsum.org/sigsum-go/pkg/merkle" "git.sigsum.org/sigsum-go/pkg/types" "github.com/golang/mock/gomock" ) @@ -87,7 +88,7 @@ func TestToCosignTreeHead(t *testing.T) { func TestCosignedTreeHead(t *testing.T) { want := &types.CosignedTreeHead{ Cosignature: make([]types.Signature, 1), - KeyHash: make([]types.Hash, 1), + KeyHash: make([]merkle.Hash, 1), } sm := StateManagerSingle{ cosignedTreeHead: want, @@ -130,7 +131,7 @@ func TestAddCosignature(t *testing.T) { }, } { sm := &StateManagerSingle{ - namespace: *types.HashFn(nil), + namespace: *merkle.HashFn(nil), signedTreeHead: &types.SignedTreeHead{}, events: make(chan *event, 1), } @@ -161,17 +162,17 @@ func TestRotate(t *testing.T) { sth := &types.SignedTreeHead{} nextSTH := &types.SignedTreeHead{TreeHead: types.TreeHead{Timestamp: 1}} ev := &event{ - keyHash: &types.Hash{}, + keyHash: &merkle.Hash{}, cosignature: &types.Signature{}, } wantCTH := &types.CosignedTreeHead{ SignedTreeHead: *sth, - KeyHash: []types.Hash{*ev.keyHash}, + KeyHash: []merkle.Hash{*ev.keyHash}, Cosignature: []types.Signature{*ev.cosignature}, } sm := &StateManagerSingle{ signedTreeHead: sth, - cosignatures: make(map[types.Hash]*types.Signature), + cosignatures: make(map[merkle.Hash]*types.Signature), events: make(chan *event, 1), } defer close(sm.events) @@ -207,7 +208,7 @@ func mustKeyPair(t *testing.T) (crypto.Signer, types.PublicKey) { return sk, pub } -func mustSign(t *testing.T, s crypto.Signer, th *types.TreeHead, kh *types.Hash) *types.SignedTreeHead { +func mustSign(t *testing.T, s crypto.Signer, th *types.TreeHead, kh *merkle.Hash) *types.SignedTreeHead { t.Helper() sth, err := th.Sign(s, kh) if err != nil { diff --git a/pkg/state/state_manager.go b/pkg/state/state_manager.go index 9533479..ce9fc0a 100644 --- a/pkg/state/state_manager.go +++ b/pkg/state/state_manager.go @@ -3,6 +3,7 @@ package state import ( "context" + "git.sigsum.org/sigsum-go/pkg/merkle" "git.sigsum.org/sigsum-go/pkg/types" ) @@ -24,6 +25,6 @@ type StateManager interface { // event is a verified cosignature request type event struct { - keyHash *types.Hash + keyHash *merkle.Hash cosignature *types.Signature } -- cgit v1.2.3