Created
December 22, 2015 23:40
-
-
Save FiloSottile/2235cbfff2c6a5979934 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2010 The Go Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style | |
// license that can be found in the LICENSE file. | |
package tls | |
import ( | |
"bytes" | |
"crypto/hmac" | |
"crypto/sha1" | |
"image/color" | |
"testing" | |
"github.com/gonum/plot" | |
"github.com/gonum/plot/plotter" | |
"github.com/gonum/plot/vg" | |
"github.com/gonum/plot/vg/draw" | |
) | |
func TestHMACSumTiming(t *testing.T) { | |
sumData := make(plotter.XYs, 70-45) | |
constData := make(plotter.XYs, 70-45) | |
data := []byte("01234567890123456789012345678901234567890123456789012345678901234567890123456789") | |
sumBuf := make([]byte, 0, 100) | |
for n := 45; n < 70; n++ { | |
var res1, res2 []byte | |
ns := testing.Benchmark(func(b *testing.B) { | |
h := hmac.New(newConstantTimeHash(sha1.New), make([]byte, 30)) | |
h.Write(data[:n]) | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
res1 = h.Sum(sumBuf) | |
} | |
}).NsPerOp() | |
t.Logf("ConstantTimeSum %d bytes: %d ns/op", n, ns) | |
constData[n-45].X = float64(n) | |
constData[n-45].Y = float64(ns) | |
ns = testing.Benchmark(func(b *testing.B) { | |
h := hmac.New(sha1.New, make([]byte, 30)) | |
h.Write(data[:n]) | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
res2 = h.Sum(sumBuf) | |
} | |
}).NsPerOp() | |
t.Logf("Sum %d bytes: %d ns/op", n, ns) | |
sumData[n-45].X = float64(n) | |
sumData[n-45].Y = float64(ns) | |
if !bytes.Equal(res1, res2) { | |
t.Errorf("different output at length %d", n) | |
} | |
} | |
p, err := plot.New() | |
if err != nil { | |
panic(err) | |
} | |
p.Title.Text = "Sum() timings" | |
p.X.Label.Text = "Buffer bytes" | |
p.Y.Label.Text = "ns" | |
s, err := plotter.NewScatter(sumData) | |
if err != nil { | |
panic(err) | |
} | |
c, err := plotter.NewScatter(constData) | |
if err != nil { | |
panic(err) | |
} | |
c.GlyphStyle.Shape = draw.PyramidGlyph{} | |
c.GlyphStyle.Color = color.RGBA{R: 255, A: 255} | |
p.Add(s, c) | |
if err := p.Save(7*vg.Inch, 5*vg.Inch, "sum.png"); err != nil { | |
panic(err) | |
} | |
} | |
func TestHMACTotalTiming(t *testing.T) { | |
sumData := make(plotter.XYs, 256) | |
constData := make(plotter.XYs, 256) | |
naiveData := make(plotter.XYs, 256) | |
data := []byte("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789") | |
sumBuf := make([]byte, 0, 100) | |
for n := 0; n < 256; n++ { | |
var res1, res2 []byte | |
ns := testing.Benchmark(func(b *testing.B) { | |
h := hmac.New(newConstantTimeHash(sha1.New), make([]byte, 30)) | |
for i := 0; i < b.N; i++ { | |
h.Reset() | |
h.Write(data[:len(data)-n]) | |
res1 = h.Sum(sumBuf) | |
h.Write(data[len(data)-n:]) | |
} | |
}).NsPerOp() | |
t.Logf("ConstantTimeHash %d bytes: %d ns/op", n, ns) | |
constData[n].X = float64(len(data) - n) | |
constData[n].Y = float64(ns) | |
ns = testing.Benchmark(func(b *testing.B) { | |
h := hmac.New(sha1.New, make([]byte, 30)) | |
for i := 0; i < b.N; i++ { | |
h.Reset() | |
h.Write(data[:len(data)-n]) | |
res2 = h.Sum(sumBuf) | |
} | |
}).NsPerOp() | |
t.Logf("Sum %d bytes: %d ns/op", n, ns) | |
sumData[n].X = float64(len(data) - n) | |
sumData[n].Y = float64(ns) | |
ns = testing.Benchmark(func(b *testing.B) { | |
h := hmac.New(sha1.New, make([]byte, 30)) | |
for i := 0; i < b.N; i++ { | |
h.Reset() | |
h.Write(data[:len(data)-n]) | |
res2 = h.Sum(sumBuf) | |
h.Write(data[len(data)-n:]) | |
} | |
}).NsPerOp() | |
t.Logf("Sum+Write %d bytes: %d ns/op", n, ns) | |
naiveData[n].X = float64(len(data) - n) | |
naiveData[n].Y = float64(ns) | |
if !bytes.Equal(res1, res2) { | |
t.Errorf("different output at length %d", n) | |
} | |
} | |
p, err := plot.New() | |
if err != nil { | |
panic(err) | |
} | |
p.Title.Text = "HMAC timings" | |
p.X.Label.Text = "First Write() bytes" | |
p.Y.Label.Text = "ns" | |
s, err := plotter.NewScatter(sumData) | |
if err != nil { | |
panic(err) | |
} | |
c, err := plotter.NewScatter(constData) | |
if err != nil { | |
panic(err) | |
} | |
c.GlyphStyle.Shape = draw.PyramidGlyph{} | |
c.GlyphStyle.Color = color.RGBA{R: 255, A: 255} | |
x, err := plotter.NewScatter(naiveData) | |
if err != nil { | |
panic(err) | |
} | |
x.GlyphStyle.Shape = draw.CrossGlyph{} | |
x.GlyphStyle.Color = color.RGBA{R: 255, A: 255} | |
p.Add(s, c, x) | |
if err := p.Save(297*vg.Millimeter, 210*vg.Millimeter, "hmac.png"); err != nil { | |
panic(err) | |
} | |
} | |
func TestDecryptTiming(t *testing.T) { | |
newData := make(plotter.XYs, 256) | |
// oldData := make(plotter.XYs, 256) | |
data := []byte("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789") | |
key := []byte("YELLOW SUBMARINE") | |
for n := 0; n < 256; n++ { | |
data[len(data)-1] = byte(n) | |
ns := testing.Benchmark(func(b *testing.B) { | |
hc := &halfConn{ | |
version: VersionTLS10, | |
cipher: cipherAES(key, key, true), | |
mac: macSHA1(VersionTLS10, key), | |
} | |
enc := make([]byte, len(data)) | |
cipherAES(key, key, false).(cbcMode).CryptBlocks(enc, data) | |
bl := &block{data: make([]byte, len(enc)+recordHeaderLen)} | |
b.ResetTimer() | |
for i := 0; i < b.N; i++ { | |
copy(bl.data[recordHeaderLen:], enc) | |
hc.decrypt(bl) | |
} | |
}).NsPerOp() | |
t.Logf("[NEW] Padding value %d: %d ns/op", n, ns) | |
newData[n].X = float64(n) | |
newData[n].Y = float64(ns) | |
// ns = testing.Benchmark(func(b *testing.B) { | |
// hc := &halfConn{ | |
// version: VersionTLS10, | |
// cipher: cipherAES(key, key, true), | |
// mac: tls10MAC{hmac.New(sha1.New, key)}, | |
// } | |
// enc := make([]byte, len(data)) | |
// cipherAES(key, key, false).(cbcMode).CryptBlocks(enc, data) | |
// bl := &block{data: make([]byte, len(enc)+recordHeaderLen)} | |
// b.ResetTimer() | |
// for i := 0; i < b.N; i++ { | |
// copy(bl.data[recordHeaderLen:], enc) | |
// hc.decryptOld(bl) | |
// } | |
// }).NsPerOp() | |
// t.Logf("[OLD] Padding value %d: %d ns/op", n, ns) | |
// oldData[n].X = float64(n) | |
// oldData[n].Y = float64(ns) | |
} | |
p, err := plot.New() | |
if err != nil { | |
panic(err) | |
} | |
p.Title.Text = "decrypt() timings" | |
p.X.Label.Text = "Padding value" | |
p.Y.Label.Text = "ns" | |
n, err := plotter.NewScatter(newData) | |
if err != nil { | |
panic(err) | |
} | |
n.GlyphStyle.Shape = draw.CrossGlyph{} | |
n.GlyphStyle.Color = color.RGBA{R: 255, A: 255} | |
// o, err := plotter.NewScatter(oldData) | |
// if err != nil { | |
// panic(err) | |
// } | |
p.Add(n) | |
if err := p.Save(297*vg.Millimeter, 210*vg.Millimeter, "decrypt.png"); err != nil { | |
panic(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment