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