]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/sha512: speed-up for very small blocks
authorIlya Tocar <ilya.tocar@intel.com>
Fri, 8 Dec 2017 20:59:55 +0000 (14:59 -0600)
committerFilippo Valsorda <hi@filippo.io>
Tue, 20 Feb 2018 23:44:12 +0000 (23:44 +0000)
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 <ilya.tocar@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <hi@filippo.io>
src/crypto/sha512/sha512.go

index b1999516ebd693780007cfcd2679bf1caaafc56f..9f2e60b5737e84c6dc799f688e79c573673952fe 100644 (file)
@@ -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