From: Ilya Tocar Date: Fri, 8 Dec 2017 20:59:55 +0000 (-0600) Subject: crypto/sha512: speed-up for very small blocks X-Git-Tag: go1.11beta1~1524 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=b43ebce59b0eabe10ea2a1950c7173ed029cd093;p=gostls13.git crypto/sha512: speed-up for very small blocks Similar to https://golang.org/cl/54391, but for sha512 name old time/op new time/op delta Hash8Bytes-8 289ns ± 1% 253ns ± 2% -12.59% (p=0.000 n=10+10) Hash1K-8 1.85µs ± 1% 1.82µs ± 1% -1.77% (p=0.000 n=9+10) Hash8K-8 12.7µs ± 2% 12.5µs ± 1% ~ (p=0.075 n=10+10) name old speed new speed delta Hash8Bytes-8 27.6MB/s ± 1% 31.6MB/s ± 2% +14.43% (p=0.000 n=10+10) Hash1K-8 554MB/s ± 1% 564MB/s ± 1% +1.81% (p=0.000 n=9+10) Hash8K-8 647MB/s ± 2% 653MB/s ± 1% ~ (p=0.075 n=10+10) Change-Id: I437668c96ad55f8dbb62c89c8fc3f433453b5330 Reviewed-on: https://go-review.googlesource.com/82996 Run-TryBot: Ilya Tocar TryBot-Result: Gobot Gobot Reviewed-by: Filippo Valsorda --- diff --git a/src/crypto/sha512/sha512.go b/src/crypto/sha512/sha512.go index b1999516eb..9f2e60b573 100644 --- a/src/crypto/sha512/sha512.go +++ b/src/crypto/sha512/sha512.go @@ -195,17 +195,21 @@ func (d *digest) UnmarshalBinary(b []byte) error { return nil } +func putUint64(x []byte, s uint64) { + _ = x[7] + x[0] = byte(s >> 56) + x[1] = byte(s >> 48) + x[2] = byte(s >> 40) + x[3] = byte(s >> 32) + x[4] = byte(s >> 24) + x[5] = byte(s >> 16) + x[6] = byte(s >> 8) + x[7] = byte(s) +} + func appendUint64(b []byte, x uint64) []byte { - a := [8]byte{ - byte(x >> 56), - byte(x >> 48), - byte(x >> 40), - byte(x >> 32), - byte(x >> 24), - byte(x >> 16), - byte(x >> 8), - byte(x), - } + var a [8]byte + putUint64(a[:], x) return append(b, a[:]...) } @@ -312,30 +316,24 @@ func (d *digest) checkSum() [Size]byte { // Length in bits. len <<= 3 - for i := uint(0); i < 16; i++ { - tmp[i] = byte(len >> (120 - 8*i)) - } + putUint64(tmp[0:], 0) // upper 64 bits are always zero, because len variable has type uint64 + putUint64(tmp[8:], len) d.Write(tmp[0:16]) if d.nx != 0 { panic("d.nx != 0") } - h := d.h[:] - if d.function == crypto.SHA384 { - h = d.h[:6] - } - var digest [Size]byte - for i, s := range h { - digest[i*8] = byte(s >> 56) - digest[i*8+1] = byte(s >> 48) - digest[i*8+2] = byte(s >> 40) - digest[i*8+3] = byte(s >> 32) - digest[i*8+4] = byte(s >> 24) - digest[i*8+5] = byte(s >> 16) - digest[i*8+6] = byte(s >> 8) - digest[i*8+7] = byte(s) + putUint64(digest[0:], d.h[0]) + putUint64(digest[8:], d.h[1]) + putUint64(digest[16:], d.h[2]) + putUint64(digest[24:], d.h[3]) + putUint64(digest[32:], d.h[4]) + putUint64(digest[40:], d.h[5]) + if d.function != crypto.SHA384 { + putUint64(digest[48:], d.h[6]) + putUint64(digest[56:], d.h[7]) } return digest