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) 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) []byte {
  40  	return append(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) []byte {
  45  	h := sha256.Sum256(id)
  46  	return h[:HashLen]
  47  }
  48  
  49  // PubHash returns an 8-byte truncated SHA-256 of a 32-byte pubkey.
  50  func PubHash(pub []byte) []byte {
  51  	h := sha256.Sum256(pub)
  52  	return h[:HashLen]
  53  }
  54  
  55  // Ident returns an 8-byte truncated SHA-256 of an arbitrary value (tag value, word).
  56  func Ident(val []byte) []byte {
  57  	h := sha256.Sum256(val)
  58  	return h[:HashLen]
  59  }
  60  
  61  // Timestamp writes a unix timestamp as 8-byte big-endian into dst.
  62  func PutTimestamp(dst []byte, ts int64) {
  63  	binary.BigEndian.PutUint64(dst, uint64(ts))
  64  }
  65  
  66  // GetTimestamp reads an 8-byte big-endian timestamp from src.
  67  func GetTimestamp(src []byte) int64 {
  68  	return int64(binary.BigEndian.Uint64(src))
  69  }
  70  
  71  // AppendTimestamp appends an 8-byte big-endian timestamp to dst.
  72  func AppendTimestamp(dst []byte, ts int64) []byte {
  73  	var buf [8]byte
  74  	binary.BigEndian.PutUint64(buf[:], uint64(ts))
  75  	return append(dst, buf[:]...)
  76  }
  77  
  78  // PutKind writes a kind as 2-byte big-endian into dst.
  79  func PutKind(dst []byte, k uint16) {
  80  	binary.BigEndian.PutUint16(dst, k)
  81  }
  82  
  83  // GetKind reads a 2-byte big-endian kind from src.
  84  func GetKind(src []byte) uint16 {
  85  	return binary.BigEndian.Uint16(src)
  86  }
  87  
  88  // AppendKind appends a 2-byte big-endian kind to dst.
  89  func AppendKind(dst []byte, k uint16) []byte {
  90  	return append(dst, byte(k>>8), byte(k))
  91  }
  92