]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/hmac: simplify implementation
authorDmitry Chestnykh <dchest@gmail.com>
Tue, 22 Mar 2016 15:41:11 +0000 (16:41 +0100)
committerAdam Langley <agl@golang.org>
Fri, 25 Mar 2016 06:24:00 +0000 (06:24 +0000)
Store already padded keys instead of storing key and padding it during
Reset and Sum. This simplifies code and makes Reset-Write-Sum sequences
faster, which helps /x/crypto/pbkdf2.

HMAC benchmark:

benchmark                    old ns/op     new ns/op     delta
BenchmarkHMACSHA256_1K-4     7669          7613          -0.73%
BenchmarkHMACSHA256_32-4     1880          1737          -7.61%

benchmark                    old MB/s     new MB/s     speedup
BenchmarkHMACSHA256_1K-4     133.52       134.50       1.01x
BenchmarkHMACSHA256_32-4     17.02        18.41        1.08x

PBKDF2 benchmark:

benchmark                       old ns/op     new ns/op     delta
BenchmarkPBKDF2HMACSHA256-4     1943196       1807699       -6.97%

Change-Id: I6697028370c226715ab477b0844951a83eb3488c
Reviewed-on: https://go-review.googlesource.com/21024
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
src/crypto/hmac/hmac.go
src/crypto/hmac/hmac_test.go

index 3b41cde0bd50f4684a84b7a89de274f53acafca1..a7481078388240a6b6ca86159d44022e06182092 100644 (file)
@@ -37,26 +37,16 @@ import (
 type hmac struct {
        size         int
        blocksize    int
-       key, tmp     []byte
+       opad, ipad   []byte
        outer, inner hash.Hash
 }
 
-func (h *hmac) tmpPad(xor byte) {
-       for i, k := range h.key {
-               h.tmp[i] = xor ^ k
-       }
-       for i := len(h.key); i < h.blocksize; i++ {
-               h.tmp[i] = xor
-       }
-}
-
 func (h *hmac) Sum(in []byte) []byte {
        origLen := len(in)
        in = h.inner.Sum(in)
-       h.tmpPad(0x5c)
-       copy(h.tmp[h.blocksize:], in[origLen:])
        h.outer.Reset()
-       h.outer.Write(h.tmp)
+       h.outer.Write(h.opad)
+       h.outer.Write(in[origLen:])
        return h.outer.Sum(in[:origLen])
 }
 
@@ -70,8 +60,7 @@ func (h *hmac) BlockSize() int { return h.blocksize }
 
 func (h *hmac) Reset() {
        h.inner.Reset()
-       h.tmpPad(0x36)
-       h.inner.Write(h.tmp[:h.blocksize])
+       h.inner.Write(h.ipad)
 }
 
 // New returns a new HMAC hash using the given hash.Hash type and key.
@@ -81,15 +70,22 @@ func New(h func() hash.Hash, key []byte) hash.Hash {
        hm.inner = h()
        hm.size = hm.inner.Size()
        hm.blocksize = hm.inner.BlockSize()
-       hm.tmp = make([]byte, hm.blocksize+hm.size)
+       hm.ipad = make([]byte, hm.blocksize)
+       hm.opad = make([]byte, hm.blocksize)
        if len(key) > hm.blocksize {
                // If key is too big, hash it.
                hm.outer.Write(key)
                key = hm.outer.Sum(nil)
        }
-       hm.key = make([]byte, len(key))
-       copy(hm.key, key)
-       hm.Reset()
+       copy(hm.ipad, key)
+       copy(hm.opad, key)
+       for i := range hm.ipad {
+               hm.ipad[i] ^= 0x36
+       }
+       for i := range hm.opad {
+               hm.opad[i] ^= 0x5c
+       }
+       hm.inner.Write(hm.ipad)
        return hm
 }
 
index e80b7e0baa0d01faf99ac4c24ccba306f4ab7666..aac9aa96a8ece496e4af4120ea556b51dbfdac34 100644 (file)
@@ -568,3 +568,29 @@ func TestEqual(t *testing.T) {
                t.Error("Equal accepted unequal slices")
        }
 }
+
+func BenchmarkHMACSHA256_1K(b *testing.B) {
+       key := make([]byte, 32)
+       buf := make([]byte, 1024)
+       h := New(sha256.New, key)
+       b.SetBytes(int64(len(buf)))
+       for i := 0; i < b.N; i++ {
+               h.Write(buf)
+               h.Reset()
+               mac := h.Sum(nil)
+               buf[0] = mac[0]
+       }
+}
+
+func BenchmarkHMACSHA256_32(b *testing.B) {
+       key := make([]byte, 32)
+       buf := make([]byte, 32)
+       h := New(sha256.New, key)
+       b.SetBytes(int64(len(buf)))
+       for i := 0; i < b.N; i++ {
+               h.Write(buf)
+               h.Reset()
+               mac := h.Sum(nil)
+               buf[0] = mac[0]
+       }
+}