1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
package types
import (
"crypto"
"crypto/ed25519"
"encoding/binary"
"fmt"
"io"
"git.sigsum.org/sigsum-lib-go/pkg/ascii"
)
type TreeHead struct {
Timestamp uint64 `ascii:"timestamp"`
TreeSize uint64 `ascii:"tree_size"`
RootHash Hash `ascii:"root_hash"`
}
type SignedTreeHead struct {
TreeHead
Signature Signature `ascii:"signature"`
}
type CosignedTreeHead struct {
SignedTreeHead
Cosignature []Signature `ascii:"cosignature"`
KeyHash []Hash `ascii:"key_hash"`
}
func (th *TreeHead) ToBinary(keyHash *Hash) []byte {
b := make([]byte, 80)
binary.BigEndian.PutUint64(b[0:8], th.Timestamp)
binary.BigEndian.PutUint64(b[8:16], th.TreeSize)
copy(b[16:48], th.RootHash[:])
copy(b[48:80], keyHash[:])
return b
}
func (th *TreeHead) Sign(s crypto.Signer, ctx *Hash) (*SignedTreeHead, error) {
sig, err := s.Sign(nil, th.ToBinary(ctx), crypto.Hash(0))
if err != nil {
return nil, fmt.Errorf("types: failed signing tree head")
}
sth := &SignedTreeHead{
TreeHead: *th,
}
copy(sth.Signature[:], sig)
return sth, nil
}
func (sth *SignedTreeHead) ToASCII(w io.Writer) error {
return ascii.StdEncoding.Serialize(w, sth)
}
func (sth *SignedTreeHead) FromASCII(r io.Reader) error {
return ascii.StdEncoding.Deserialize(r, sth)
}
func (sth *SignedTreeHead) Verify(key *PublicKey, ctx *Hash) bool {
return ed25519.Verify(ed25519.PublicKey(key[:]), sth.TreeHead.ToBinary(ctx), sth.Signature[:])
}
func (cth *CosignedTreeHead) ToASCII(w io.Writer) error {
return ascii.StdEncoding.Serialize(w, cth)
}
func (cth *CosignedTreeHead) FromASCII(r io.Reader) error {
if err := ascii.StdEncoding.Deserialize(r, cth); err != nil {
return err
}
if len(cth.Cosignature) != len(cth.KeyHash) {
return fmt.Errorf("types: mismatched cosignature count")
}
return nil
}
|