From 140aed9ab7a528b98f891c19eafd6db4a2de9c98 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 20 May 2009 18:16:38 -0700 Subject: hash reorg. * new package hash defining interfaces Hash and Hash32. * adler32 and crc32 return Hash32 instead of specific types. * adler32 and crc32 provide non-allocating methods for single slices. * sha1 and md5 move to crypto, return Hash. * sum.go, a simple test program, moves to /usr/rsc. * refresh Make.deps R=r DELTA=1908 (935 added, 923 deleted, 50 changed) OCL=29095 CL=29135 --- src/lib/Make.deps | 10 +- src/lib/Makefile | 11 ++- src/lib/crypto/md5/Makefile | 76 +++++++++++++++ src/lib/crypto/md5/md5.go | 115 ++++++++++++++++++++++ src/lib/crypto/md5/md5_test.go | 65 +++++++++++++ src/lib/crypto/md5/md5block.go | 178 +++++++++++++++++++++++++++++++++++ src/lib/crypto/sha1/Makefile | 76 +++++++++++++++ src/lib/crypto/sha1/sha1.go | 117 +++++++++++++++++++++++ src/lib/crypto/sha1/sha1_test.go | 67 +++++++++++++ src/lib/crypto/sha1/sha1block.go | 86 +++++++++++++++++ src/lib/hash/adler32/adler32.go | 60 ++++++++---- src/lib/hash/adler32/adler32_test.go | 2 +- src/lib/hash/crc32/crc32.go | 76 +++++++++------ src/lib/hash/crc32/crc32_test.go | 2 +- src/lib/hash/md5/Makefile | 76 --------------- src/lib/hash/md5/md5.go | 105 --------------------- src/lib/hash/md5/md5_test.go | 65 ------------- src/lib/hash/md5/md5block.go | 178 ----------------------------------- src/lib/hash/sha1/Makefile | 76 --------------- src/lib/hash/sha1/sha1.go | 107 --------------------- src/lib/hash/sha1/sha1_test.go | 67 ------------- src/lib/hash/sha1/sha1block.go | 86 ----------------- 22 files changed, 884 insertions(+), 817 deletions(-) create mode 100644 src/lib/crypto/md5/Makefile create mode 100644 src/lib/crypto/md5/md5.go create mode 100644 src/lib/crypto/md5/md5_test.go create mode 100644 src/lib/crypto/md5/md5block.go create mode 100644 src/lib/crypto/sha1/Makefile create mode 100644 src/lib/crypto/sha1/sha1.go create mode 100644 src/lib/crypto/sha1/sha1_test.go create mode 100644 src/lib/crypto/sha1/sha1block.go delete mode 100644 src/lib/hash/md5/Makefile delete mode 100644 src/lib/hash/md5/md5.go delete mode 100644 src/lib/hash/md5/md5_test.go delete mode 100644 src/lib/hash/md5/md5block.go delete mode 100644 src/lib/hash/sha1/Makefile delete mode 100644 src/lib/hash/sha1/sha1.go delete mode 100644 src/lib/hash/sha1/sha1_test.go delete mode 100644 src/lib/hash/sha1/sha1block.go (limited to 'src/lib') diff --git a/src/lib/Make.deps b/src/lib/Make.deps index d75dbf22e5..30083f2631 100644 --- a/src/lib/Make.deps +++ b/src/lib/Make.deps @@ -3,6 +3,8 @@ bufio.install: io.install os.install utf8.install container/vector.install: crypto/aes.install: os.install crypto/block.install: fmt.install io.install os.install +crypto/md5.install: hash.install os.install +crypto/sha1.install: hash.install os.install exec.install: os.install strings.install exvar.install: fmt.install http.install io.install log.install strconv.install sync.install flag.install: fmt.install os.install strconv.install @@ -12,11 +14,9 @@ go/doc.install: container/vector.install fmt.install go/ast.install go/token.ins go/parser.install: container/vector.install fmt.install go/ast.install go/scanner.install go/token.install io.install os.install go/scanner.install: go/token.install strconv.install unicode.install utf8.install go/token.install: strconv.install -hash/adler32.install: os.install -hash/crc32.install: os.install -hash/md5.install: os.install -hash/sha1.install: os.install -hash/sum.install: flag.install fmt.install hash/adler32.install hash/crc32.install hash/md5.install hash/sha1.install io.install os.install +hash.install: io.install +hash/adler32.install: hash.install os.install +hash/crc32.install: hash.install os.install http.install: bufio.install fmt.install io.install log.install net.install os.install path.install strconv.install strings.install utf8.install io.install: os.install sync.install json.install: container/vector.install fmt.install io.install math.install reflect.install strconv.install strings.install utf8.install diff --git a/src/lib/Makefile b/src/lib/Makefile index 75c6758d36..d258e1adbc 100644 --- a/src/lib/Makefile +++ b/src/lib/Makefile @@ -19,6 +19,8 @@ DIRS=\ container/vector\ crypto/aes\ crypto/block\ + crypto/md5\ + crypto/sha1\ exec\ exvar\ flag\ @@ -28,11 +30,9 @@ DIRS=\ go/parser\ go/scanner\ go/token\ + hash\ hash/adler32\ hash/crc32\ - hash/md5\ - hash/sha1\ - hash/sum\ http\ io\ json\ @@ -65,6 +65,9 @@ TEST=\ bufio\ container/vector\ crypto/aes\ + crypto/block\ + crypto/md5\ + crypto/sha1\ exec\ exvar\ flag\ @@ -73,8 +76,6 @@ TEST=\ go/scanner\ hash/adler32\ hash/crc32\ - hash/md5\ - hash/sha1\ http\ io\ json\ diff --git a/src/lib/crypto/md5/Makefile b/src/lib/crypto/md5/Makefile new file mode 100644 index 0000000000..8867b84a52 --- /dev/null +++ b/src/lib/crypto/md5/Makefile @@ -0,0 +1,76 @@ +# Copyright 2009 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. + +# DO NOT EDIT. Automatically generated by gobuild. +# gobuild -m >Makefile + +D=/crypto/ + +O_arm=5 +O_amd64=6 +O_386=8 +OS=568vq + +O=$(O_$(GOARCH)) +GC=$(O)g -I_obj +CC=$(O)c -FVw +AS=$(O)a +AR=6ar + +default: packages + +clean: + rm -rf *.[$(OS)] *.a [$(OS)].out _obj + +test: packages + gotest + +coverage: packages + gotest + 6cov -g `pwd` | grep -v '_test\.go:' + +%.$O: %.go + $(GC) $*.go + +%.$O: %.c + $(CC) $*.c + +%.$O: %.s + $(AS) $*.s + +O1=\ + md5.$O\ + +O2=\ + md5block.$O\ + + +phases: a1 a2 +_obj$D/md5.a: phases + +a1: $(O1) + $(AR) grc _obj$D/md5.a md5.$O + rm -f $(O1) + +a2: $(O2) + $(AR) grc _obj$D/md5.a md5block.$O + rm -f $(O2) + + +newpkg: clean + mkdir -p _obj$D + $(AR) grc _obj$D/md5.a + +$(O1): newpkg +$(O2): a1 +$(O3): a2 + +nuke: clean + rm -f $(GOROOT)/pkg$D/md5.a + +packages: _obj$D/md5.a + +install: packages + test -d $(GOROOT)/pkg && mkdir -p $(GOROOT)/pkg$D + cp _obj$D/md5.a $(GOROOT)/pkg$D/md5.a diff --git a/src/lib/crypto/md5/md5.go b/src/lib/crypto/md5/md5.go new file mode 100644 index 0000000000..f8b8dda2fb --- /dev/null +++ b/src/lib/crypto/md5/md5.go @@ -0,0 +1,115 @@ +// Copyright 2009 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. + +// This package implements the MD5 hash algorithm as defined in RFC 1321. +package md5 + +import ( + "hash"; + "os"; +) + +// The size of an MD5 checksum in bytes. +const Size = 16; + +const ( + _Chunk = 64; + + _Init0 = 0x67452301; + _Init1 = 0xEFCDAB89; + _Init2 = 0x98BADCFE; + _Init3 = 0x10325476; +) + +// digest represents the partial evaluation of a checksum. +type digest struct { + s [4]uint32; + x [_Chunk]byte; + nx int; + len uint64; +} + +func (d *digest) Reset() { + d.s[0] = _Init0; + d.s[1] = _Init1; + d.s[2] = _Init2; + d.s[3] = _Init3; +} + +// New returns a Hash computing the SHA1 checksum. +func New() hash.Hash { + d := new(digest); + d.Reset(); + return d; +} + +func (d *digest) Size() int { + return Size; +} + +func _Block(dig *digest, p []byte) int + +func (d *digest) Write(p []byte) (nn int, err os.Error) { + nn = len(p); + d.len += uint64(nn); + if d.nx > 0 { + n := len(p); + if n > _Chunk-d.nx { + n = _Chunk-d.nx; + } + for i := 0; i < n; i++ { + d.x[d.nx+i] = p[i]; + } + d.nx += n; + if d.nx == _Chunk { + _Block(d, &d.x); + d.nx = 0; + } + p = p[n:len(p)]; + } + n := _Block(d, p); + p = p[n:len(p)]; + if len(p) > 0 { + for i := 0; i < len(p); i++ { + d.x[i] = p[i]; + } + d.nx = len(p); + } + return; +} + +func (d *digest) Sum() []byte { + // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. + len := d.len; + var tmp [64]byte; + tmp[0] = 0x80; + if len%64 < 56 { + d.Write(tmp[0:56-len%64]); + } else { + d.Write(tmp[0:64+56-len%64]); + } + + // Length in bits. + len <<= 3; + for i := uint(0); i < 8; i++ { + tmp[i] = byte(len>>(8*i)); + } + d.Write(tmp[0:8]); + + if d.nx != 0 { + panicln("oops"); + } + + p := make([]byte, 16); + j := 0; + for i := 0; i < 4; i++ { + s := d.s[i]; + p[j] = byte(s); j++; + p[j] = byte(s>>8); j++; + p[j] = byte(s>>16); j++; + p[j] = byte(s>>24); j++; + } + return p; +} + diff --git a/src/lib/crypto/md5/md5_test.go b/src/lib/crypto/md5/md5_test.go new file mode 100644 index 0000000000..e557742cc7 --- /dev/null +++ b/src/lib/crypto/md5/md5_test.go @@ -0,0 +1,65 @@ +// Copyright 2009 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 md5 + +import ( + "fmt"; + "crypto/md5"; + "io"; + "testing"; +) + +type md5Test struct { + out string; + in string; +} + +var golden = []md5Test { + md5Test{ "d41d8cd98f00b204e9800998ecf8427e", "" }, + md5Test{ "0cc175b9c0f1b6a831c399e269772661", "a" }, + md5Test{ "187ef4436122d1cc2f40dc2b92f0eba0", "ab" }, + md5Test{ "900150983cd24fb0d6963f7d28e17f72", "abc" }, + md5Test{ "e2fc714c4727ee9395f324cd2e7f331f", "abcd" }, + md5Test{ "ab56b4d92b40713acc5af89985d4b786", "abcde" }, + md5Test{ "e80b5017098950fc58aad83c8c14978e", "abcdef" }, + md5Test{ "7ac66c0f148de9519b8bd264312c4d64", "abcdefg" }, + md5Test{ "e8dc4081b13434b45189a720b77b6818", "abcdefgh" }, + md5Test{ "8aa99b1f439ff71293e95357bac6fd94", "abcdefghi" }, + md5Test{ "a925576942e94b2ef57a066101b48876", "abcdefghij" }, + md5Test{ "d747fc1719c7eacb84058196cfe56d57", "Discard medicine more than two years old." }, + md5Test{ "bff2dcb37ef3a44ba43ab144768ca837", "He who has a shady past knows that nice guys finish last." }, + md5Test{ "0441015ecb54a7342d017ed1bcfdbea5", "I wouldn't marry him with a ten foot pole." }, + md5Test{ "9e3cac8e9e9757a60c3ea391130d3689", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave" }, + md5Test{ "a0f04459b031f916a59a35cc482dc039", "The days of the digital watch are numbered. -Tom Stoppard" }, + md5Test{ "e7a48e0fe884faf31475d2a04b1362cc", "Nepal premier won't resign." }, + md5Test{ "637d2fe925c07c113800509964fb0e06", "For every action there is an equal and opposite government program." }, + md5Test{ "834a8d18d5c6562119cf4c7f5086cb71", "His money is twice tainted: 'taint yours and 'taint mine." }, + md5Test{ "de3a4d2fd6c73ec2db2abad23b444281", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977" }, + md5Test{ "acf203f997e2cf74ea3aff86985aefaf", "It's a tiny change to the code and not completely disgusting. - Bob Manchek" }, + md5Test{ "e1c1384cb4d2221dfdd7c795a4222c9a", "size: a.out: bad magic" }, + md5Test{ "c90f3ddecc54f34228c063d7525bf644", "The major problem is with sendmail. -Mark Horton" }, + md5Test{ "cdf7ab6c1fd49bd9933c43f3ea5af185", "Give me a rock, paper and scissors and I will move the world. CCFestoon" }, + md5Test{ "83bc85234942fc883c063cbd7f0ad5d0", "If the enemy is within range, then so are you." }, + md5Test{ "277cbe255686b48dd7e8f389394d9299", "It's well we cannot hear the screams/That we create in others' dreams." }, + md5Test{ "fd3fb0a7ffb8af16603f3d3af98f8e1f", "You remind me of a TV show, but that's all right: I watch it anyway." }, + md5Test{ "469b13a78ebf297ecda64d4723655154", "C is as portable as Stonehedge!!" }, + md5Test{ "63eb3a2f466410104731c4b037600110", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley" }, + md5Test{ "72c2ed7592debca1c90fc0100f931a2f", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule" }, + md5Test{ "132f7619d33b523b1d9e5bd8e0928355", "How can you write a big system without C++? -Paul Glick" }, +} + +func TestGolden(t *testing.T) { + for i := 0; i < len(golden); i++ { + g := golden[i]; + c := New(); + io.WriteString(c, g.in); + s := fmt.Sprintf("%x", c.Sum()); + if s != g.out { + t.Errorf("md5(%s) = %s want %s", g.in, s, g.out); + t.FailNow(); + } + } +} + diff --git a/src/lib/crypto/md5/md5block.go b/src/lib/crypto/md5/md5block.go new file mode 100644 index 0000000000..2776c8795c --- /dev/null +++ b/src/lib/crypto/md5/md5block.go @@ -0,0 +1,178 @@ +// Copyright 2009 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. + +// MD5 block step. +// In its own file so that a faster assembly or C version +// can be substituted easily. + +package md5 + +import "crypto/md5" + +// table[i] = int((1<<32) * abs(sin(i+1 radians))). +var table = []uint32 { + // round 1 + 0xd76aa478, + 0xe8c7b756, + 0x242070db, + 0xc1bdceee, + 0xf57c0faf, + 0x4787c62a, + 0xa8304613, + 0xfd469501, + 0x698098d8, + 0x8b44f7af, + 0xffff5bb1, + 0x895cd7be, + 0x6b901122, + 0xfd987193, + 0xa679438e, + 0x49b40821, + + // round 2 + 0xf61e2562, + 0xc040b340, + 0x265e5a51, + 0xe9b6c7aa, + 0xd62f105d, + 0x2441453, + 0xd8a1e681, + 0xe7d3fbc8, + 0x21e1cde6, + 0xc33707d6, + 0xf4d50d87, + 0x455a14ed, + 0xa9e3e905, + 0xfcefa3f8, + 0x676f02d9, + 0x8d2a4c8a, + + // round3 + 0xfffa3942, + 0x8771f681, + 0x6d9d6122, + 0xfde5380c, + 0xa4beea44, + 0x4bdecfa9, + 0xf6bb4b60, + 0xbebfbc70, + 0x289b7ec6, + 0xeaa127fa, + 0xd4ef3085, + 0x4881d05, + 0xd9d4d039, + 0xe6db99e5, + 0x1fa27cf8, + 0xc4ac5665, + + // round 4 + 0xf4292244, + 0x432aff97, + 0xab9423a7, + 0xfc93a039, + 0x655b59c3, + 0x8f0ccc92, + 0xffeff47d, + 0x85845dd1, + 0x6fa87e4f, + 0xfe2ce6e0, + 0xa3014314, + 0x4e0811a1, + 0xf7537e82, + 0xbd3af235, + 0x2ad7d2bb, + 0xeb86d391, +} + +var shift1 = []uint { 7, 12, 17, 22 }; +var shift2 = []uint { 5, 9, 14, 20 }; +var shift3 = []uint { 4, 11, 16, 23 }; +var shift4 = []uint { 6, 10, 15, 21 }; + +func _Block(dig *digest, p []byte) int { + a := dig.s[0]; + b := dig.s[1]; + c := dig.s[2]; + d := dig.s[3]; + n := 0; + var X [16]uint32; + for len(p) >= _Chunk { + aa, bb, cc, dd := a, b, c, d; + + for i := 0; i < 16; i++ { + j := i*4; + X[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24; + } + + // If this needs to be made faster in the future, + // the usual trick is to unroll each of these + // loops by a factor of 4; that lets you replace + // the shift[] lookups with constants and, + // with suitable variable renaming in each + // unrolled body, delete the a, b, c, d = d, a, b, c + // (or you can let the optimizer do the renaming). + + // Round 1. + for i := 0; i < 16; i++ { + x := i; + t := i; + s := shift1[i%4]; + f := ((c ^ d) & b) ^ d; + a += f + X[x] + table[t]; + a = a<>(32-s); + a += b; + a, b, c, d = d, a, b, c; + } + + // Round 2. + for i := 0; i < 16; i++ { + x := (1+5*i)%16; + t := 16+i; + s := shift2[i%4]; + g := ((b ^ c) & d) ^ c; + a += g + X[x] + table[t]; + a = a<>(32-s); + a += b; + a, b, c, d = d, a, b, c; + } + + // Round 3. + for i := 0; i < 16; i++ { + x := (5+3*i)%16; + t := 32+i; + s := shift3[i%4]; + h := b ^ c ^ d; + a += h + X[x] + table[t]; + a = a<>(32-s); + a += b; + a, b, c, d = d, a, b, c; + } + + // Round 4. + for i := 0; i < 16; i++ { + x := (7*i)%16; + s := shift4[i%4]; + t := 48+i; + ii := c ^ (b | ^d); + a += ii + X[x] + table[t]; + a = a<>(32-s); + a += b; + a, b, c, d = d, a, b, c; + } + + a += aa; + b += bb; + c += cc; + d += dd; + + p = p[_Chunk:len(p)]; + n += _Chunk; + } + + dig.s[0] = a; + dig.s[1] = b; + dig.s[2] = c; + dig.s[3] = d; + return n; +} diff --git a/src/lib/crypto/sha1/Makefile b/src/lib/crypto/sha1/Makefile new file mode 100644 index 0000000000..f4e1ea0dd5 --- /dev/null +++ b/src/lib/crypto/sha1/Makefile @@ -0,0 +1,76 @@ +# Copyright 2009 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. + +# DO NOT EDIT. Automatically generated by gobuild. +# gobuild -m >Makefile + +D=/crypto/ + +O_arm=5 +O_amd64=6 +O_386=8 +OS=568vq + +O=$(O_$(GOARCH)) +GC=$(O)g -I_obj +CC=$(O)c -FVw +AS=$(O)a +AR=6ar + +default: packages + +clean: + rm -rf *.[$(OS)] *.a [$(OS)].out _obj + +test: packages + gotest + +coverage: packages + gotest + 6cov -g `pwd` | grep -v '_test\.go:' + +%.$O: %.go + $(GC) $*.go + +%.$O: %.c + $(CC) $*.c + +%.$O: %.s + $(AS) $*.s + +O1=\ + sha1.$O\ + +O2=\ + sha1block.$O\ + + +phases: a1 a2 +_obj$D/sha1.a: phases + +a1: $(O1) + $(AR) grc _obj$D/sha1.a sha1.$O + rm -f $(O1) + +a2: $(O2) + $(AR) grc _obj$D/sha1.a sha1block.$O + rm -f $(O2) + + +newpkg: clean + mkdir -p _obj$D + $(AR) grc _obj$D/sha1.a + +$(O1): newpkg +$(O2): a1 +$(O3): a2 + +nuke: clean + rm -f $(GOROOT)/pkg$D/sha1.a + +packages: _obj$D/sha1.a + +install: packages + test -d $(GOROOT)/pkg && mkdir -p $(GOROOT)/pkg$D + cp _obj$D/sha1.a $(GOROOT)/pkg$D/sha1.a diff --git a/src/lib/crypto/sha1/sha1.go b/src/lib/crypto/sha1/sha1.go new file mode 100644 index 0000000000..c5f702264f --- /dev/null +++ b/src/lib/crypto/sha1/sha1.go @@ -0,0 +1,117 @@ +// Copyright 2009 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. + +// This package implements the SHA1 hash algorithm as defined in RFC 3174. +package sha1 + +import ( + "hash"; + "os"; +) + +// The size of a SHA1 checksum in bytes. +const Size = 20; + +const ( + _Chunk = 64; + + _Init0 = 0x67452301; + _Init1 = 0xEFCDAB89; + _Init2 = 0x98BADCFE; + _Init3 = 0x10325476; + _Init4 = 0xC3D2E1F0; +) + +// digest represents the partial evaluation of a checksum. +type digest struct { + h [5]uint32; + x [_Chunk]byte; + nx int; + len uint64; +} + +func (d *digest) Reset() { + d.h[0] = _Init0; + d.h[1] = _Init1; + d.h[2] = _Init2; + d.h[3] = _Init3; + d.h[4] = _Init4; +} + +// New returns a Hash computing the SHA1 checksum. +func New() hash.Hash { + d := new(digest); + d.Reset(); + return d; +} + +func (d *digest) Size() int { + return Size; +} + +func _Block(dig *digest, p []byte) int + +func (d *digest) Write(p []byte) (nn int, err os.Error) { + nn = len(p); + d.len += uint64(nn); + if d.nx > 0 { + n := len(p); + if n > _Chunk-d.nx { + n = _Chunk-d.nx; + } + for i := 0; i < n; i++ { + d.x[d.nx+i] = p[i]; + } + d.nx += n; + if d.nx == _Chunk { + _Block(d, &d.x); + d.nx = 0; + } + p = p[n:len(p)]; + } + n := _Block(d, p); + p = p[n:len(p)]; + if len(p) > 0 { + for i := 0; i < len(p); i++ { + d.x[i] = p[i]; + } + d.nx = len(p); + } + return; +} + +func (d *digest) Sum() []byte { + // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. + len := d.len; + var tmp [64]byte; + tmp[0] = 0x80; + if len%64 < 56 { + d.Write(tmp[0:56-len%64]); + } else { + d.Write(tmp[0:64+56-len%64]); + } + + // Length in bits. + len <<= 3; + for i := uint(0); i < 8; i++ { + tmp[i] = byte(len>>(56-8*i)); + } + d.Write(tmp[0:8]); + + if d.nx != 0 { + panicln("oops"); + } + + p := make([]byte, 20); + j := 0; + for i := 0; i < 5; i++ { + s := d.h[i]; + p[j] = byte(s>>24); j++; + p[j] = byte(s>>16); j++; + p[j] = byte(s>>8); j++; + p[j] = byte(s); j++; + } + return p; +} + diff --git a/src/lib/crypto/sha1/sha1_test.go b/src/lib/crypto/sha1/sha1_test.go new file mode 100644 index 0000000000..3ac9a47ec2 --- /dev/null +++ b/src/lib/crypto/sha1/sha1_test.go @@ -0,0 +1,67 @@ +// Copyright 2009 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. + +// SHA1 hash algorithm. See RFC 3174. + +package sha1 + +import ( + "fmt"; + "crypto/sha1"; + "io"; + "testing"; +) + +type sha1Test struct { + out string; + in string; +} + +var golden = []sha1Test { + sha1Test{ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "" }, + sha1Test{ "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", "a" }, + sha1Test{ "da23614e02469a0d7c7bd1bdab5c9c474b1904dc", "ab" }, + sha1Test{ "a9993e364706816aba3e25717850c26c9cd0d89d", "abc" }, + sha1Test{ "81fe8bfe87576c3ecb22426f8e57847382917acf", "abcd" }, + sha1Test{ "03de6c570bfe24bfc328ccd7ca46b76eadaf4334", "abcde" }, + sha1Test{ "1f8ac10f23c5b5bc1167bda84b833e5c057a77d2", "abcdef" }, + sha1Test{ "2fb5e13419fc89246865e7a324f476ec624e8740", "abcdefg" }, + sha1Test{ "425af12a0743502b322e93a015bcf868e324d56a", "abcdefgh" }, + sha1Test{ "c63b19f1e4c8b5f76b25c49b8b87f57d8e4872a1", "abcdefghi" }, + sha1Test{ "d68c19a0a345b7eab78d5e11e991c026ec60db63", "abcdefghij" }, + sha1Test{ "ebf81ddcbe5bf13aaabdc4d65354fdf2044f38a7", "Discard medicine more than two years old." }, + sha1Test{ "e5dea09392dd886ca63531aaa00571dc07554bb6", "He who has a shady past knows that nice guys finish last." }, + sha1Test{ "45988f7234467b94e3e9494434c96ee3609d8f8f", "I wouldn't marry him with a ten foot pole." }, + sha1Test{ "55dee037eb7460d5a692d1ce11330b260e40c988", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave" }, + sha1Test{ "b7bc5fb91080c7de6b582ea281f8a396d7c0aee8", "The days of the digital watch are numbered. -Tom Stoppard" }, + sha1Test{ "c3aed9358f7c77f523afe86135f06b95b3999797", "Nepal premier won't resign." }, + sha1Test{ "6e29d302bf6e3a5e4305ff318d983197d6906bb9", "For every action there is an equal and opposite government program." }, + sha1Test{ "597f6a540010f94c15d71806a99a2c8710e747bd", "His money is twice tainted: 'taint yours and 'taint mine." }, + sha1Test{ "6859733b2590a8a091cecf50086febc5ceef1e80", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977" }, + sha1Test{ "514b2630ec089b8aee18795fc0cf1f4860cdacad", "It's a tiny change to the code and not completely disgusting. - Bob Manchek" }, + sha1Test{ "c5ca0d4a7b6676fc7aa72caa41cc3d5df567ed69", "size: a.out: bad magic" }, + sha1Test{ "74c51fa9a04eadc8c1bbeaa7fc442f834b90a00a", "The major problem is with sendmail. -Mark Horton" }, + sha1Test{ "0b4c4ce5f52c3ad2821852a8dc00217fa18b8b66", "Give me a rock, paper and scissors and I will move the world. CCFestoon" }, + sha1Test{ "3ae7937dd790315beb0f48330e8642237c61550a", "If the enemy is within range, then so are you." }, + sha1Test{ "410a2b296df92b9a47412b13281df8f830a9f44b", "It's well we cannot hear the screams/That we create in others' dreams." }, + sha1Test{ "841e7c85ca1adcddbdd0187f1289acb5c642f7f5", "You remind me of a TV show, but that's all right: I watch it anyway." }, + sha1Test{ "163173b825d03b952601376b25212df66763e1db", "C is as portable as Stonehedge!!" }, + sha1Test{ "32b0377f2687eb88e22106f133c586ab314d5279", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley" }, + sha1Test{ "0885aaf99b569542fd165fa44e322718f4a984e0", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule" }, + sha1Test{ "6627d6904d71420b0bf3886ab629623538689f45", "How can you write a big system without C++? -Paul Glick" }, +} + +func TestGolden(t *testing.T) { + for i := 0; i < len(golden); i++ { + g := golden[i]; + c := New(); + io.WriteString(c, g.in); + s := fmt.Sprintf("%x", c.Sum()); + if s != g.out { + t.Errorf("sha1(%s) = %s want %s", g.in, s, g.out); + t.FailNow(); + } + } +} + diff --git a/src/lib/crypto/sha1/sha1block.go b/src/lib/crypto/sha1/sha1block.go new file mode 100644 index 0000000000..01ddd9506a --- /dev/null +++ b/src/lib/crypto/sha1/sha1block.go @@ -0,0 +1,86 @@ +// Copyright 2009 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. + +// SHA1 block step. +// In its own file so that a faster assembly or C version +// can be substituted easily. + +package sha1 + +import "crypto/sha1" + +const ( + _K0 = 0x5A827999; + _K1 = 0x6ED9EBA1; + _K2 = 0x8F1BBCDC; + _K3 = 0xCA62C1D6; +) + +func _Block(dig *digest, p []byte) int { + 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]; + for len(p) >= _Chunk { + // Can interlace the computation of w with the + // rounds below if needed for speed. + for i := 0; i < 16; i++ { + j := i*4; + w[i] = uint32(p[j])<<24 | + uint32(p[j+1])<<16 | + uint32(p[j+2])<<8 | + uint32(p[j+3]); + } + for i := 16; i < 80; i++ { + tmp := w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]; + w[i] = tmp<<1 | tmp>>(32-1); + } + + a, b, c, d, e := h0, h1, h2, h3, h4; + + // Each of the four 20-iteration rounds + // differs only in the computation of f and + // the choice of K (_K0, _K1, etc). + for i := 0; i < 20; i++ { + f := b&c | (^b)&d; + a5 := a<<5 | a>>(32-5); + b30 := b<<30 | b>>(32-30); + t := a5 + f + e + w[i] + _K0; + a, b, c, d, e = t, a, b30, c, d; + } + for i := 20; i < 40; i++ { + f := b ^ c ^ d; + a5 := a<<5 | a>>(32-5); + b30 := b<<30 | b>>(32-30); + t := a5 + f + e + w[i] + _K1; + a, b, c, d, e = t, a, b30, c, d; + } + for i := 40; i < 60; i++ { + f := b&c | b&d | c&d; + a5 := a<<5 | a>>(32-5); + b30 := b<<30 | b>>(32-30); + t := a5 + f + e + w[i] + _K2; + a, b, c, d, e = t, a, b30, c, d; + } + for i := 60; i < 80; i++ { + f := b ^ c ^ d; + a5 := a<<5 | a>>(32-5); + b30 := b<<30 | b>>(32-30); + t := a5 + f + e + w[i] + _K3; + a, b, c, d, e = t, a, b30, c, d; + } + + h0 += a; + h1 += b; + h2 += c; + h3 += d; + h4 += e; + + p = p[_Chunk:len(p)]; + n += _Chunk; + } + + dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4] = h0, h1, h2, h3, h4; + return n; +} diff --git a/src/lib/hash/adler32/adler32.go b/src/lib/hash/adler32/adler32.go index 2b3bd6f85a..fbf9177f89 100644 --- a/src/lib/hash/adler32/adler32.go +++ b/src/lib/hash/adler32/adler32.go @@ -11,28 +11,42 @@ // significant-byte first (network) order. package adler32 -import "os" +import ( + "hash"; + "os"; +) const ( mod = 65521; ) -// Digest represents the partial evaluation of a checksum. -type Digest struct { +// The size of an Adler-32 checksum in bytes. +const Size = 4; + +// digest represents the partial evaluation of a checksum. +type digest struct { // invariant: (a < mod && b < mod) || a <= b // invariant: a + b + 255 <= 0xffffffff a, b uint32; } -// NewDigest creates a new Digest. -func NewDigest() *Digest { - return &Digest{1, 0}; +func (d *digest) Reset() { + d.a, d.b = 1, 0; +} + +// New returns a new Hash32 computing the Adler-32 checksum. +func New() hash.Hash32 { + d := new(digest); + d.Reset(); + return d; +} + +func (d *digest) Size() int { + return Size; } -// Write updates the Digest with the incremental checksum generated by p. -// It returns the number of bytes written; err is always nil. -func (d *Digest) Write(p []byte) (nn int, err os.Error) { - a, b := d.a, d.b; +// Add p to the running checksum a, b. +func update(a, b uint32, p []byte) (aa, bb uint32) { for i := 0; i < len(p); i++ { a += uint32(p[i]); b += a; @@ -45,13 +59,11 @@ func (d *Digest) Write(p []byte) (nn int, err os.Error) { // invariant: a + b + 255 <= 2 * b + 255 <= 0xffffffff } } - d.a, d.b = a, b; - return len(p), nil + return a, b; } -// Sum32 returns the 32-bit Adler-32 checksum of the data written to the Digest. -func (d *Digest) Sum32() uint32 { - a, b := d.a, d.b; +// Return the 32-bit checksum corresponding to a, b. +func finish(a, b uint32) uint32 { if b >= mod { a %= mod; b %= mod; @@ -59,9 +71,16 @@ func (d *Digest) Sum32() uint32 { return b<<16 | a; } -// Sum returns the 32-bit Adler-32 checksum of the data written to the Digest -// in the form of an array of 4 bytes in big-endian order. -func (d *Digest) Sum() []byte { +func (d *digest) Write(p []byte) (nn int, err os.Error) { + d.a, d.b = update(d.a, d.b, p); + return len(p), nil; +} + +func (d *digest) Sum32() uint32 { + return finish(d.a, d.b); +} + +func (d *digest) Sum() []byte { p := make([]byte, 4); s := d.Sum32(); p[0] = byte(s>>24); @@ -70,3 +89,8 @@ func (d *Digest) Sum() []byte { p[3] = byte(s); return p; } + +// Checksum returns the Adler-32 checksum of data. +func Checksum(data []byte) uint32 { + return finish(update(1, 0, data)); +} diff --git a/src/lib/hash/adler32/adler32_test.go b/src/lib/hash/adler32/adler32_test.go index 90c0f6d39e..ce49a110bb 100644 --- a/src/lib/hash/adler32/adler32_test.go +++ b/src/lib/hash/adler32/adler32_test.go @@ -53,7 +53,7 @@ var golden = []_Adler32Test { func TestGolden(t *testing.T) { for i := 0; i < len(golden); i++ { g := golden[i]; - c := NewDigest(); + c := New(); io.WriteString(c, g.in); s := c.Sum32(); if s != g.out { diff --git a/src/lib/hash/crc32/crc32.go b/src/lib/hash/crc32/crc32.go index 57fa6af816..7fc3966aea 100644 --- a/src/lib/hash/crc32/crc32.go +++ b/src/lib/hash/crc32/crc32.go @@ -6,7 +6,13 @@ // See http://en.wikipedia.org/wiki/Cyclic_redundancy_check for information. package crc32 -import "os" +import ( + "hash"; + "os"; +) + +// The size of a CRC-32 checksum in bytes. +const Size = 4; // Predefined polynomials. const ( @@ -26,12 +32,11 @@ const ( ) // Table is a 256-word table representing the polynomial for efficient processing. -// TODO(rsc): Change to [256]uint32 once 6g can handle it. -type Table []uint32 +type Table [256]uint32 // MakeTable returns the Table constructed from the specified polynomial. -func MakeTable(poly uint32) Table { - t := make(Table, 256); +func MakeTable(poly uint32) *Table { + t := new(Table); for i := 0; i < 256; i++ { crc := uint32(i); for j := 0; j < 8; j++ { @@ -49,44 +54,51 @@ func MakeTable(poly uint32) Table { // IEEETable is the table for the IEEE polynomial. var IEEETable = MakeTable(IEEE); -// Digest represents the partial evaluation of a checksum. -type Digest struct { +// digest represents the partial evaluation of a checksum. +type digest struct { crc uint32; - tab Table; + tab *Table; +} + +// New creates a new Hash computing the CRC-32 checksum +// using the polynomial represented by the Table. +func New(tab *Table) hash.Hash32 { + return &digest{0, tab}; +} + +// NewIEEE creates a new Hash computing the CRC-32 checksum +// using the IEEE polynomial. +func NewIEEE() hash.Hash32 { + return New(IEEETable); } -// NewDigest creates a new Digest for the checksum based on -// the polynomial represented by the Table. -func NewDigest(tab Table) *Digest { - return &Digest{0, tab}; +func (d *digest) Size() int { + return Size; } -// NewIEEEDigest creates a new Digest for the checksum based on -// the IEEE polynomial. -func NewIEEEDigest() *Digest { - return NewDigest(IEEETable); +func (d *digest) Reset() { + d.crc = 0; } -// Write updates the Digest with the incremental checksum generated by p. -// It returns the number of bytes written; err is always nil. -func (d *Digest) Write(p []byte) (n int, err os.Error) { - crc := d.crc ^ 0xFFFFFFFF; - tab := d.tab; +func update(crc uint32, tab *Table, p []byte) uint32 { + crc ^= 0xFFFFFFFF; for i := 0; i < len(p); i++ { crc = tab[byte(crc) ^ p[i]] ^ (crc >> 8); } - d.crc = crc ^ 0xFFFFFFFF; + crc ^= 0xFFFFFFFF; + return crc; +} + +func (d *digest) Write(p []byte) (n int, err os.Error) { + d.crc = update(d.crc, d.tab, p); return len(p), nil; } -// Sum32 returns the CRC-32 checksum of the data written to the Digest. -func (d *Digest) Sum32() uint32 { +func (d *digest) Sum32() uint32 { return d.crc } -// Sum returns the CRC-32 checksum of the data written to the Digest -// in the form of an array of 4 bytes in big-endian order. -func (d *Digest) Sum() []byte { +func (d *digest) Sum() []byte { p := make([]byte, 4); s := d.Sum32(); p[0] = byte(s>>24); @@ -96,4 +108,14 @@ func (d *Digest) Sum() []byte { return p; } +// Checksum returns the CRC-32 checksum of data +// using the polynomial represented by the Table. +func Checksum(data []byte, tab *Table) uint32 { + return update(0, tab, data); +} +// ChecksumIEEE returns the CRC-32 checksum of data +// using the IEEE polynomial. +func ChecksumIEEE(data []byte) uint32 { + return update(0, IEEETable, data); +} diff --git a/src/lib/hash/crc32/crc32_test.go b/src/lib/hash/crc32/crc32_test.go index 2d675468d0..c037da600e 100644 --- a/src/lib/hash/crc32/crc32_test.go +++ b/src/lib/hash/crc32/crc32_test.go @@ -52,7 +52,7 @@ var golden = []_Crc32Test { func TestGolden(t *testing.T) { for i := 0; i < len(golden); i++ { g := golden[i]; - c := NewIEEEDigest(); + c := NewIEEE(); io.WriteString(c, g.in); s := c.Sum32(); if s != g.out { diff --git a/src/lib/hash/md5/Makefile b/src/lib/hash/md5/Makefile deleted file mode 100644 index f9320faaf5..0000000000 --- a/src/lib/hash/md5/Makefile +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright 2009 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. - -# DO NOT EDIT. Automatically generated by gobuild. -# gobuild -m >Makefile - -D=/hash/ - -O_arm=5 -O_amd64=6 -O_386=8 -OS=568vq - -O=$(O_$(GOARCH)) -GC=$(O)g -I_obj -CC=$(O)c -FVw -AS=$(O)a -AR=6ar - -default: packages - -clean: - rm -rf *.[$(OS)] *.a [$(OS)].out _obj - -test: packages - gotest - -coverage: packages - gotest - 6cov -g `pwd` | grep -v '_test\.go:' - -%.$O: %.go - $(GC) $*.go - -%.$O: %.c - $(CC) $*.c - -%.$O: %.s - $(AS) $*.s - -O1=\ - md5.$O\ - -O2=\ - md5block.$O\ - - -phases: a1 a2 -_obj$D/md5.a: phases - -a1: $(O1) - $(AR) grc _obj$D/md5.a md5.$O - rm -f $(O1) - -a2: $(O2) - $(AR) grc _obj$D/md5.a md5block.$O - rm -f $(O2) - - -newpkg: clean - mkdir -p _obj$D - $(AR) grc _obj$D/md5.a - -$(O1): newpkg -$(O2): a1 -$(O3): a2 - -nuke: clean - rm -f $(GOROOT)/pkg$D/md5.a - -packages: _obj$D/md5.a - -install: packages - test -d $(GOROOT)/pkg && mkdir -p $(GOROOT)/pkg$D - cp _obj$D/md5.a $(GOROOT)/pkg$D/md5.a diff --git a/src/lib/hash/md5/md5.go b/src/lib/hash/md5/md5.go deleted file mode 100644 index de8d34d33f..0000000000 --- a/src/lib/hash/md5/md5.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2009 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. - -// This package implements the MD5 hash algorithm as defined in RFC 1321. -package md5 - -import "os" - -const ( - _Chunk = 64; - - _Init0 = 0x67452301; - _Init1 = 0xEFCDAB89; - _Init2 = 0x98BADCFE; - _Init3 = 0x10325476; -) - -// Digest represents the partial evaluation of a checksum. -type Digest struct { - s [4]uint32; - x [_Chunk]byte; - nx int; - len uint64; -} - -// NewDigest creates a new Digest. -func NewDigest() *Digest { - d := new(Digest); - d.s[0] = _Init0; - d.s[1] = _Init1; - d.s[2] = _Init2; - d.s[3] = _Init3; - return d; -} - -func _Block(dig *Digest, p []byte) int - -// Write updates the Digest with the incremental checksum generated by p. -// It returns the number of bytes written; err is always nil. -func (d *Digest) Write(p []byte) (nn int, err os.Error) { - nn = len(p); - d.len += uint64(nn); - if d.nx > 0 { - n := len(p); - if n > _Chunk-d.nx { - n = _Chunk-d.nx; - } - for i := 0; i < n; i++ { - d.x[d.nx+i] = p[i]; - } - d.nx += n; - if d.nx == _Chunk { - _Block(d, &d.x); - d.nx = 0; - } - p = p[n:len(p)]; - } - n := _Block(d, p); - p = p[n:len(p)]; - if len(p) > 0 { - for i := 0; i < len(p); i++ { - d.x[i] = p[i]; - } - d.nx = len(p); - } - return; -} - -// Sum returns the MD5 checksum of the data written to the Digest -// in the form of an array of 16 bytes in big-endian order. -func (d *Digest) Sum() []byte { - // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. - len := d.len; - var tmp [64]byte; - tmp[0] = 0x80; - if len%64 < 56 { - d.Write(tmp[0:56-len%64]); - } else { - d.Write(tmp[0:64+56-len%64]); - } - - // Length in bits. - len <<= 3; - for i := uint(0); i < 8; i++ { - tmp[i] = byte(len>>(8*i)); - } - d.Write(tmp[0:8]); - - if d.nx != 0 { - panicln("oops"); - } - - p := make([]byte, 16); - j := 0; - for i := 0; i < 4; i++ { - s := d.s[i]; - p[j] = byte(s); j++; - p[j] = byte(s>>8); j++; - p[j] = byte(s>>16); j++; - p[j] = byte(s>>24); j++; - } - return p; -} - diff --git a/src/lib/hash/md5/md5_test.go b/src/lib/hash/md5/md5_test.go deleted file mode 100644 index 80271978d3..0000000000 --- a/src/lib/hash/md5/md5_test.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2009 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 md5 - -import ( - "fmt"; - "hash/md5"; - "io"; - "testing"; -) - -type md5Test struct { - out string; - in string; -} - -var golden = []md5Test { - md5Test{ "d41d8cd98f00b204e9800998ecf8427e", "" }, - md5Test{ "0cc175b9c0f1b6a831c399e269772661", "a" }, - md5Test{ "187ef4436122d1cc2f40dc2b92f0eba0", "ab" }, - md5Test{ "900150983cd24fb0d6963f7d28e17f72", "abc" }, - md5Test{ "e2fc714c4727ee9395f324cd2e7f331f", "abcd" }, - md5Test{ "ab56b4d92b40713acc5af89985d4b786", "abcde" }, - md5Test{ "e80b5017098950fc58aad83c8c14978e", "abcdef" }, - md5Test{ "7ac66c0f148de9519b8bd264312c4d64", "abcdefg" }, - md5Test{ "e8dc4081b13434b45189a720b77b6818", "abcdefgh" }, - md5Test{ "8aa99b1f439ff71293e95357bac6fd94", "abcdefghi" }, - md5Test{ "a925576942e94b2ef57a066101b48876", "abcdefghij" }, - md5Test{ "d747fc1719c7eacb84058196cfe56d57", "Discard medicine more than two years old." }, - md5Test{ "bff2dcb37ef3a44ba43ab144768ca837", "He who has a shady past knows that nice guys finish last." }, - md5Test{ "0441015ecb54a7342d017ed1bcfdbea5", "I wouldn't marry him with a ten foot pole." }, - md5Test{ "9e3cac8e9e9757a60c3ea391130d3689", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave" }, - md5Test{ "a0f04459b031f916a59a35cc482dc039", "The days of the digital watch are numbered. -Tom Stoppard" }, - md5Test{ "e7a48e0fe884faf31475d2a04b1362cc", "Nepal premier won't resign." }, - md5Test{ "637d2fe925c07c113800509964fb0e06", "For every action there is an equal and opposite government program." }, - md5Test{ "834a8d18d5c6562119cf4c7f5086cb71", "His money is twice tainted: 'taint yours and 'taint mine." }, - md5Test{ "de3a4d2fd6c73ec2db2abad23b444281", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977" }, - md5Test{ "acf203f997e2cf74ea3aff86985aefaf", "It's a tiny change to the code and not completely disgusting. - Bob Manchek" }, - md5Test{ "e1c1384cb4d2221dfdd7c795a4222c9a", "size: a.out: bad magic" }, - md5Test{ "c90f3ddecc54f34228c063d7525bf644", "The major problem is with sendmail. -Mark Horton" }, - md5Test{ "cdf7ab6c1fd49bd9933c43f3ea5af185", "Give me a rock, paper and scissors and I will move the world. CCFestoon" }, - md5Test{ "83bc85234942fc883c063cbd7f0ad5d0", "If the enemy is within range, then so are you." }, - md5Test{ "277cbe255686b48dd7e8f389394d9299", "It's well we cannot hear the screams/That we create in others' dreams." }, - md5Test{ "fd3fb0a7ffb8af16603f3d3af98f8e1f", "You remind me of a TV show, but that's all right: I watch it anyway." }, - md5Test{ "469b13a78ebf297ecda64d4723655154", "C is as portable as Stonehedge!!" }, - md5Test{ "63eb3a2f466410104731c4b037600110", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley" }, - md5Test{ "72c2ed7592debca1c90fc0100f931a2f", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule" }, - md5Test{ "132f7619d33b523b1d9e5bd8e0928355", "How can you write a big system without C++? -Paul Glick" }, -} - -func TestGolden(t *testing.T) { - for i := 0; i < len(golden); i++ { - g := golden[i]; - c := NewDigest(); - io.WriteString(c, g.in); - s := fmt.Sprintf("%x", c.Sum()); - if s != g.out { - t.Errorf("md5(%s) = %s want %s", g.in, s, g.out); - t.FailNow(); - } - } -} - diff --git a/src/lib/hash/md5/md5block.go b/src/lib/hash/md5/md5block.go deleted file mode 100644 index 0fc210a2cf..0000000000 --- a/src/lib/hash/md5/md5block.go +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2009 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. - -// MD5 block step. -// In its own file so that a faster assembly or C version -// can be substituted easily. - -package md5 - -import "hash/md5" - -// table[i] = int((1<<32) * abs(sin(i+1 radians))). -var table = []uint32 { - // round 1 - 0xd76aa478, - 0xe8c7b756, - 0x242070db, - 0xc1bdceee, - 0xf57c0faf, - 0x4787c62a, - 0xa8304613, - 0xfd469501, - 0x698098d8, - 0x8b44f7af, - 0xffff5bb1, - 0x895cd7be, - 0x6b901122, - 0xfd987193, - 0xa679438e, - 0x49b40821, - - // round 2 - 0xf61e2562, - 0xc040b340, - 0x265e5a51, - 0xe9b6c7aa, - 0xd62f105d, - 0x2441453, - 0xd8a1e681, - 0xe7d3fbc8, - 0x21e1cde6, - 0xc33707d6, - 0xf4d50d87, - 0x455a14ed, - 0xa9e3e905, - 0xfcefa3f8, - 0x676f02d9, - 0x8d2a4c8a, - - // round3 - 0xfffa3942, - 0x8771f681, - 0x6d9d6122, - 0xfde5380c, - 0xa4beea44, - 0x4bdecfa9, - 0xf6bb4b60, - 0xbebfbc70, - 0x289b7ec6, - 0xeaa127fa, - 0xd4ef3085, - 0x4881d05, - 0xd9d4d039, - 0xe6db99e5, - 0x1fa27cf8, - 0xc4ac5665, - - // round 4 - 0xf4292244, - 0x432aff97, - 0xab9423a7, - 0xfc93a039, - 0x655b59c3, - 0x8f0ccc92, - 0xffeff47d, - 0x85845dd1, - 0x6fa87e4f, - 0xfe2ce6e0, - 0xa3014314, - 0x4e0811a1, - 0xf7537e82, - 0xbd3af235, - 0x2ad7d2bb, - 0xeb86d391, -} - -var shift1 = []uint { 7, 12, 17, 22 }; -var shift2 = []uint { 5, 9, 14, 20 }; -var shift3 = []uint { 4, 11, 16, 23 }; -var shift4 = []uint { 6, 10, 15, 21 }; - -func _Block(dig *Digest, p []byte) int { - a := dig.s[0]; - b := dig.s[1]; - c := dig.s[2]; - d := dig.s[3]; - n := 0; - var X [16]uint32; - for len(p) >= _Chunk { - aa, bb, cc, dd := a, b, c, d; - - for i := 0; i < 16; i++ { - j := i*4; - X[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24; - } - - // If this needs to be made faster in the future, - // the usual trick is to unroll each of these - // loops by a factor of 4; that lets you replace - // the shift[] lookups with constants and, - // with suitable variable renaming in each - // unrolled body, delete the a, b, c, d = d, a, b, c - // (or you can let the optimizer do the renaming). - - // Round 1. - for i := 0; i < 16; i++ { - x := i; - t := i; - s := shift1[i%4]; - f := ((c ^ d) & b) ^ d; - a += f + X[x] + table[t]; - a = a<>(32-s); - a += b; - a, b, c, d = d, a, b, c; - } - - // Round 2. - for i := 0; i < 16; i++ { - x := (1+5*i)%16; - t := 16+i; - s := shift2[i%4]; - g := ((b ^ c) & d) ^ c; - a += g + X[x] + table[t]; - a = a<>(32-s); - a += b; - a, b, c, d = d, a, b, c; - } - - // Round 3. - for i := 0; i < 16; i++ { - x := (5+3*i)%16; - t := 32+i; - s := shift3[i%4]; - h := b ^ c ^ d; - a += h + X[x] + table[t]; - a = a<>(32-s); - a += b; - a, b, c, d = d, a, b, c; - } - - // Round 4. - for i := 0; i < 16; i++ { - x := (7*i)%16; - s := shift4[i%4]; - t := 48+i; - ii := c ^ (b | ^d); - a += ii + X[x] + table[t]; - a = a<>(32-s); - a += b; - a, b, c, d = d, a, b, c; - } - - a += aa; - b += bb; - c += cc; - d += dd; - - p = p[_Chunk:len(p)]; - n += _Chunk; - } - - dig.s[0] = a; - dig.s[1] = b; - dig.s[2] = c; - dig.s[3] = d; - return n; -} diff --git a/src/lib/hash/sha1/Makefile b/src/lib/hash/sha1/Makefile deleted file mode 100644 index 0f09259b48..0000000000 --- a/src/lib/hash/sha1/Makefile +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright 2009 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. - -# DO NOT EDIT. Automatically generated by gobuild. -# gobuild -m >Makefile - -D=/hash/ - -O_arm=5 -O_amd64=6 -O_386=8 -OS=568vq - -O=$(O_$(GOARCH)) -GC=$(O)g -I_obj -CC=$(O)c -FVw -AS=$(O)a -AR=6ar - -default: packages - -clean: - rm -rf *.[$(OS)] *.a [$(OS)].out _obj - -test: packages - gotest - -coverage: packages - gotest - 6cov -g `pwd` | grep -v '_test\.go:' - -%.$O: %.go - $(GC) $*.go - -%.$O: %.c - $(CC) $*.c - -%.$O: %.s - $(AS) $*.s - -O1=\ - sha1.$O\ - -O2=\ - sha1block.$O\ - - -phases: a1 a2 -_obj$D/sha1.a: phases - -a1: $(O1) - $(AR) grc _obj$D/sha1.a sha1.$O - rm -f $(O1) - -a2: $(O2) - $(AR) grc _obj$D/sha1.a sha1block.$O - rm -f $(O2) - - -newpkg: clean - mkdir -p _obj$D - $(AR) grc _obj$D/sha1.a - -$(O1): newpkg -$(O2): a1 -$(O3): a2 - -nuke: clean - rm -f $(GOROOT)/pkg$D/sha1.a - -packages: _obj$D/sha1.a - -install: packages - test -d $(GOROOT)/pkg && mkdir -p $(GOROOT)/pkg$D - cp _obj$D/sha1.a $(GOROOT)/pkg$D/sha1.a diff --git a/src/lib/hash/sha1/sha1.go b/src/lib/hash/sha1/sha1.go deleted file mode 100644 index 2b83eb9b0c..0000000000 --- a/src/lib/hash/sha1/sha1.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2009 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. - -// This package implements the SHA1 hash algorithm as defined in RFC 3174. -package sha1 - -import "os" - -const ( - _Chunk = 64; - - _Init0 = 0x67452301; - _Init1 = 0xEFCDAB89; - _Init2 = 0x98BADCFE; - _Init3 = 0x10325476; - _Init4 = 0xC3D2E1F0; -) - -// Digest represents the partial evaluation of a checksum. -type Digest struct { - h [5]uint32; - x [_Chunk]byte; - nx int; - len uint64; -} - -// NewDigest creates a new Digest. -func NewDigest() *Digest { - d := new(Digest); - d.h[0] = _Init0; - d.h[1] = _Init1; - d.h[2] = _Init2; - d.h[3] = _Init3; - d.h[4] = _Init4; - return d; -} - -func _Block(dig *Digest, p []byte) int - -// Write updates the Digest with the incremental checksum generated by p. -// It returns the number of bytes written; err is always nil. -func (d *Digest) Write(p []byte) (nn int, err os.Error) { - nn = len(p); - d.len += uint64(nn); - if d.nx > 0 { - n := len(p); - if n > _Chunk-d.nx { - n = _Chunk-d.nx; - } - for i := 0; i < n; i++ { - d.x[d.nx+i] = p[i]; - } - d.nx += n; - if d.nx == _Chunk { - _Block(d, &d.x); - d.nx = 0; - } - p = p[n:len(p)]; - } - n := _Block(d, p); - p = p[n:len(p)]; - if len(p) > 0 { - for i := 0; i < len(p); i++ { - d.x[i] = p[i]; - } - d.nx = len(p); - } - return; -} - -// Sum returns the SHA-1 checksum of the data written to the Digest -// in the form of an array of 20 bytes in big-endian order. -func (d *Digest) Sum() []byte { - // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. - len := d.len; - var tmp [64]byte; - tmp[0] = 0x80; - if len%64 < 56 { - d.Write(tmp[0:56-len%64]); - } else { - d.Write(tmp[0:64+56-len%64]); - } - - // Length in bits. - len <<= 3; - for i := uint(0); i < 8; i++ { - tmp[i] = byte(len>>(56-8*i)); - } - d.Write(tmp[0:8]); - - if d.nx != 0 { - panicln("oops"); - } - - p := make([]byte, 20); - j := 0; - for i := 0; i < 5; i++ { - s := d.h[i]; - p[j] = byte(s>>24); j++; - p[j] = byte(s>>16); j++; - p[j] = byte(s>>8); j++; - p[j] = byte(s); j++; - } - return p; -} - diff --git a/src/lib/hash/sha1/sha1_test.go b/src/lib/hash/sha1/sha1_test.go deleted file mode 100644 index 103b218e9b..0000000000 --- a/src/lib/hash/sha1/sha1_test.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2009 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. - -// SHA1 hash algorithm. See RFC 3174. - -package sha1 - -import ( - "fmt"; - "hash/sha1"; - "io"; - "testing"; -) - -type sha1Test struct { - out string; - in string; -} - -var golden = []sha1Test { - sha1Test{ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "" }, - sha1Test{ "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", "a" }, - sha1Test{ "da23614e02469a0d7c7bd1bdab5c9c474b1904dc", "ab" }, - sha1Test{ "a9993e364706816aba3e25717850c26c9cd0d89d", "abc" }, - sha1Test{ "81fe8bfe87576c3ecb22426f8e57847382917acf", "abcd" }, - sha1Test{ "03de6c570bfe24bfc328ccd7ca46b76eadaf4334", "abcde" }, - sha1Test{ "1f8ac10f23c5b5bc1167bda84b833e5c057a77d2", "abcdef" }, - sha1Test{ "2fb5e13419fc89246865e7a324f476ec624e8740", "abcdefg" }, - sha1Test{ "425af12a0743502b322e93a015bcf868e324d56a", "abcdefgh" }, - sha1Test{ "c63b19f1e4c8b5f76b25c49b8b87f57d8e4872a1", "abcdefghi" }, - sha1Test{ "d68c19a0a345b7eab78d5e11e991c026ec60db63", "abcdefghij" }, - sha1Test{ "ebf81ddcbe5bf13aaabdc4d65354fdf2044f38a7", "Discard medicine more than two years old." }, - sha1Test{ "e5dea09392dd886ca63531aaa00571dc07554bb6", "He who has a shady past knows that nice guys finish last." }, - sha1Test{ "45988f7234467b94e3e9494434c96ee3609d8f8f", "I wouldn't marry him with a ten foot pole." }, - sha1Test{ "55dee037eb7460d5a692d1ce11330b260e40c988", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave" }, - sha1Test{ "b7bc5fb91080c7de6b582ea281f8a396d7c0aee8", "The days of the digital watch are numbered. -Tom Stoppard" }, - sha1Test{ "c3aed9358f7c77f523afe86135f06b95b3999797", "Nepal premier won't resign." }, - sha1Test{ "6e29d302bf6e3a5e4305ff318d983197d6906bb9", "For every action there is an equal and opposite government program." }, - sha1Test{ "597f6a540010f94c15d71806a99a2c8710e747bd", "His money is twice tainted: 'taint yours and 'taint mine." }, - sha1Test{ "6859733b2590a8a091cecf50086febc5ceef1e80", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977" }, - sha1Test{ "514b2630ec089b8aee18795fc0cf1f4860cdacad", "It's a tiny change to the code and not completely disgusting. - Bob Manchek" }, - sha1Test{ "c5ca0d4a7b6676fc7aa72caa41cc3d5df567ed69", "size: a.out: bad magic" }, - sha1Test{ "74c51fa9a04eadc8c1bbeaa7fc442f834b90a00a", "The major problem is with sendmail. -Mark Horton" }, - sha1Test{ "0b4c4ce5f52c3ad2821852a8dc00217fa18b8b66", "Give me a rock, paper and scissors and I will move the world. CCFestoon" }, - sha1Test{ "3ae7937dd790315beb0f48330e8642237c61550a", "If the enemy is within range, then so are you." }, - sha1Test{ "410a2b296df92b9a47412b13281df8f830a9f44b", "It's well we cannot hear the screams/That we create in others' dreams." }, - sha1Test{ "841e7c85ca1adcddbdd0187f1289acb5c642f7f5", "You remind me of a TV show, but that's all right: I watch it anyway." }, - sha1Test{ "163173b825d03b952601376b25212df66763e1db", "C is as portable as Stonehedge!!" }, - sha1Test{ "32b0377f2687eb88e22106f133c586ab314d5279", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley" }, - sha1Test{ "0885aaf99b569542fd165fa44e322718f4a984e0", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule" }, - sha1Test{ "6627d6904d71420b0bf3886ab629623538689f45", "How can you write a big system without C++? -Paul Glick" }, -} - -func TestGolden(t *testing.T) { - for i := 0; i < len(golden); i++ { - g := golden[i]; - c := NewDigest(); - io.WriteString(c, g.in); - s := fmt.Sprintf("%x", c.Sum()); - if s != g.out { - t.Errorf("sha1(%s) = %s want %s", g.in, s, g.out); - t.FailNow(); - } - } -} - diff --git a/src/lib/hash/sha1/sha1block.go b/src/lib/hash/sha1/sha1block.go deleted file mode 100644 index 51bfd6d092..0000000000 --- a/src/lib/hash/sha1/sha1block.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2009 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. - -// SHA1 block step. -// In its own file so that a faster assembly or C version -// can be substituted easily. - -package sha1 - -import "hash/sha1" - -const ( - _K0 = 0x5A827999; - _K1 = 0x6ED9EBA1; - _K2 = 0x8F1BBCDC; - _K3 = 0xCA62C1D6; -) - -func _Block(dig *Digest, p []byte) int { - 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]; - for len(p) >= _Chunk { - // Can interlace the computation of w with the - // rounds below if needed for speed. - for i := 0; i < 16; i++ { - j := i*4; - w[i] = uint32(p[j])<<24 | - uint32(p[j+1])<<16 | - uint32(p[j+2])<<8 | - uint32(p[j+3]); - } - for i := 16; i < 80; i++ { - tmp := w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]; - w[i] = tmp<<1 | tmp>>(32-1); - } - - a, b, c, d, e := h0, h1, h2, h3, h4; - - // Each of the four 20-iteration rounds - // differs only in the computation of f and - // the choice of K (_K0, _K1, etc). - for i := 0; i < 20; i++ { - f := b&c | (^b)&d; - a5 := a<<5 | a>>(32-5); - b30 := b<<30 | b>>(32-30); - t := a5 + f + e + w[i] + _K0; - a, b, c, d, e = t, a, b30, c, d; - } - for i := 20; i < 40; i++ { - f := b ^ c ^ d; - a5 := a<<5 | a>>(32-5); - b30 := b<<30 | b>>(32-30); - t := a5 + f + e + w[i] + _K1; - a, b, c, d, e = t, a, b30, c, d; - } - for i := 40; i < 60; i++ { - f := b&c | b&d | c&d; - a5 := a<<5 | a>>(32-5); - b30 := b<<30 | b>>(32-30); - t := a5 + f + e + w[i] + _K2; - a, b, c, d, e = t, a, b30, c, d; - } - for i := 60; i < 80; i++ { - f := b ^ c ^ d; - a5 := a<<5 | a>>(32-5); - b30 := b<<30 | b>>(32-30); - t := a5 + f + e + w[i] + _K3; - a, b, c, d, e = t, a, b30, c, d; - } - - h0 += a; - h1 += b; - h2 += c; - h3 += d; - h4 += e; - - p = p[_Chunk:len(p)]; - n += _Chunk; - } - - dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4] = h0, h1, h2, h3, h4; - return n; -} -- cgit v1.3