leb.io/aeshash@v0.1.2/aeshash.go (about)

     1  package aeshash
     2  
     3  import (
     4  	_ "unsafe"
     5  
     6  	"leb.io/hashland/nhash"
     7  )
     8  
     9  const hashRandomBytes = 32 // used in asm_{386,amd64}.s
    10  var masks [32]uint64
    11  var shifts [32]uint64
    12  var aeskeysched [hashRandomBytes]byte // this is really 2 x 128 bit round keys
    13  var aesdebug [hashRandomBytes]byte
    14  
    15  func aeshashbody()
    16  
    17  // Use these functions for higest speed
    18  func Hash(b []byte, seed uint64) uint64
    19  func HashStr(s string, seed uint64) uint64
    20  func Hash64(v uint64, s uint64) uint64
    21  func Hash32(v uint32, s uint64) uint64
    22  
    23  func init() {
    24  	p := aeskeysched[:]
    25  	p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7] = 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8
    26  	p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] = 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10
    27  	p[16], p[17], p[18], p[19], p[20], p[21], p[22], p[23] = 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18
    28  	p[24], p[25], p[26], p[27], p[28], p[29], p[30], p[31] = 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0xFF
    29  	p = aesdebug[:]
    30  	p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7] = 0xFF, 0, 0, 0, 0, 0, 0, 0xFE
    31  	p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] = 0xFD, 0, 0, 0, 0, 0, 0, 0xFC
    32  }
    33  
    34  //
    35  type State struct {
    36  	hash uint64
    37  	seed uint64
    38  	clen int
    39  	tail []byte
    40  }
    41  
    42  func n(seed uint64) *State {
    43  	s := new(State)
    44  	s.seed = seed
    45  	s.Reset()
    46  	return s
    47  }
    48  
    49  // New returns state used for a aeshash.
    50  func New(seed uint64) nhash.Hash64 {
    51  	s := n(seed)
    52  	return s
    53  }
    54  
    55  // Size returns the size of the resulting hash.
    56  func (s *State) Size() int { return 8 }
    57  
    58  // BlockSize returns the blocksize of the hash which in this case is 1 byte.
    59  func (s *State) BlockSize() int { return 1 }
    60  
    61  // NumSeedBytes returns the maximum number of seed bypes required. In this case 2 x 32
    62  func (s *State) NumSeedBytes() int {
    63  	return 8
    64  }
    65  
    66  // HashSizeInBits returns the number of bits the hash function outputs.
    67  func (s *State) HashSizeInBits() int {
    68  	return 64
    69  }
    70  
    71  // Reset the hash state.
    72  func (s *State) Reset() {
    73  	s.hash = 0
    74  	s.clen = 0
    75  	s.tail = nil
    76  }
    77  
    78  // Write accepts a byte stream p used for calculating the hash. For now this call is lazy and the actual hash calculations take place in Sum() and Sum32().
    79  func (s *State) Write(p []byte) (nn int, err error) {
    80  	l := len(p)
    81  	s.clen += l
    82  	s.tail = append(s.tail, p...)
    83  	return l, nil
    84  }
    85  
    86  // Write64 accepts a uint64 stream p used for calculating the hash. For now this call is lazy and the actual hash calculations take place in Sum() and Sum32().
    87  func (s *State) Write64(h uint64) (err error) {
    88  	s.clen += 8
    89  	s.tail = append(s.tail, byte(h>>56), byte(h>>48), byte(h>>40), byte(h>>32), byte(h>>24), byte(h>>16), byte(h>>8), byte(h))
    90  	return nil
    91  }
    92  
    93  // Sum returns the current hash as a byte slice.
    94  func (s *State) Sum(b []byte) []byte {
    95  	s.hash = Hash(s.tail, s.seed)
    96  	h := s.hash
    97  	return append(b, byte(h>>56), byte(h>>48), byte(h>>40), byte(h>>32), byte(h>>24), byte(h>>16), byte(h>>8), byte(h))
    98  }
    99  
   100  // Sum64 returns the current hash as a 64 bit unsigned type.
   101  func (s *State) Sum64() uint64 {
   102  	s.hash = Hash(s.tail, s.seed)
   103  	return s.hash
   104  }