Commit 992a11b8 authored by Russ Cox's avatar Russ Cox

crypto: housekeeping

Rename _Block to block, don't bother making it compute count.
Add benchmarks.

R=agl, agl
CC=golang-dev
https://golang.org/cl/6243053
parent 14ad4114
...@@ -186,15 +186,14 @@ import ( ...@@ -186,15 +186,14 @@ import (
} }
{{end}} {{end}}
func _Block(dig *digest, p []byte) int { func block(dig *digest, p []byte) {
a := dig.s[0] a := dig.s[0]
b := dig.s[1] b := dig.s[1]
c := dig.s[2] c := dig.s[2]
d := dig.s[3] d := dig.s[3]
n := 0
var X *[16]uint32 var X *[16]uint32
var xbuf [16]uint32 var xbuf [16]uint32
for len(p) >= _Chunk { for len(p) >= chunk {
aa, bb, cc, dd := a, b, c, d aa, bb, cc, dd := a, b, c, d
// This is a constant condition - it is not evaluated on each iteration. // This is a constant condition - it is not evaluated on each iteration.
...@@ -288,14 +287,12 @@ func _Block(dig *digest, p []byte) int { ...@@ -288,14 +287,12 @@ func _Block(dig *digest, p []byte) int {
c += cc c += cc
d += dd d += dd
p = p[_Chunk:] p = p[chunk:]
n += _Chunk
} }
dig.s[0] = a dig.s[0] = a
dig.s[1] = b dig.s[1] = b
dig.s[2] = c dig.s[2] = c
dig.s[3] = d dig.s[3] = d
return n
} }
` `
...@@ -21,26 +21,26 @@ const Size = 16 ...@@ -21,26 +21,26 @@ const Size = 16
const BlockSize = 64 const BlockSize = 64
const ( const (
_Chunk = 64 chunk = 64
_Init0 = 0x67452301 init0 = 0x67452301
_Init1 = 0xEFCDAB89 init1 = 0xEFCDAB89
_Init2 = 0x98BADCFE init2 = 0x98BADCFE
_Init3 = 0x10325476 init3 = 0x10325476
) )
// digest represents the partial evaluation of a checksum. // digest represents the partial evaluation of a checksum.
type digest struct { type digest struct {
s [4]uint32 s [4]uint32
x [_Chunk]byte x [chunk]byte
nx int nx int
len uint64 len uint64
} }
func (d *digest) Reset() { func (d *digest) Reset() {
d.s[0] = _Init0 d.s[0] = init0
d.s[1] = _Init1 d.s[1] = init1
d.s[2] = _Init2 d.s[2] = init2
d.s[3] = _Init3 d.s[3] = init3
d.nx = 0 d.nx = 0
d.len = 0 d.len = 0
} }
...@@ -61,21 +61,24 @@ func (d *digest) Write(p []byte) (nn int, err error) { ...@@ -61,21 +61,24 @@ func (d *digest) Write(p []byte) (nn int, err error) {
d.len += uint64(nn) d.len += uint64(nn)
if d.nx > 0 { if d.nx > 0 {
n := len(p) n := len(p)
if n > _Chunk-d.nx { if n > chunk-d.nx {
n = _Chunk - d.nx n = chunk - d.nx
} }
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
d.x[d.nx+i] = p[i] d.x[d.nx+i] = p[i]
} }
d.nx += n d.nx += n
if d.nx == _Chunk { if d.nx == chunk {
_Block(d, d.x[0:]) block(d, d.x[0:chunk])
d.nx = 0 d.nx = 0
} }
p = p[n:] p = p[n:]
} }
n := _Block(d, p) if len(p) >= chunk {
n := len(p) &^ (chunk - 1)
block(d, p[:n])
p = p[n:] p = p[n:]
}
if len(p) > 0 { if len(p) > 0 {
d.nx = copy(d.x[:], p) d.nx = copy(d.x[:], p)
} }
......
...@@ -5,15 +5,14 @@ import ( ...@@ -5,15 +5,14 @@ import (
"unsafe" "unsafe"
) )
func _Block(dig *digest, p []byte) int { func block(dig *digest, p []byte) {
a := dig.s[0] a := dig.s[0]
b := dig.s[1] b := dig.s[1]
c := dig.s[2] c := dig.s[2]
d := dig.s[3] d := dig.s[3]
n := 0
var X *[16]uint32 var X *[16]uint32
var xbuf [16]uint32 var xbuf [16]uint32
for len(p) >= _Chunk { for len(p) >= chunk {
aa, bb, cc, dd := a, b, c, d aa, bb, cc, dd := a, b, c, d
// This is a constant condition - it is not evaluated on each iteration. // This is a constant condition - it is not evaluated on each iteration.
...@@ -237,13 +236,11 @@ func _Block(dig *digest, p []byte) int { ...@@ -237,13 +236,11 @@ func _Block(dig *digest, p []byte) int {
c += cc c += cc
d += dd d += dd
p = p[_Chunk:] p = p[chunk:]
n += _Chunk
} }
dig.s[0] = a dig.s[0] = a
dig.s[1] = b dig.s[1] = b
dig.s[2] = c dig.s[2] = c
dig.s[3] = d dig.s[3] = d
return n
} }
...@@ -21,28 +21,28 @@ const Size = 20 ...@@ -21,28 +21,28 @@ const Size = 20
const BlockSize = 64 const BlockSize = 64
const ( const (
_Chunk = 64 chunk = 64
_Init0 = 0x67452301 init0 = 0x67452301
_Init1 = 0xEFCDAB89 init1 = 0xEFCDAB89
_Init2 = 0x98BADCFE init2 = 0x98BADCFE
_Init3 = 0x10325476 init3 = 0x10325476
_Init4 = 0xC3D2E1F0 init4 = 0xC3D2E1F0
) )
// digest represents the partial evaluation of a checksum. // digest represents the partial evaluation of a checksum.
type digest struct { type digest struct {
h [5]uint32 h [5]uint32
x [_Chunk]byte x [chunk]byte
nx int nx int
len uint64 len uint64
} }
func (d *digest) Reset() { func (d *digest) Reset() {
d.h[0] = _Init0 d.h[0] = init0
d.h[1] = _Init1 d.h[1] = init1
d.h[2] = _Init2 d.h[2] = init2
d.h[3] = _Init3 d.h[3] = init3
d.h[4] = _Init4 d.h[4] = init4
d.nx = 0 d.nx = 0
d.len = 0 d.len = 0
} }
...@@ -63,21 +63,24 @@ func (d *digest) Write(p []byte) (nn int, err error) { ...@@ -63,21 +63,24 @@ func (d *digest) Write(p []byte) (nn int, err error) {
d.len += uint64(nn) d.len += uint64(nn)
if d.nx > 0 { if d.nx > 0 {
n := len(p) n := len(p)
if n > _Chunk-d.nx { if n > chunk-d.nx {
n = _Chunk - d.nx n = chunk - d.nx
} }
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
d.x[d.nx+i] = p[i] d.x[d.nx+i] = p[i]
} }
d.nx += n d.nx += n
if d.nx == _Chunk { if d.nx == chunk {
_Block(d, d.x[0:]) block(d, d.x[0:])
d.nx = 0 d.nx = 0
} }
p = p[n:] p = p[n:]
} }
n := _Block(d, p) if len(p) >= chunk {
n := len(p) &^ (chunk - 1)
block(d, p[:n])
p = p[n:] p = p[n:]
}
if len(p) > 0 { if len(p) > 0 {
d.nx = copy(d.x[:], p) d.nx = copy(d.x[:], p)
} }
......
...@@ -79,3 +79,28 @@ func ExampleNew() { ...@@ -79,3 +79,28 @@ func ExampleNew() {
fmt.Printf("% x", h.Sum(nil)) fmt.Printf("% x", h.Sum(nil))
// Output: 59 7f 6a 54 00 10 f9 4c 15 d7 18 06 a9 9a 2c 87 10 e7 47 bd // Output: 59 7f 6a 54 00 10 f9 4c 15 d7 18 06 a9 9a 2c 87 10 e7 47 bd
} }
var bench = sha1.New()
var buf = makeBuf()
func makeBuf() []byte {
b := make([]byte, 8<<10)
for i := range b {
b[i] = byte(i)
}
return b
}
func BenchmarkHash1K(b *testing.B) {
b.SetBytes(1024)
for i := 0; i < b.N; i++ {
bench.Write(buf[:1024])
}
}
func BenchmarkHash8K(b *testing.B) {
b.SetBytes(int64(len(buf)))
for i := 0; i < b.N; i++ {
bench.Write(buf)
}
}
...@@ -15,12 +15,11 @@ const ( ...@@ -15,12 +15,11 @@ const (
_K3 = 0xCA62C1D6 _K3 = 0xCA62C1D6
) )
func _Block(dig *digest, p []byte) int { func block(dig *digest, p []byte) {
var w [80]uint32 var w [80]uint32
n := 0
h0, h1, h2, h3, h4 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4] h0, h1, h2, h3, h4 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4]
for len(p) >= _Chunk { for len(p) >= chunk {
// Can interlace the computation of w with the // Can interlace the computation of w with the
// rounds below if needed for speed. // rounds below if needed for speed.
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
...@@ -72,10 +71,8 @@ func _Block(dig *digest, p []byte) int { ...@@ -72,10 +71,8 @@ func _Block(dig *digest, p []byte) int {
h3 += d h3 += d
h4 += e h4 += e
p = p[_Chunk:] p = p[chunk:]
n += _Chunk
} }
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4] = h0, h1, h2, h3, h4 dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4] = h0, h1, h2, h3, h4
return n
} }
...@@ -26,29 +26,29 @@ const Size224 = 28 ...@@ -26,29 +26,29 @@ const Size224 = 28
const BlockSize = 64 const BlockSize = 64
const ( const (
_Chunk = 64 chunk = 64
_Init0 = 0x6A09E667 init0 = 0x6A09E667
_Init1 = 0xBB67AE85 init1 = 0xBB67AE85
_Init2 = 0x3C6EF372 init2 = 0x3C6EF372
_Init3 = 0xA54FF53A init3 = 0xA54FF53A
_Init4 = 0x510E527F init4 = 0x510E527F
_Init5 = 0x9B05688C init5 = 0x9B05688C
_Init6 = 0x1F83D9AB init6 = 0x1F83D9AB
_Init7 = 0x5BE0CD19 init7 = 0x5BE0CD19
_Init0_224 = 0xC1059ED8 init0_224 = 0xC1059ED8
_Init1_224 = 0x367CD507 init1_224 = 0x367CD507
_Init2_224 = 0x3070DD17 init2_224 = 0x3070DD17
_Init3_224 = 0xF70E5939 init3_224 = 0xF70E5939
_Init4_224 = 0xFFC00B31 init4_224 = 0xFFC00B31
_Init5_224 = 0x68581511 init5_224 = 0x68581511
_Init6_224 = 0x64F98FA7 init6_224 = 0x64F98FA7
_Init7_224 = 0xBEFA4FA4 init7_224 = 0xBEFA4FA4
) )
// digest represents the partial evaluation of a checksum. // digest represents the partial evaluation of a checksum.
type digest struct { type digest struct {
h [8]uint32 h [8]uint32
x [_Chunk]byte x [chunk]byte
nx int nx int
len uint64 len uint64
is224 bool // mark if this digest is SHA-224 is224 bool // mark if this digest is SHA-224
...@@ -56,23 +56,23 @@ type digest struct { ...@@ -56,23 +56,23 @@ type digest struct {
func (d *digest) Reset() { func (d *digest) Reset() {
if !d.is224 { if !d.is224 {
d.h[0] = _Init0 d.h[0] = init0
d.h[1] = _Init1 d.h[1] = init1
d.h[2] = _Init2 d.h[2] = init2
d.h[3] = _Init3 d.h[3] = init3
d.h[4] = _Init4 d.h[4] = init4
d.h[5] = _Init5 d.h[5] = init5
d.h[6] = _Init6 d.h[6] = init6
d.h[7] = _Init7 d.h[7] = init7
} else { } else {
d.h[0] = _Init0_224 d.h[0] = init0_224
d.h[1] = _Init1_224 d.h[1] = init1_224
d.h[2] = _Init2_224 d.h[2] = init2_224
d.h[3] = _Init3_224 d.h[3] = init3_224
d.h[4] = _Init4_224 d.h[4] = init4_224
d.h[5] = _Init5_224 d.h[5] = init5_224
d.h[6] = _Init6_224 d.h[6] = init6_224
d.h[7] = _Init7_224 d.h[7] = init7_224
} }
d.nx = 0 d.nx = 0
d.len = 0 d.len = 0
...@@ -107,21 +107,24 @@ func (d *digest) Write(p []byte) (nn int, err error) { ...@@ -107,21 +107,24 @@ func (d *digest) Write(p []byte) (nn int, err error) {
d.len += uint64(nn) d.len += uint64(nn)
if d.nx > 0 { if d.nx > 0 {
n := len(p) n := len(p)
if n > _Chunk-d.nx { if n > chunk-d.nx {
n = _Chunk - d.nx n = chunk - d.nx
} }
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
d.x[d.nx+i] = p[i] d.x[d.nx+i] = p[i]
} }
d.nx += n d.nx += n
if d.nx == _Chunk { if d.nx == chunk {
_Block(d, d.x[0:]) block(d, d.x[0:])
d.nx = 0 d.nx = 0
} }
p = p[n:] p = p[n:]
} }
n := _Block(d, p) if len(p) >= chunk {
n := len(p) &^ (chunk - 1)
block(d, p[:n])
p = p[n:] p = p[n:]
}
if len(p) > 0 { if len(p) > 0 {
d.nx = copy(d.x[:], p) d.nx = copy(d.x[:], p)
} }
......
...@@ -123,3 +123,28 @@ func TestGolden(t *testing.T) { ...@@ -123,3 +123,28 @@ func TestGolden(t *testing.T) {
} }
} }
} }
var bench = New()
var buf = makeBuf()
func makeBuf() []byte {
b := make([]byte, 8<<10)
for i := range b {
b[i] = byte(i)
}
return b
}
func BenchmarkHash1K(b *testing.B) {
b.SetBytes(1024)
for i := 0; i < b.N; i++ {
bench.Write(buf[:1024])
}
}
func BenchmarkHash8K(b *testing.B) {
b.SetBytes(int64(len(buf)))
for i := 0; i < b.N; i++ {
bench.Write(buf)
}
}
...@@ -75,11 +75,10 @@ var _K = []uint32{ ...@@ -75,11 +75,10 @@ var _K = []uint32{
0xc67178f2, 0xc67178f2,
} }
func _Block(dig *digest, p []byte) int { func block(dig *digest, p []byte) {
var w [64]uint32 var w [64]uint32
n := 0
h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]
for len(p) >= _Chunk { for len(p) >= chunk {
// Can interlace the computation of w with the // Can interlace the computation of w with the
// rounds below if needed for speed. // rounds below if needed for speed.
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
...@@ -120,10 +119,8 @@ func _Block(dig *digest, p []byte) int { ...@@ -120,10 +119,8 @@ func _Block(dig *digest, p []byte) int {
h6 += g h6 += g
h7 += h h7 += h
p = p[_Chunk:] p = p[chunk:]
n += _Chunk
} }
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h0, h1, h2, h3, h4, h5, h6, h7 dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h0, h1, h2, h3, h4, h5, h6, h7
return n
} }
...@@ -26,29 +26,29 @@ const Size384 = 48 ...@@ -26,29 +26,29 @@ const Size384 = 48
const BlockSize = 128 const BlockSize = 128
const ( const (
_Chunk = 128 chunk = 128
_Init0 = 0x6a09e667f3bcc908 init0 = 0x6a09e667f3bcc908
_Init1 = 0xbb67ae8584caa73b init1 = 0xbb67ae8584caa73b
_Init2 = 0x3c6ef372fe94f82b init2 = 0x3c6ef372fe94f82b
_Init3 = 0xa54ff53a5f1d36f1 init3 = 0xa54ff53a5f1d36f1
_Init4 = 0x510e527fade682d1 init4 = 0x510e527fade682d1
_Init5 = 0x9b05688c2b3e6c1f init5 = 0x9b05688c2b3e6c1f
_Init6 = 0x1f83d9abfb41bd6b init6 = 0x1f83d9abfb41bd6b
_Init7 = 0x5be0cd19137e2179 init7 = 0x5be0cd19137e2179
_Init0_384 = 0xcbbb9d5dc1059ed8 init0_384 = 0xcbbb9d5dc1059ed8
_Init1_384 = 0x629a292a367cd507 init1_384 = 0x629a292a367cd507
_Init2_384 = 0x9159015a3070dd17 init2_384 = 0x9159015a3070dd17
_Init3_384 = 0x152fecd8f70e5939 init3_384 = 0x152fecd8f70e5939
_Init4_384 = 0x67332667ffc00b31 init4_384 = 0x67332667ffc00b31
_Init5_384 = 0x8eb44a8768581511 init5_384 = 0x8eb44a8768581511
_Init6_384 = 0xdb0c2e0d64f98fa7 init6_384 = 0xdb0c2e0d64f98fa7
_Init7_384 = 0x47b5481dbefa4fa4 init7_384 = 0x47b5481dbefa4fa4
) )
// digest represents the partial evaluation of a checksum. // digest represents the partial evaluation of a checksum.
type digest struct { type digest struct {
h [8]uint64 h [8]uint64
x [_Chunk]byte x [chunk]byte
nx int nx int
len uint64 len uint64
is384 bool // mark if this digest is SHA-384 is384 bool // mark if this digest is SHA-384
...@@ -56,23 +56,23 @@ type digest struct { ...@@ -56,23 +56,23 @@ type digest struct {
func (d *digest) Reset() { func (d *digest) Reset() {
if !d.is384 { if !d.is384 {
d.h[0] = _Init0 d.h[0] = init0
d.h[1] = _Init1 d.h[1] = init1
d.h[2] = _Init2 d.h[2] = init2
d.h[3] = _Init3 d.h[3] = init3
d.h[4] = _Init4 d.h[4] = init4
d.h[5] = _Init5 d.h[5] = init5
d.h[6] = _Init6 d.h[6] = init6
d.h[7] = _Init7 d.h[7] = init7
} else { } else {
d.h[0] = _Init0_384 d.h[0] = init0_384
d.h[1] = _Init1_384 d.h[1] = init1_384
d.h[2] = _Init2_384 d.h[2] = init2_384
d.h[3] = _Init3_384 d.h[3] = init3_384
d.h[4] = _Init4_384 d.h[4] = init4_384
d.h[5] = _Init5_384 d.h[5] = init5_384
d.h[6] = _Init6_384 d.h[6] = init6_384
d.h[7] = _Init7_384 d.h[7] = init7_384
} }
d.nx = 0 d.nx = 0
d.len = 0 d.len = 0
...@@ -107,21 +107,24 @@ func (d *digest) Write(p []byte) (nn int, err error) { ...@@ -107,21 +107,24 @@ func (d *digest) Write(p []byte) (nn int, err error) {
d.len += uint64(nn) d.len += uint64(nn)
if d.nx > 0 { if d.nx > 0 {
n := len(p) n := len(p)
if n > _Chunk-d.nx { if n > chunk-d.nx {
n = _Chunk - d.nx n = chunk - d.nx
} }
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
d.x[d.nx+i] = p[i] d.x[d.nx+i] = p[i]
} }
d.nx += n d.nx += n
if d.nx == _Chunk { if d.nx == chunk {
_Block(d, d.x[0:]) block(d, d.x[0:])
d.nx = 0 d.nx = 0
} }
p = p[n:] p = p[n:]
} }
n := _Block(d, p) if len(p) >= chunk {
n := len(p) &^ (chunk - 1)
block(d, p[:n])
p = p[n:] p = p[n:]
}
if len(p) > 0 { if len(p) > 0 {
d.nx = copy(d.x[:], p) d.nx = copy(d.x[:], p)
} }
......
...@@ -123,3 +123,28 @@ func TestGolden(t *testing.T) { ...@@ -123,3 +123,28 @@ func TestGolden(t *testing.T) {
} }
} }
} }
var bench = New()
var buf = makeBuf()
func makeBuf() []byte {
b := make([]byte, 8<<10)
for i := range b {
b[i] = byte(i)
}
return b
}
func BenchmarkHash1K(b *testing.B) {
b.SetBytes(1024)
for i := 0; i < b.N; i++ {
bench.Write(buf[:1024])
}
}
func BenchmarkHash8K(b *testing.B) {
b.SetBytes(int64(len(buf)))
for i := 0; i < b.N; i++ {
bench.Write(buf)
}
}
...@@ -91,11 +91,10 @@ var _K = []uint64{ ...@@ -91,11 +91,10 @@ var _K = []uint64{
0x6c44198c4a475817, 0x6c44198c4a475817,
} }
func _Block(dig *digest, p []byte) int { func block(dig *digest, p []byte) {
var w [80]uint64 var w [80]uint64
n := 0
h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]
for len(p) >= _Chunk { for len(p) >= chunk {
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
j := i * 8 j := i * 8
w[i] = uint64(p[j])<<56 | uint64(p[j+1])<<48 | uint64(p[j+2])<<40 | uint64(p[j+3])<<32 | w[i] = uint64(p[j])<<56 | uint64(p[j+1])<<48 | uint64(p[j+2])<<40 | uint64(p[j+3])<<32 |
...@@ -135,10 +134,8 @@ func _Block(dig *digest, p []byte) int { ...@@ -135,10 +134,8 @@ func _Block(dig *digest, p []byte) int {
h6 += g h6 += g
h7 += h h7 += h
p = p[_Chunk:] p = p[chunk:]
n += _Chunk
} }
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h0, h1, h2, h3, h4, h5, h6, h7 dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h0, h1, h2, h3, h4, h5, h6, h7
return n
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment