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 }