github.com/gitbookio/syncgroup@v0.0.0-20181003125046-3e73b2e6a972/quickhash/aeshash/aeshash.go (about)

     1  package aeshash
     2  
     3  import _ "unsafe"
     4  
     5  // import "leb.io/hashland/nhash"
     6  
     7  var masks [32]uint64
     8  var shifts [32]uint64
     9  
    10  // used in asm_{386,amd64}.s
    11  const hashRandomBytes = 32
    12  
    13  // this is really 2 x 128 bit round keys
    14  var aeskeysched [hashRandomBytes]byte
    15  
    16  var aesdebug [hashRandomBytes]byte
    17  
    18  func aeshashbody()
    19  
    20  //func Hash(p unsafe.Pointer, s, h uintptr) uintptr
    21  //func HashStr(p string, s, h uintptr) uintptr
    22  func Hash(b []byte, seed uint64) uint64
    23  func HashStr(s string, seed uint64) uint64
    24  func Hash64(v uint64, s uint64) uint64
    25  func Hash32(v uint32, s uint64) uint64
    26  
    27  //func aeshash(p unsafe.Pointer, s, h uintptr) uintptr
    28  //func aeshash32(p unsafe.Pointer, s, h uintptr) uintptr
    29  //func aeshash64(p unsafe.Pointer, s, h uintptr) uintptr
    30  //func aeshashstr(p unsafe.Pointer, s, h uintptr) uintptr
    31  
    32  func init() {
    33  	p := aeskeysched[:]
    34  	p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7] = 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8
    35  	p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] = 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10
    36  	p[16], p[17], p[18], p[19], p[20], p[21], p[22], p[23] = 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18
    37  	p[24], p[25], p[26], p[27], p[28], p[29], p[30], p[31] = 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0xFF
    38  	p = aesdebug[:]
    39  	p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7] = 0xFF, 0, 0, 0, 0, 0, 0, 0xFE
    40  	p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15] = 0xFD, 0, 0, 0, 0, 0, 0, 0xFC
    41  }
    42  
    43  // Make sure interfaces are correctly implemented. Stolen from another implementation.
    44  // I did something similar in another package to verify the interface but didn't know you could elide the variable in a var.
    45  // What a cute wart it is.
    46  var (
    47  //_ hash.Hash   = new(Digest)
    48  // _ nhash.Hash64     = new(StateAES)
    49  // _ nhash.HashStream = new(StateAES)
    50  )
    51  
    52  type StateAES struct {
    53  	hash uint64
    54  	seed uint64
    55  	clen int
    56  	tail []byte
    57  }
    58  
    59  func NewAES(seed uint64) *StateAES {
    60  	s := new(StateAES)
    61  	s.seed = seed
    62  	s.Reset()
    63  	return s
    64  }
    65  
    66  // Return the size of the resulting hash.
    67  func (d *StateAES) Size() int { return 8 }
    68  
    69  // Return the blocksize of the hash which in this case is 1 byte.
    70  func (d *StateAES) BlockSize() int { return 1 }
    71  
    72  // Return the maximum number of seed bypes required. In this case 2 x 32
    73  func (d *StateAES) NumSeedBytes() int {
    74  	return 8
    75  }
    76  
    77  // Return the number of bits the hash function outputs.
    78  func (d *StateAES) HashSizeInBits() int {
    79  	return 64
    80  }
    81  
    82  // Reset the hash state.
    83  func (d *StateAES) Reset() {
    84  	d.hash = 0
    85  	d.clen = 0
    86  	d.tail = nil
    87  }
    88  
    89  // Accept 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().
    90  func (d *StateAES) Write(p []byte) (nn int, err error) {
    91  	l := len(p)
    92  	d.clen += l
    93  	d.tail = append(d.tail, p...)
    94  	return l, nil
    95  }
    96  
    97  func (d *StateAES) Write64(h uint64) (err error) {
    98  	d.clen += 8
    99  	d.tail = append(d.tail, byte(h>>56), byte(h>>48), byte(h>>40), byte(h>>32), byte(h>>24), byte(h>>16), byte(h>>8), byte(h))
   100  	return nil
   101  }
   102  
   103  // Return the current hash as a byte slice.
   104  func (d *StateAES) Sum(b []byte) []byte {
   105  	d.hash = Hash(d.tail, d.seed)
   106  	h := d.hash
   107  	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))
   108  }
   109  
   110  // Return the current hash as a 64 bit unsigned type.
   111  func (d *StateAES) Sum64() uint64 {
   112  	d.hash = Hash(d.tail, d.seed)
   113  	return d.hash
   114  }
   115  
   116  func (d *StateAES) Hash64(b []byte, seeds ...uint64) uint64 {
   117  	switch len(seeds) {
   118  	case 1:
   119  		d.seed = seeds[0]
   120  	}
   121  	d.hash = Hash(b, d.seed)
   122  	//fmt.Printf("pc=0x%08x, pb=0x%08x\n", d.pc, d.pb)
   123  	return d.hash
   124  }