]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/tls, crypto/aes: remove allocations when Writing & Reading
authorBrad Fitzpatrick <bradfitz@golang.org>
Thu, 12 Nov 2015 14:09:03 +0000 (14:09 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Sat, 14 Nov 2015 13:12:47 +0000 (13:12 +0000)
benchmark          old ns/op     new ns/op     delta
BenchmarkTLS-4     8571          7938          -7.39%

benchmark          old MB/s     new MB/s     speedup
BenchmarkTLS-4     119.46       128.98       1.08x

benchmark          old allocs     new allocs     delta
BenchmarkTLS-4     8              0              -100.00%

benchmark          old bytes     new bytes     delta
BenchmarkTLS-4     128           0             -100.00%

On:

func BenchmarkTLS(b *testing.B) {
        b.ReportAllocs()
        b.SetBytes(1024)
        ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                io.Copy(ioutil.Discard, r.Body)
        }))
        defer ts.Close()
        buf := make([]byte, 1024)
        for i := range buf {
                buf[i] = byte(i)
        }
        c, err := tls.Dial("tcp", ts.Listener.Addr().String(), &tls.Config{
                InsecureSkipVerify: true,
        })
        if err != nil {
                b.Fatal(err)
        }
        defer c.Close()
        clen := int64(b.N) * 1024
        if _, err := c.Write([]byte(
            "POST / HTTP/1.1\r\nHost: foo\r\nContent-Length: " +
            fmt.Sprint(clen) + "\r\n\r\n")); err != nil {
                b.Fatal(err)
        }
        b.ResetTimer()
        for i := 0; i < b.N; i++ {
                if _, err := c.Write(buf); err != nil {
                        b.Fatal(err)
                }
        }
}

Change-Id: I206e7e2118b97148f9751b740d8470895634d3f5
Reviewed-on: https://go-review.googlesource.com/16828
Reviewed-by: Adam Langley <agl@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/crypto/aes/aes_gcm.go
src/crypto/tls/conn.go

index fbb17d82c9c9eb892eee18f1f6a34517036b6e25..13775789509041d475ac2e7809bab9c18a4784be 100644 (file)
@@ -14,11 +14,23 @@ import (
 
 // The following functions are defined in gcm_amd64.s.
 func hasGCMAsm() bool
+
+//go:noescape
 func aesEncBlock(dst, src *[16]byte, ks []uint32)
+
+//go:noescape
 func gcmAesInit(productTable *[256]byte, ks []uint32)
+
+//go:noescape
 func gcmAesData(productTable *[256]byte, data []byte, T *[16]byte)
+
+//go:noescape
 func gcmAesEnc(productTable *[256]byte, dst, src []byte, ctr, T *[16]byte, ks []uint32)
+
+//go:noescape
 func gcmAesDec(productTable *[256]byte, dst, src []byte, ctr, T *[16]byte, ks []uint32)
+
+//go:noescape
 func gcmAesFinish(productTable *[256]byte, tagMask, T *[16]byte, pLen, dLen uint64)
 
 const (
index e3dcf15400ce18a6c3985ba02239fb013910e78e..7638bbc6a9934d9ddc316a03e6196bb27851c17b 100644 (file)
@@ -98,12 +98,13 @@ func (c *Conn) SetWriteDeadline(t time.Time) error {
 type halfConn struct {
        sync.Mutex
 
-       err     error       // first permanent error
-       version uint16      // protocol version
-       cipher  interface{} // cipher algorithm
-       mac     macFunction
-       seq     [8]byte // 64-bit sequence number
-       bfree   *block  // list of free blocks
+       err            error       // first permanent error
+       version        uint16      // protocol version
+       cipher         interface{} // cipher algorithm
+       mac            macFunction
+       seq            [8]byte  // 64-bit sequence number
+       bfree          *block   // list of free blocks
+       additionalData [13]byte // to avoid allocs; interface method args escape
 
        nextCipher interface{} // next encryption state
        nextMac    macFunction // next MAC algorithm
@@ -262,14 +263,13 @@ func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert)
                        nonce := payload[:8]
                        payload = payload[8:]
 
-                       var additionalData [13]byte
-                       copy(additionalData[:], hc.seq[:])
-                       copy(additionalData[8:], b.data[:3])
+                       copy(hc.additionalData[:], hc.seq[:])
+                       copy(hc.additionalData[8:], b.data[:3])
                        n := len(payload) - c.Overhead()
-                       additionalData[11] = byte(n >> 8)
-                       additionalData[12] = byte(n)
+                       hc.additionalData[11] = byte(n >> 8)
+                       hc.additionalData[12] = byte(n)
                        var err error
-                       payload, err = c.Open(payload[:0], nonce, payload, additionalData[:])
+                       payload, err = c.Open(payload[:0], nonce, payload, hc.additionalData[:])
                        if err != nil {
                                return false, 0, alertBadRecordMAC
                        }
@@ -378,13 +378,12 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
                        payload := b.data[recordHeaderLen+explicitIVLen:]
                        payload = payload[:payloadLen]
 
-                       var additionalData [13]byte
-                       copy(additionalData[:], hc.seq[:])
-                       copy(additionalData[8:], b.data[:3])
-                       additionalData[11] = byte(payloadLen >> 8)
-                       additionalData[12] = byte(payloadLen)
+                       copy(hc.additionalData[:], hc.seq[:])
+                       copy(hc.additionalData[8:], b.data[:3])
+                       hc.additionalData[11] = byte(payloadLen >> 8)
+                       hc.additionalData[12] = byte(payloadLen)
 
-                       c.Seal(payload[:0], nonce, payload, additionalData[:])
+                       c.Seal(payload[:0], nonce, payload, hc.additionalData[:])
                case cbcMode:
                        blockSize := c.BlockSize()
                        if explicitIVLen > 0 {