serial.mx raw
1 // Package serial provides the 5-byte uint40 serial type and truncated hash
2 // types used by the store's index system.
3 package serial
4
5 import (
6 "crypto/sha256"
7 "encoding/binary"
8 )
9
10 const (
11 // Len is the byte length of a serial (5 bytes = 40 bits).
12 Len = 5
13 // Max is the maximum serial value (2^40 - 1).
14 Max uint64 = 1<<40 - 1
15 // HashLen is the byte length of truncated hashes used in index keys.
16 HashLen = 8
17 )
18
19 // Put writes a uint64 as a 5-byte big-endian serial into dst.
20 // dst must be at least 5 bytes.
21 func Put(dst []byte, v uint64) {
22 dst[0] = byte(v >> 32)
23 dst[1] = byte(v >> 24)
24 dst[2] = byte(v >> 16)
25 dst[3] = byte(v >> 8)
26 dst[4] = byte(v)
27 }
28
29 // Get reads a 5-byte big-endian serial from src and returns it as uint64.
30 func Get(src []byte) (n uint64) {
31 return uint64(src[0])<<32 |
32 uint64(src[1])<<24 |
33 uint64(src[2])<<16 |
34 uint64(src[3])<<8 |
35 uint64(src[4])
36 }
37
38 // Append appends a 5-byte serial to dst.
39 func Append(dst []byte, v uint64) (buf []byte) {
40 return push(dst, byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
41 }
42
43 // IdHash returns an 8-byte truncated SHA-256 of a 32-byte event ID.
44 func IdHash(id []byte) (buf []byte) {
45 h := sha256.Sum256(id)
46 // Copy out of the local array; h[:HashLen] aliases this frame.
47 buf = []byte{:HashLen}
48 copy(buf, h[:HashLen])
49 return
50 }
51
52 // PubHash returns an 8-byte truncated SHA-256 of a 32-byte pubkey.
53 func PubHash(pub []byte) (buf []byte) {
54 h := sha256.Sum256(pub)
55 buf = []byte{:HashLen}
56 copy(buf, h[:HashLen])
57 return
58 }
59
60 // Ident returns an 8-byte truncated SHA-256 of an arbitrary value (tag value, word).
61 func Ident(val []byte) (buf []byte) {
62 h := sha256.Sum256(val)
63 buf = []byte{:HashLen}
64 copy(buf, h[:HashLen])
65 return
66 }
67
68 // Timestamp writes a unix timestamp as 8-byte big-endian into dst.
69 func PutTimestamp(dst []byte, ts int64) {
70 binary.BigEndian().PutUint64(dst, uint64(ts))
71 }
72
73 // GetTimestamp reads an 8-byte big-endian timestamp from src.
74 func GetTimestamp(src []byte) (n int64) {
75 return int64(binary.BigEndian().Uint64(src))
76 }
77
78 // AppendTimestamp appends an 8-byte big-endian timestamp to dst.
79 func AppendTimestamp(dst []byte, ts int64) (buf []byte) {
80 var buf [8]byte
81 binary.BigEndian().PutUint64(buf[:], uint64(ts))
82 return dst | buf[:]
83 }
84
85 // PutKind writes a kind as 2-byte big-endian into dst.
86 func PutKind(dst []byte, k uint16) {
87 binary.BigEndian().PutUint16(dst, k)
88 }
89
90 // GetKind reads a 2-byte big-endian kind from src.
91 func GetKind(src []byte) (n uint16) {
92 return binary.BigEndian().Uint16(src)
93 }
94
95 // AppendKind appends a 2-byte big-endian kind to dst.
96 func AppendKind(dst []byte, k uint16) (buf []byte) {
97 return push(dst, byte(k>>8), byte(k))
98 }
99