-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathsigsum.go
More file actions
128 lines (113 loc) · 3.58 KB
/
Copy pathsigsum.go
File metadata and controls
128 lines (113 loc) · 3.58 KB
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
//go:build sigsum
// Run with "go run -tags sigsum -mod=mod ./cmd/litewitness/testdata/gentest"
// and re-run "go mod tidy" after use to clean up its dependencies.
package main
import (
"crypto/ed25519"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/binary"
"encoding/hex"
"encoding/pem"
"flag"
"fmt"
"log"
"net/url"
"golang.org/x/crypto/hkdf"
"golang.org/x/crypto/ssh"
"golang.org/x/mod/sumdb/note"
"golang.org/x/mod/sumdb/tlog"
sigsum "sigsum.org/sigsum-go/pkg/crypto"
"sigsum.org/sigsum-go/pkg/merkle"
)
var seedFlag = flag.String("seed", "", "hex-encoded seed")
func main() {
flag.Parse()
var seed []byte
if *seedFlag == "" {
seed = make([]byte, 32)
if _, err := rand.Read(seed); err != nil {
log.Fatal(err)
}
} else {
seed = make([]byte, hex.DecodedLen(len(*seedFlag)))
if _, err := hex.Decode(seed, []byte(*seedFlag)); err != nil {
log.Fatal(err)
}
}
fmt.Printf("- seed: %x\n", seed)
h := hkdf.New(sha256.New, seed, []byte("litewitness gentest"), nil)
publicKey, privateKey, _ := ed25519.GenerateKey(h)
fmt.Printf("- log private key: %x\n", privateKey.Seed())
fmt.Printf("- log public key: %x\n", publicKey)
keyHash := sigsum.HashBytes(publicKey[:])
fmt.Printf("- log key hash: %x\n", keyHash)
origin := fmt.Sprintf("sigsum.org/v1/tree/%x", keyHash)
fmt.Printf("- origin: %s\n", origin)
fmt.Printf("- origin URL-encoded: %s\n", url.QueryEscape(origin))
const algEd25519 = 1
kh := noteKeyHash(origin, append([]byte{algEd25519}, publicKey...))
vkey := fmt.Sprintf("%s+%08x+%s", origin, kh, base64.StdEncoding.EncodeToString(append([]byte{algEd25519}, publicKey...)))
skey := fmt.Sprintf("PRIVATE+KEY+%s+%08x+%s", origin, kh, base64.StdEncoding.EncodeToString(append([]byte{algEd25519}, privateKey.Seed()...)))
s, _ := note.NewSigner(skey)
fmt.Printf("- log note vkey: %s\n", vkey)
fmt.Printf("- log note key: %s\n", skey)
witSeed := make([]byte, ed25519.SeedSize)
h.Read(witSeed)
witKey := ed25519.NewKeyFromSeed(witSeed)
ss, err := ssh.NewSignerFromSigner(witKey)
if err != nil {
log.Fatal(err)
}
pkHash := sigsum.HashBytes(ss.PublicKey().(ssh.CryptoPublicKey).CryptoPublicKey().(ed25519.PublicKey))
fmt.Printf("- witness key hash: %s\n", hex.EncodeToString(pkHash[:]))
fmt.Printf("- witness key: %x\n", witKey)
pemKey, err := ssh.MarshalPrivateKey(witKey, "")
if err != nil {
log.Fatal(err)
}
fmt.Printf("- witness key:\n%s", pem.EncodeToMemory(pemKey))
tree := merkle.NewTree()
addLeaf := func(leaf sigsum.Hash) {
if !tree.AddLeafHash(&leaf) {
panic("duplicate")
}
fmt.Printf("- leaf[%d] hash: %x\n", tree.Size(), leaf)
}
signTreeHead := func() {
checkpoint := fmt.Sprintf("%s\n%d\n%s\n", origin, tree.Size(), tlog.Hash(tree.GetRootHash()))
n, _ := note.Sign(¬e.Note{Text: checkpoint}, s)
fmt.Printf("- checkpoint (size %d):\n%s\n", tree.Size(), n)
}
consistencyProof := func(oldSize uint64) {
proof, err := tree.ProveConsistency(oldSize, tree.Size())
if err != nil {
log.Fatal(err)
}
fmt.Printf("- consistency proof from size %d:\n", oldSize)
fmt.Printf("old %d\n", oldSize)
for _, p := range proof {
fmt.Printf("%s\n", base64.StdEncoding.EncodeToString(p[:]))
}
}
addLeaf(sigsum.Hash{42, 0})
signTreeHead()
addLeaf(sigsum.Hash{42, 1})
addLeaf(sigsum.Hash{42, 2})
signTreeHead()
consistencyProof(1)
addLeaf(sigsum.Hash{42, 3})
addLeaf(sigsum.Hash{42, 4})
signTreeHead()
consistencyProof(1)
consistencyProof(3)
}
func noteKeyHash(name string, key []byte) uint32 {
h := sha256.New()
h.Write([]byte(name))
h.Write([]byte("\n"))
h.Write(key)
sum := h.Sum(nil)
return binary.BigEndian.Uint32(sum)
}