aboutsummaryrefslogtreecommitdiff
path: root/pkg/types/types.go
blob: bc58c981eb5489e5ba8759a936d0e690d865aab8 (plain)
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package types

import (
	"crypto"
	"crypto/ed25519"
	"crypto/sha256"
	"fmt"
	"strings"
)

const (
	HashSize            = sha256.Size
	SignatureSize       = ed25519.SignatureSize
	VerificationKeySize = ed25519.PublicKeySize

	EndpointAddLeaf             = Endpoint("add-leaf")
	EndpointAddCosignature      = Endpoint("add-cosignature")
	EndpointGetTreeHeadLatest   = Endpoint("get-tree-head-latest")
	EndpointGetTreeHeadToSign   = Endpoint("get-tree-head-to-sign")
	EndpointGetTreeHeadCosigned = Endpoint("get-tree-head-cosigned")
	EndpointGetInclusionProof   = Endpoint("get-inclusion-proof")
	EndpointGetConsistencyProof = Endpoint("get-consistency-proof")
	EndpointGetLeaves           = Endpoint("get-leaves")
)

// Endpoint is a named HTTP API endpoint
type Endpoint string

// Path joins a number of components to form a full endpoint path.  For example,
// EndpointAddLeaf.Path("example.com", "st/v0") -> example.com/st/v0/add-leaf.
func (e Endpoint) Path(components ...string) string {
	return strings.Join(append(components, string(e)), "/")
}

type Leaf struct {
	Message
	SigIdent
}

type Message struct {
	ShardHint uint64
	Checksum  *[HashSize]byte
}

type SigIdent struct {
	Signature *[SignatureSize]byte
	KeyHash   *[HashSize]byte
}

type SignedTreeHead struct {
	TreeHead
	Signature *[SignatureSize]byte
}

type CosignedTreeHead struct {
	SignedTreeHead
	SigIdent []*SigIdent
}

type TreeHead struct {
	Timestamp uint64
	TreeSize  uint64
	RootHash  *[HashSize]byte
	KeyHash   *[HashSize]byte
}

type ConsistencyProof struct {
	NewSize uint64
	OldSize uint64
	Path    []*[HashSize]byte
}

type InclusionProof struct {
	TreeSize  uint64
	LeafIndex uint64
	Path      []*[HashSize]byte
}

type LeafList []*Leaf

type ConsistencyProofRequest struct {
	NewSize uint64
	OldSize uint64
}

type InclusionProofRequest struct {
	LeafHash *[HashSize]byte
	TreeSize uint64
}

type LeavesRequest struct {
	StartSize uint64
	EndSize   uint64
}

type LeafRequest struct {
	Message
	Signature       *[SignatureSize]byte
	VerificationKey *[VerificationKeySize]byte
	DomainHint      string
}

type CosignatureRequest struct {
	SigIdent
}

// Sign signs the tree head using the log's signature scheme
func (th *TreeHead) Sign(signer crypto.Signer) (*SignedTreeHead, error) {
	sig, err := signer.Sign(nil, th.Marshal(), crypto.Hash(0))
	if err != nil {
		return nil, fmt.Errorf("Sign: %v", err)
	}

	sth := &SignedTreeHead{
		TreeHead:  *th,
		Signature: &[SignatureSize]byte{},
	}
	copy(sth.Signature[:], sig)
	return sth, nil
}

// Verify verifies the tree head signature using the log's signature scheme
func (th *TreeHead) Verify(vk *[VerificationKeySize]byte, sig *[SignatureSize]byte) error {
	if !ed25519.Verify(ed25519.PublicKey(vk[:]), th.Marshal(), sig[:]) {
		return fmt.Errorf("invalid tree head signature")
	}
	return nil
}

// Verify checks if a leaf is included in the log
func (p *InclusionProof) Verify(leaf *Leaf, th *TreeHead) error { // TODO
	return nil
}

// Verify checks if two tree heads are consistent
func (p *ConsistencyProof) Verify(oldTH, newTH *TreeHead) error { // TODO
	return nil
}