// Package serial provides the 5-byte uint40 serial type and truncated hash // types used by the store's index system. package serial import ( "crypto/sha256" "encoding/binary" ) const ( // Len is the byte length of a serial (5 bytes = 40 bits). Len = 5 // Max is the maximum serial value (2^40 - 1). Max uint64 = 1<<40 - 1 // HashLen is the byte length of truncated hashes used in index keys. HashLen = 8 ) // Put writes a uint64 as a 5-byte big-endian serial into dst. // dst must be at least 5 bytes. func Put(dst []byte, v uint64) { dst[0] = byte(v >> 32) dst[1] = byte(v >> 24) dst[2] = byte(v >> 16) dst[3] = byte(v >> 8) dst[4] = byte(v) } // Get reads a 5-byte big-endian serial from src and returns it as uint64. func Get(src []byte) uint64 { return uint64(src[0])<<32 | uint64(src[1])<<24 | uint64(src[2])<<16 | uint64(src[3])<<8 | uint64(src[4]) } // Append appends a 5-byte serial to dst. func Append(dst []byte, v uint64) []byte { return append(dst, byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) } // IdHash returns an 8-byte truncated SHA-256 of a 32-byte event ID. func IdHash(id []byte) []byte { h := sha256.Sum256(id) return h[:HashLen] } // PubHash returns an 8-byte truncated SHA-256 of a 32-byte pubkey. func PubHash(pub []byte) []byte { h := sha256.Sum256(pub) return h[:HashLen] } // Ident returns an 8-byte truncated SHA-256 of an arbitrary value (tag value, word). func Ident(val []byte) []byte { h := sha256.Sum256(val) return h[:HashLen] } // Timestamp writes a unix timestamp as 8-byte big-endian into dst. func PutTimestamp(dst []byte, ts int64) { binary.BigEndian.PutUint64(dst, uint64(ts)) } // GetTimestamp reads an 8-byte big-endian timestamp from src. func GetTimestamp(src []byte) int64 { return int64(binary.BigEndian.Uint64(src)) } // AppendTimestamp appends an 8-byte big-endian timestamp to dst. func AppendTimestamp(dst []byte, ts int64) []byte { var buf [8]byte binary.BigEndian.PutUint64(buf[:], uint64(ts)) return append(dst, buf[:]...) } // PutKind writes a kind as 2-byte big-endian into dst. func PutKind(dst []byte, k uint16) { binary.BigEndian.PutUint16(dst, k) } // GetKind reads a 2-byte big-endian kind from src. func GetKind(src []byte) uint16 { return binary.BigEndian.Uint16(src) } // AppendKind appends a 2-byte big-endian kind to dst. func AppendKind(dst []byte, k uint16) []byte { return append(dst, byte(k>>8), byte(k)) }