prometheus/vendor/github.com/dgryski/go-sip13/sip13.go

84 lines
1.6 KiB
Go

// +build !amd64 noasm
package sip13
import (
"math/bits"
"unsafe"
)
func Sum64(k0, k1 uint64, b []byte) uint64 {
return Sum64Str(k0, k1, unsafeB2S(b))
}
func readUint64(b string) uint64 {
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
}
func unsafeB2S(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
func Sum64Str(k0, k1 uint64, p string) uint64 {
var v0, v1, v2, v3 uint64
v0 = k0 ^ 0x736f6d6570736575
v1 = k1 ^ 0x646f72616e646f6d
v2 = k0 ^ 0x6c7967656e657261
v3 = k1 ^ 0x7465646279746573
b := uint64(len(p)) << 56
for len(p) >= 8 {
m := readUint64(p)
v3 ^= m
v0 += v1
v2 += v3
v1 = bits.RotateLeft64(v1, 13)
v3 = bits.RotateLeft64(v3, 16)
v1 ^= v0
v3 ^= v2
v0 = bits.RotateLeft64(v0, 32)
v2 += v1
v0 += v3
v1 = bits.RotateLeft64(v1, 17)
v3 = bits.RotateLeft64(v3, 21)
v1 ^= v2
v3 ^= v0
v2 = bits.RotateLeft64(v2, 32)
v0 ^= m
p = p[8:]
}
for _, c := range []byte(p) {
b = bits.RotateLeft64(b|uint64(c), 56)
}
m := bits.RotateLeft64(b, len(p)*8)
// last block with finalization
v3 ^= m
f := uint64(0xff)
for i := 0; i < 4; i++ {
v0 += v1
v2 += v3
v1 = bits.RotateLeft64(v1, 13)
v3 = bits.RotateLeft64(v3, 16)
v1 ^= v0
v3 ^= v2
v0 = bits.RotateLeft64(v0, 32)
v2 += v1
v0 += v3
v1 = bits.RotateLeft64(v1, 17)
v3 = bits.RotateLeft64(v3, 21)
v1 ^= v2
v3 ^= v0
v2 = bits.RotateLeft64(v2, 32)
v2 ^= f
v0 ^= m
m, f = 0, 0 // clear last block and finalization mixins
}
return v0 ^ v1 ^ v2 ^ v3
}