Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / mod@v0.3.0 / sumdb / tlog / tlog.go
1 // Copyright 2019 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Package tlog implements a tamper-evident log
6 // used in the Go module go.sum database server.
7 //
8 // This package follows the design of Certificate Transparency (RFC 6962)
9 // and its proofs are compatible with that system.
10 // See TestCertificateTransparency.
11 //
12 package tlog
13
14 import (
15         "crypto/sha256"
16         "encoding/base64"
17         "errors"
18         "fmt"
19         "math/bits"
20 )
21
22 // A Hash is a hash identifying a log record or tree root.
23 type Hash [HashSize]byte
24
25 // HashSize is the size of a Hash in bytes.
26 const HashSize = 32
27
28 // String returns a base64 representation of the hash for printing.
29 func (h Hash) String() string {
30         return base64.StdEncoding.EncodeToString(h[:])
31 }
32
33 // MarshalJSON marshals the hash as a JSON string containing the base64-encoded hash.
34 func (h Hash) MarshalJSON() ([]byte, error) {
35         return []byte(`"` + h.String() + `"`), nil
36 }
37
38 // UnmarshalJSON unmarshals a hash from JSON string containing the a base64-encoded hash.
39 func (h *Hash) UnmarshalJSON(data []byte) error {
40         if len(data) != 1+44+1 || data[0] != '"' || data[len(data)-2] != '=' || data[len(data)-1] != '"' {
41                 return errors.New("cannot decode hash")
42         }
43
44         // As of Go 1.12, base64.StdEncoding.Decode insists on
45         // slicing into target[33:] even when it only writes 32 bytes.
46         // Since we already checked that the hash ends in = above,
47         // we can use base64.RawStdEncoding with the = removed;
48         // RawStdEncoding does not exhibit the same bug.
49         // We decode into a temporary to avoid writing anything to *h
50         // unless the entire input is well-formed.
51         var tmp Hash
52         n, err := base64.RawStdEncoding.Decode(tmp[:], data[1:len(data)-2])
53         if err != nil || n != HashSize {
54                 return errors.New("cannot decode hash")
55         }
56         *h = tmp
57         return nil
58 }
59
60 // ParseHash parses the base64-encoded string form of a hash.
61 func ParseHash(s string) (Hash, error) {
62         data, err := base64.StdEncoding.DecodeString(s)
63         if err != nil || len(data) != HashSize {
64                 return Hash{}, fmt.Errorf("malformed hash")
65         }
66         var h Hash
67         copy(h[:], data)
68         return h, nil
69 }
70
71 // maxpow2 returns k, the maximum power of 2 smaller than n,
72 // as well as l = log₂ k (so k = 1<<l).
73 func maxpow2(n int64) (k int64, l int) {
74         l = 0
75         for 1<<uint(l+1) < n {
76                 l++
77         }
78         return 1 << uint(l), l
79 }
80
81 var zeroPrefix = []byte{0x00}
82
83 // RecordHash returns the content hash for the given record data.
84 func RecordHash(data []byte) Hash {
85         // SHA256(0x00 || data)
86         // https://tools.ietf.org/html/rfc6962#section-2.1
87         h := sha256.New()
88         h.Write(zeroPrefix)
89         h.Write(data)
90         var h1 Hash
91         h.Sum(h1[:0])
92         return h1
93 }
94
95 // NodeHash returns the hash for an interior tree node with the given left and right hashes.
96 func NodeHash(left, right Hash) Hash {
97         // SHA256(0x01 || left || right)
98         // https://tools.ietf.org/html/rfc6962#section-2.1
99         // We use a stack buffer to assemble the hash input
100         // to avoid allocating a hash struct with sha256.New.
101         var buf [1 + HashSize + HashSize]byte
102         buf[0] = 0x01
103         copy(buf[1:], left[:])
104         copy(buf[1+HashSize:], right[:])
105         return sha256.Sum256(buf[:])
106 }
107
108 // For information about the stored hash index ordering,
109 // see section 3.3 of Crosby and Wallach's paper
110 // "Efficient Data Structures for Tamper-Evident Logging".
111 // https://www.usenix.org/legacy/event/sec09/tech/full_papers/crosby.pdf
112
113 // StoredHashIndex maps the tree coordinates (level, n)
114 // to a dense linear ordering that can be used for hash storage.
115 // Hash storage implementations that store hashes in sequential
116 // storage can use this function to compute where to read or write
117 // a given hash.
118 func StoredHashIndex(level int, n int64) int64 {
119         // Level L's n'th hash is written right after level L+1's 2n+1'th hash.
120         // Work our way down to the level 0 ordering.
121         // We'll add back the original level count at the end.
122         for l := level; l > 0; l-- {
123                 n = 2*n + 1
124         }
125
126         // Level 0's n'th hash is written at n+n/2+n/4+... (eventually n/2ⁱ hits zero).
127         i := int64(0)
128         for ; n > 0; n >>= 1 {
129                 i += n
130         }
131
132         return i + int64(level)
133 }
134
135 // SplitStoredHashIndex is the inverse of StoredHashIndex.
136 // That is, SplitStoredHashIndex(StoredHashIndex(level, n)) == level, n.
137 func SplitStoredHashIndex(index int64) (level int, n int64) {
138         // Determine level 0 record before index.
139         // StoredHashIndex(0, n) < 2*n,
140         // so the n we want is in [index/2, index/2+log₂(index)].
141         n = index / 2
142         indexN := StoredHashIndex(0, n)
143         if indexN > index {
144                 panic("bad math")
145         }
146         for {
147                 // Each new record n adds 1 + trailingZeros(n) hashes.
148                 x := indexN + 1 + int64(bits.TrailingZeros64(uint64(n+1)))
149                 if x > index {
150                         break
151                 }
152                 n++
153                 indexN = x
154         }
155         // The hash we want was committed with record n,
156         // meaning it is one of (0, n), (1, n/2), (2, n/4), ...
157         level = int(index - indexN)
158         return level, n >> uint(level)
159 }
160
161 // StoredHashCount returns the number of stored hashes
162 // that are expected for a tree with n records.
163 func StoredHashCount(n int64) int64 {
164         if n == 0 {
165                 return 0
166         }
167         // The tree will have the hashes up to the last leaf hash.
168         numHash := StoredHashIndex(0, n-1) + 1
169         // And it will have any hashes for subtrees completed by that leaf.
170         for i := uint64(n - 1); i&1 != 0; i >>= 1 {
171                 numHash++
172         }
173         return numHash
174 }
175
176 // StoredHashes returns the hashes that must be stored when writing
177 // record n with the given data. The hashes should be stored starting
178 // at StoredHashIndex(0, n). The result will have at most 1 + log₂ n hashes,
179 // but it will average just under two per call for a sequence of calls for n=1..k.
180 //
181 // StoredHashes may read up to log n earlier hashes from r
182 // in order to compute hashes for completed subtrees.
183 func StoredHashes(n int64, data []byte, r HashReader) ([]Hash, error) {
184         return StoredHashesForRecordHash(n, RecordHash(data), r)
185 }
186
187 // StoredHashesForRecordHash is like StoredHashes but takes
188 // as its second argument RecordHash(data) instead of data itself.
189 func StoredHashesForRecordHash(n int64, h Hash, r HashReader) ([]Hash, error) {
190         // Start with the record hash.
191         hashes := []Hash{h}
192
193         // Build list of indexes needed for hashes for completed subtrees.
194         // Each trailing 1 bit in the binary representation of n completes a subtree
195         // and consumes a hash from an adjacent subtree.
196         m := int(bits.TrailingZeros64(uint64(n + 1)))
197         indexes := make([]int64, m)
198         for i := 0; i < m; i++ {
199                 // We arrange indexes in sorted order.
200                 // Note that n>>i is always odd.
201                 indexes[m-1-i] = StoredHashIndex(i, n>>uint(i)-1)
202         }
203
204         // Fetch hashes.
205         old, err := r.ReadHashes(indexes)
206         if err != nil {
207                 return nil, err
208         }
209         if len(old) != len(indexes) {
210                 return nil, fmt.Errorf("tlog: ReadHashes(%d indexes) = %d hashes", len(indexes), len(old))
211         }
212
213         // Build new hashes.
214         for i := 0; i < m; i++ {
215                 h = NodeHash(old[m-1-i], h)
216                 hashes = append(hashes, h)
217         }
218         return hashes, nil
219 }
220
221 // A HashReader can read hashes for nodes in the log's tree structure.
222 type HashReader interface {
223         // ReadHashes returns the hashes with the given stored hash indexes
224         // (see StoredHashIndex and SplitStoredHashIndex).
225         // ReadHashes must return a slice of hashes the same length as indexes,
226         // or else it must return a non-nil error.
227         // ReadHashes may run faster if indexes is sorted in increasing order.
228         ReadHashes(indexes []int64) ([]Hash, error)
229 }
230
231 // A HashReaderFunc is a function implementing HashReader.
232 type HashReaderFunc func([]int64) ([]Hash, error)
233
234 func (f HashReaderFunc) ReadHashes(indexes []int64) ([]Hash, error) {
235         return f(indexes)
236 }
237
238 // TreeHash computes the hash for the root of the tree with n records,
239 // using the HashReader to obtain previously stored hashes
240 // (those returned by StoredHashes during the writes of those n records).
241 // TreeHash makes a single call to ReadHash requesting at most 1 + log₂ n hashes.
242 // The tree of size zero is defined to have an all-zero Hash.
243 func TreeHash(n int64, r HashReader) (Hash, error) {
244         if n == 0 {
245                 return Hash{}, nil
246         }
247         indexes := subTreeIndex(0, n, nil)
248         hashes, err := r.ReadHashes(indexes)
249         if err != nil {
250                 return Hash{}, err
251         }
252         if len(hashes) != len(indexes) {
253                 return Hash{}, fmt.Errorf("tlog: ReadHashes(%d indexes) = %d hashes", len(indexes), len(hashes))
254         }
255         hash, hashes := subTreeHash(0, n, hashes)
256         if len(hashes) != 0 {
257                 panic("tlog: bad index math in TreeHash")
258         }
259         return hash, nil
260 }
261
262 // subTreeIndex returns the storage indexes needed to compute
263 // the hash for the subtree containing records [lo, hi),
264 // appending them to need and returning the result.
265 // See https://tools.ietf.org/html/rfc6962#section-2.1
266 func subTreeIndex(lo, hi int64, need []int64) []int64 {
267         // See subTreeHash below for commentary.
268         for lo < hi {
269                 k, level := maxpow2(hi - lo + 1)
270                 if lo&(k-1) != 0 {
271                         panic("tlog: bad math in subTreeIndex")
272                 }
273                 need = append(need, StoredHashIndex(level, lo>>uint(level)))
274                 lo += k
275         }
276         return need
277 }
278
279 // subTreeHash computes the hash for the subtree containing records [lo, hi),
280 // assuming that hashes are the hashes corresponding to the indexes
281 // returned by subTreeIndex(lo, hi).
282 // It returns any leftover hashes.
283 func subTreeHash(lo, hi int64, hashes []Hash) (Hash, []Hash) {
284         // Repeatedly partition the tree into a left side with 2^level nodes,
285         // for as large a level as possible, and a right side with the fringe.
286         // The left hash is stored directly and can be read from storage.
287         // The right side needs further computation.
288         numTree := 0
289         for lo < hi {
290                 k, _ := maxpow2(hi - lo + 1)
291                 if lo&(k-1) != 0 || lo >= hi {
292                         panic("tlog: bad math in subTreeHash")
293                 }
294                 numTree++
295                 lo += k
296         }
297
298         if len(hashes) < numTree {
299                 panic("tlog: bad index math in subTreeHash")
300         }
301
302         // Reconstruct hash.
303         h := hashes[numTree-1]
304         for i := numTree - 2; i >= 0; i-- {
305                 h = NodeHash(hashes[i], h)
306         }
307         return h, hashes[numTree:]
308 }
309
310 // A RecordProof is a verifiable proof that a particular log root contains a particular record.
311 // RFC 6962 calls this a “Merkle audit path.”
312 type RecordProof []Hash
313
314 // ProveRecord returns the proof that the tree of size t contains the record with index n.
315 func ProveRecord(t, n int64, r HashReader) (RecordProof, error) {
316         if t < 0 || n < 0 || n >= t {
317                 return nil, fmt.Errorf("tlog: invalid inputs in ProveRecord")
318         }
319         indexes := leafProofIndex(0, t, n, nil)
320         if len(indexes) == 0 {
321                 return RecordProof{}, nil
322         }
323         hashes, err := r.ReadHashes(indexes)
324         if err != nil {
325                 return nil, err
326         }
327         if len(hashes) != len(indexes) {
328                 return nil, fmt.Errorf("tlog: ReadHashes(%d indexes) = %d hashes", len(indexes), len(hashes))
329         }
330
331         p, hashes := leafProof(0, t, n, hashes)
332         if len(hashes) != 0 {
333                 panic("tlog: bad index math in ProveRecord")
334         }
335         return p, nil
336 }
337
338 // leafProofIndex builds the list of indexes needed to construct the proof
339 // that leaf n is contained in the subtree with leaves [lo, hi).
340 // It appends those indexes to need and returns the result.
341 // See https://tools.ietf.org/html/rfc6962#section-2.1.1
342 func leafProofIndex(lo, hi, n int64, need []int64) []int64 {
343         // See leafProof below for commentary.
344         if !(lo <= n && n < hi) {
345                 panic("tlog: bad math in leafProofIndex")
346         }
347         if lo+1 == hi {
348                 return need
349         }
350         if k, _ := maxpow2(hi - lo); n < lo+k {
351                 need = leafProofIndex(lo, lo+k, n, need)
352                 need = subTreeIndex(lo+k, hi, need)
353         } else {
354                 need = subTreeIndex(lo, lo+k, need)
355                 need = leafProofIndex(lo+k, hi, n, need)
356         }
357         return need
358 }
359
360 // leafProof constructs the proof that leaf n is contained in the subtree with leaves [lo, hi).
361 // It returns any leftover hashes as well.
362 // See https://tools.ietf.org/html/rfc6962#section-2.1.1
363 func leafProof(lo, hi, n int64, hashes []Hash) (RecordProof, []Hash) {
364         // We must have lo <= n < hi or else the code here has a bug.
365         if !(lo <= n && n < hi) {
366                 panic("tlog: bad math in leafProof")
367         }
368
369         if lo+1 == hi { // n == lo
370                 // Reached the leaf node.
371                 // The verifier knows what the leaf hash is, so we don't need to send it.
372                 return RecordProof{}, hashes
373         }
374
375         // Walk down the tree toward n.
376         // Record the hash of the path not taken (needed for verifying the proof).
377         var p RecordProof
378         var th Hash
379         if k, _ := maxpow2(hi - lo); n < lo+k {
380                 // n is on left side
381                 p, hashes = leafProof(lo, lo+k, n, hashes)
382                 th, hashes = subTreeHash(lo+k, hi, hashes)
383         } else {
384                 // n is on right side
385                 th, hashes = subTreeHash(lo, lo+k, hashes)
386                 p, hashes = leafProof(lo+k, hi, n, hashes)
387         }
388         return append(p, th), hashes
389 }
390
391 var errProofFailed = errors.New("invalid transparency proof")
392
393 // CheckRecord verifies that p is a valid proof that the tree of size t
394 // with hash th has an n'th record with hash h.
395 func CheckRecord(p RecordProof, t int64, th Hash, n int64, h Hash) error {
396         if t < 0 || n < 0 || n >= t {
397                 return fmt.Errorf("tlog: invalid inputs in CheckRecord")
398         }
399         th2, err := runRecordProof(p, 0, t, n, h)
400         if err != nil {
401                 return err
402         }
403         if th2 == th {
404                 return nil
405         }
406         return errProofFailed
407 }
408
409 // runRecordProof runs the proof p that leaf n is contained in the subtree with leaves [lo, hi).
410 // Running the proof means constructing and returning the implied hash of that
411 // subtree.
412 func runRecordProof(p RecordProof, lo, hi, n int64, leafHash Hash) (Hash, error) {
413         // We must have lo <= n < hi or else the code here has a bug.
414         if !(lo <= n && n < hi) {
415                 panic("tlog: bad math in runRecordProof")
416         }
417
418         if lo+1 == hi { // m == lo
419                 // Reached the leaf node.
420                 // The proof must not have any unnecessary hashes.
421                 if len(p) != 0 {
422                         return Hash{}, errProofFailed
423                 }
424                 return leafHash, nil
425         }
426
427         if len(p) == 0 {
428                 return Hash{}, errProofFailed
429         }
430
431         k, _ := maxpow2(hi - lo)
432         if n < lo+k {
433                 th, err := runRecordProof(p[:len(p)-1], lo, lo+k, n, leafHash)
434                 if err != nil {
435                         return Hash{}, err
436                 }
437                 return NodeHash(th, p[len(p)-1]), nil
438         } else {
439                 th, err := runRecordProof(p[:len(p)-1], lo+k, hi, n, leafHash)
440                 if err != nil {
441                         return Hash{}, err
442                 }
443                 return NodeHash(p[len(p)-1], th), nil
444         }
445 }
446
447 // A TreeProof is a verifiable proof that a particular log tree contains
448 // as a prefix all records present in an earlier tree.
449 // RFC 6962 calls this a “Merkle consistency proof.”
450 type TreeProof []Hash
451
452 // ProveTree returns the proof that the tree of size t contains
453 // as a prefix all the records from the tree of smaller size n.
454 func ProveTree(t, n int64, h HashReader) (TreeProof, error) {
455         if t < 1 || n < 1 || n > t {
456                 return nil, fmt.Errorf("tlog: invalid inputs in ProveTree")
457         }
458         indexes := treeProofIndex(0, t, n, nil)
459         if len(indexes) == 0 {
460                 return TreeProof{}, nil
461         }
462         hashes, err := h.ReadHashes(indexes)
463         if err != nil {
464                 return nil, err
465         }
466         if len(hashes) != len(indexes) {
467                 return nil, fmt.Errorf("tlog: ReadHashes(%d indexes) = %d hashes", len(indexes), len(hashes))
468         }
469
470         p, hashes := treeProof(0, t, n, hashes)
471         if len(hashes) != 0 {
472                 panic("tlog: bad index math in ProveTree")
473         }
474         return p, nil
475 }
476
477 // treeProofIndex builds the list of indexes needed to construct
478 // the sub-proof related to the subtree containing records [lo, hi).
479 // See https://tools.ietf.org/html/rfc6962#section-2.1.2.
480 func treeProofIndex(lo, hi, n int64, need []int64) []int64 {
481         // See treeProof below for commentary.
482         if !(lo < n && n <= hi) {
483                 panic("tlog: bad math in treeProofIndex")
484         }
485
486         if n == hi {
487                 if lo == 0 {
488                         return need
489                 }
490                 return subTreeIndex(lo, hi, need)
491         }
492
493         if k, _ := maxpow2(hi - lo); n <= lo+k {
494                 need = treeProofIndex(lo, lo+k, n, need)
495                 need = subTreeIndex(lo+k, hi, need)
496         } else {
497                 need = subTreeIndex(lo, lo+k, need)
498                 need = treeProofIndex(lo+k, hi, n, need)
499         }
500         return need
501 }
502
503 // treeProof constructs the sub-proof related to the subtree containing records [lo, hi).
504 // It returns any leftover hashes as well.
505 // See https://tools.ietf.org/html/rfc6962#section-2.1.2.
506 func treeProof(lo, hi, n int64, hashes []Hash) (TreeProof, []Hash) {
507         // We must have lo < n <= hi or else the code here has a bug.
508         if !(lo < n && n <= hi) {
509                 panic("tlog: bad math in treeProof")
510         }
511
512         // Reached common ground.
513         if n == hi {
514                 if lo == 0 {
515                         // This subtree corresponds exactly to the old tree.
516                         // The verifier knows that hash, so we don't need to send it.
517                         return TreeProof{}, hashes
518                 }
519                 th, hashes := subTreeHash(lo, hi, hashes)
520                 return TreeProof{th}, hashes
521         }
522
523         // Interior node for the proof.
524         // Decide whether to walk down the left or right side.
525         var p TreeProof
526         var th Hash
527         if k, _ := maxpow2(hi - lo); n <= lo+k {
528                 // m is on left side
529                 p, hashes = treeProof(lo, lo+k, n, hashes)
530                 th, hashes = subTreeHash(lo+k, hi, hashes)
531         } else {
532                 // m is on right side
533                 th, hashes = subTreeHash(lo, lo+k, hashes)
534                 p, hashes = treeProof(lo+k, hi, n, hashes)
535         }
536         return append(p, th), hashes
537 }
538
539 // CheckTree verifies that p is a valid proof that the tree of size t with hash th
540 // contains as a prefix the tree of size n with hash h.
541 func CheckTree(p TreeProof, t int64, th Hash, n int64, h Hash) error {
542         if t < 1 || n < 1 || n > t {
543                 return fmt.Errorf("tlog: invalid inputs in CheckTree")
544         }
545         h2, th2, err := runTreeProof(p, 0, t, n, h)
546         if err != nil {
547                 return err
548         }
549         if th2 == th && h2 == h {
550                 return nil
551         }
552         return errProofFailed
553 }
554
555 // runTreeProof runs the sub-proof p related to the subtree containing records [lo, hi),
556 // where old is the hash of the old tree with n records.
557 // Running the proof means constructing and returning the implied hashes of that
558 // subtree in both the old and new tree.
559 func runTreeProof(p TreeProof, lo, hi, n int64, old Hash) (Hash, Hash, error) {
560         // We must have lo < n <= hi or else the code here has a bug.
561         if !(lo < n && n <= hi) {
562                 panic("tlog: bad math in runTreeProof")
563         }
564
565         // Reached common ground.
566         if n == hi {
567                 if lo == 0 {
568                         if len(p) != 0 {
569                                 return Hash{}, Hash{}, errProofFailed
570                         }
571                         return old, old, nil
572                 }
573                 if len(p) != 1 {
574                         return Hash{}, Hash{}, errProofFailed
575                 }
576                 return p[0], p[0], nil
577         }
578
579         if len(p) == 0 {
580                 return Hash{}, Hash{}, errProofFailed
581         }
582
583         // Interior node for the proof.
584         k, _ := maxpow2(hi - lo)
585         if n <= lo+k {
586                 oh, th, err := runTreeProof(p[:len(p)-1], lo, lo+k, n, old)
587                 if err != nil {
588                         return Hash{}, Hash{}, err
589                 }
590                 return oh, NodeHash(th, p[len(p)-1]), nil
591         } else {
592                 oh, th, err := runTreeProof(p[:len(p)-1], lo+k, hi, n, old)
593                 if err != nil {
594                         return Hash{}, Hash{}, err
595                 }
596                 return NodeHash(p[len(p)-1], oh), NodeHash(p[len(p)-1], th), nil
597         }
598 }