summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-01-19 10:50:04 -0800
committerRuss Cox <rsc@golang.org>2010-01-19 10:50:04 -0800
commitd0430f3303242f5c955af283b4592e3ce5760bfa (patch)
treebc4b37d2ecd8b5536778595a821f3f578f204ef3
parent45055df5ecb28964aac7879f6b0b3a92f964a10f (diff)
downloadgolang-d0430f3303242f5c955af283b4592e3ce5760bfa.tar.gz
hash: document that Sum does not change hash state
crypto/*: implement and test proper Sum Fixes issue 216. R=agl1 CC=golang-dev http://codereview.appspot.com/186210 Committer: Russ Cox <rsc@golang.org>
-rw-r--r--src/pkg/crypto/md4/md4.go6
-rw-r--r--src/pkg/crypto/md4/md4_test.go13
-rw-r--r--src/pkg/crypto/md5/md5.go6
-rw-r--r--src/pkg/crypto/md5/md5_test.go13
-rw-r--r--src/pkg/crypto/sha1/sha1.go6
-rw-r--r--src/pkg/crypto/sha1/sha1_test.go13
-rw-r--r--src/pkg/crypto/sha256/sha256.go6
-rw-r--r--src/pkg/crypto/sha256/sha256_test.go13
-rw-r--r--src/pkg/hash/hash.go13
9 files changed, 66 insertions, 23 deletions
diff --git a/src/pkg/crypto/md4/md4.go b/src/pkg/crypto/md4/md4.go
index 6096ab997..793cb16fd 100644
--- a/src/pkg/crypto/md4/md4.go
+++ b/src/pkg/crypto/md4/md4.go
@@ -76,7 +76,11 @@ func (d *digest) Write(p []byte) (nn int, err os.Error) {
return
}
-func (d *digest) Sum() []byte {
+func (d0 *digest) Sum() []byte {
+ // Make a copy of d0, so that caller can keep writing and summing.
+ d := new(digest)
+ *d = *d0
+
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
var tmp [64]byte
diff --git a/src/pkg/crypto/md4/md4_test.go b/src/pkg/crypto/md4/md4_test.go
index 9cab80c63..b883e6459 100644
--- a/src/pkg/crypto/md4/md4_test.go
+++ b/src/pkg/crypto/md4/md4_test.go
@@ -53,12 +53,17 @@ func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i]
c := New()
- for j := 0; j < 2; j++ {
- io.WriteString(c, g.in)
+ for j := 0; j < 3; j++ {
+ if j < 2 {
+ io.WriteString(c, g.in)
+ } else {
+ io.WriteString(c, g.in[0:len(g.in)/2])
+ c.Sum()
+ io.WriteString(c, g.in[len(g.in)/2:])
+ }
s := fmt.Sprintf("%x", c.Sum())
if s != g.out {
- t.Errorf("md4[%d](%s) = %s want %s", j, g.in, s, g.out)
- t.FailNow()
+ t.Fatalf("md4[%d](%s) = %s want %s", j, g.in, s, g.out)
}
c.Reset()
}
diff --git a/src/pkg/crypto/md5/md5.go b/src/pkg/crypto/md5/md5.go
index fd0984a41..90774af6b 100644
--- a/src/pkg/crypto/md5/md5.go
+++ b/src/pkg/crypto/md5/md5.go
@@ -76,7 +76,11 @@ func (d *digest) Write(p []byte) (nn int, err os.Error) {
return
}
-func (d *digest) Sum() []byte {
+func (d0 *digest) Sum() []byte {
+ // Make a copy of d0 so that caller can keep writing and summing.
+ d := new(digest)
+ *d = *d0
+
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
var tmp [64]byte
diff --git a/src/pkg/crypto/md5/md5_test.go b/src/pkg/crypto/md5/md5_test.go
index 7d5737b26..f6c293837 100644
--- a/src/pkg/crypto/md5/md5_test.go
+++ b/src/pkg/crypto/md5/md5_test.go
@@ -53,12 +53,17 @@ func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i]
c := New()
- for j := 0; j < 2; j++ {
- io.WriteString(c, g.in)
+ for j := 0; j < 3; j++ {
+ if j < 2 {
+ io.WriteString(c, g.in)
+ } else {
+ io.WriteString(c, g.in[0:len(g.in)/2])
+ c.Sum()
+ io.WriteString(c, g.in[len(g.in)/2:])
+ }
s := fmt.Sprintf("%x", c.Sum())
if s != g.out {
- t.Errorf("md5[%d](%s) = %s want %s", j, g.in, s, g.out)
- t.FailNow()
+ t.Fatalf("md5[%d](%s) = %s want %s", j, g.in, s, g.out)
}
c.Reset()
}
diff --git a/src/pkg/crypto/sha1/sha1.go b/src/pkg/crypto/sha1/sha1.go
index 7209041ee..98f0a0667 100644
--- a/src/pkg/crypto/sha1/sha1.go
+++ b/src/pkg/crypto/sha1/sha1.go
@@ -78,7 +78,11 @@ func (d *digest) Write(p []byte) (nn int, err os.Error) {
return
}
-func (d *digest) Sum() []byte {
+func (d0 *digest) Sum() []byte {
+ // Make a copy of d0 so that caller can keep writing and summing.
+ d := new(digest)
+ *d = *d0
+
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
var tmp [64]byte
diff --git a/src/pkg/crypto/sha1/sha1_test.go b/src/pkg/crypto/sha1/sha1_test.go
index 8d4485282..f18c7b096 100644
--- a/src/pkg/crypto/sha1/sha1_test.go
+++ b/src/pkg/crypto/sha1/sha1_test.go
@@ -55,12 +55,17 @@ func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i]
c := New()
- for j := 0; j < 2; j++ {
- io.WriteString(c, g.in)
+ for j := 0; j < 3; j++ {
+ if j < 2 {
+ io.WriteString(c, g.in)
+ } else {
+ io.WriteString(c, g.in[0:len(g.in)/2])
+ c.Sum()
+ io.WriteString(c, g.in[len(g.in)/2:])
+ }
s := fmt.Sprintf("%x", c.Sum())
if s != g.out {
- t.Errorf("sha1[%d](%s) = %s want %s", j, g.in, s, g.out)
- t.FailNow()
+ t.Fatalf("sha1[%d](%s) = %s want %s", j, g.in, s, g.out)
}
c.Reset()
}
diff --git a/src/pkg/crypto/sha256/sha256.go b/src/pkg/crypto/sha256/sha256.go
index bacefc563..df18e5fb2 100644
--- a/src/pkg/crypto/sha256/sha256.go
+++ b/src/pkg/crypto/sha256/sha256.go
@@ -84,7 +84,11 @@ func (d *digest) Write(p []byte) (nn int, err os.Error) {
return
}
-func (d *digest) Sum() []byte {
+func (d0 *digest) Sum() []byte {
+ // Make a copy of d0 so that caller can keep writing and summing.
+ d := new(digest)
+ *d = *d0
+
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
len := d.len
var tmp [64]byte
diff --git a/src/pkg/crypto/sha256/sha256_test.go b/src/pkg/crypto/sha256/sha256_test.go
index 29c0bce60..4d0be6257 100644
--- a/src/pkg/crypto/sha256/sha256_test.go
+++ b/src/pkg/crypto/sha256/sha256_test.go
@@ -55,12 +55,17 @@ func TestGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i]
c := New()
- for j := 0; j < 2; j++ {
- io.WriteString(c, g.in)
+ for j := 0; j < 3; j++ {
+ if j < 2 {
+ io.WriteString(c, g.in)
+ } else {
+ io.WriteString(c, g.in[0:len(g.in)/2])
+ c.Sum()
+ io.WriteString(c, g.in[len(g.in)/2:])
+ }
s := fmt.Sprintf("%x", c.Sum())
if s != g.out {
- t.Errorf("sha256[%d](%s) = %s want %s", j, g.in, s, g.out)
- t.FailNow()
+ t.Fatalf("sha256[%d](%s) = %s want %s", j, g.in, s, g.out)
}
c.Reset()
}
diff --git a/src/pkg/hash/hash.go b/src/pkg/hash/hash.go
index 470e9a36c..f5c08d360 100644
--- a/src/pkg/hash/hash.go
+++ b/src/pkg/hash/hash.go
@@ -7,13 +7,20 @@ package hash
import "io"
// Hash is the common interface implemented by all hash functions.
-// The Write method never returns an error.
-// Sum returns the bytes of integer hash codes in big-endian order.
type Hash interface {
+ // Write adds more data to the running hash.
+ // It never returns an error.
io.Writer
+
+ // Sum returns the current hash, without changing the
+ // underlying hash state.
Sum() []byte
+
+ // Reset resets the hash to one with zero bytes written.
Reset()
- Size() int // number of bytes Sum returns
+
+ // Size returns the number of bytes Sum will return.
+ Size() int
}
// Hash32 is the common interface implemented by all 32-bit hash functions.