summaryrefslogtreecommitdiff
path: root/libgo/go/crypto/md5/md5.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/crypto/md5/md5.go')
-rw-r--r--libgo/go/crypto/md5/md5.go100
1 files changed, 43 insertions, 57 deletions
diff --git a/libgo/go/crypto/md5/md5.go b/libgo/go/crypto/md5/md5.go
index 88d914d22ce..01157840475 100644
--- a/libgo/go/crypto/md5/md5.go
+++ b/libgo/go/crypto/md5/md5.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:generate go run gen.go -full -output md5block.go
+//go:generate go run gen.go -output md5block.go
// Package md5 implements the MD5 hash algorithm as defined in RFC 1321.
//
@@ -12,6 +12,7 @@ package md5
import (
"crypto"
+ "encoding/binary"
"errors"
"hash"
)
@@ -27,7 +28,6 @@ const Size = 16
const BlockSize = 64
const (
- chunk = 64
init0 = 0x67452301
init1 = 0xEFCDAB89
init2 = 0x98BADCFE
@@ -37,7 +37,7 @@ const (
// digest represents the partial evaluation of a checksum.
type digest struct {
s [4]uint32
- x [chunk]byte
+ x [BlockSize]byte
nx int
len uint64
}
@@ -53,7 +53,7 @@ func (d *digest) Reset() {
const (
magic = "md5\x01"
- marshaledSize = len(magic) + 4*4 + chunk + 8
+ marshaledSize = len(magic) + 4*4 + BlockSize + 8
)
func (d *digest) MarshalBinary() ([]byte, error) {
@@ -83,45 +83,28 @@ func (d *digest) UnmarshalBinary(b []byte) error {
b, d.s[3] = consumeUint32(b)
b = b[copy(d.x[:], b):]
b, d.len = consumeUint64(b)
- d.nx = int(d.len) % chunk
+ d.nx = int(d.len % BlockSize)
return nil
}
func appendUint64(b []byte, x uint64) []byte {
- a := [8]byte{
- byte(x >> 56),
- byte(x >> 48),
- byte(x >> 40),
- byte(x >> 32),
- byte(x >> 24),
- byte(x >> 16),
- byte(x >> 8),
- byte(x),
- }
+ var a [8]byte
+ binary.BigEndian.PutUint64(a[:], x)
return append(b, a[:]...)
}
func appendUint32(b []byte, x uint32) []byte {
- a := [4]byte{
- byte(x >> 24),
- byte(x >> 16),
- byte(x >> 8),
- byte(x),
- }
+ var a [4]byte
+ binary.BigEndian.PutUint32(a[:], x)
return append(b, a[:]...)
}
func consumeUint64(b []byte) ([]byte, uint64) {
- _ = b[7]
- x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
- uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
- return b[8:], x
+ return b[8:], binary.BigEndian.Uint64(b[0:8])
}
func consumeUint32(b []byte) ([]byte, uint32) {
- _ = b[3]
- x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
- return b[4:], x
+ return b[4:], binary.BigEndian.Uint32(b[0:4])
}
// New returns a new hash.Hash computing the MD5 checksum. The Hash also
@@ -138,20 +121,31 @@ func (d *digest) Size() int { return Size }
func (d *digest) BlockSize() int { return BlockSize }
func (d *digest) Write(p []byte) (nn int, err error) {
+ // Note that we currently call block or blockGeneric
+ // directly (guarded using haveAsm) because this allows
+ // escape analysis to see that p and d don't escape.
nn = len(p)
d.len += uint64(nn)
if d.nx > 0 {
n := copy(d.x[d.nx:], p)
d.nx += n
- if d.nx == chunk {
- block(d, d.x[:])
+ if d.nx == BlockSize {
+ if haveAsm {
+ block(d, d.x[:])
+ } else {
+ blockGeneric(d, d.x[:])
+ }
d.nx = 0
}
p = p[n:]
}
- if len(p) >= chunk {
- n := len(p) &^ (chunk - 1)
- block(d, p[:n])
+ if len(p) >= BlockSize {
+ n := len(p) &^ (BlockSize - 1)
+ if haveAsm {
+ block(d, p[:n])
+ } else {
+ blockGeneric(d, p[:n])
+ }
p = p[n:]
}
if len(p) > 0 {
@@ -168,35 +162,27 @@ func (d *digest) Sum(in []byte) []byte {
}
func (d *digest) checkSum() [Size]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])
-
+ // Append 0x80 to the end of the message and then append zeros
+ // until the length is a multiple of 56 bytes. Finally append
+ // 8 bytes representing the message length in bits.
+ //
+ // 1 byte end marker :: 0-63 padding bytes :: 8 byte length
+ tmp := [1 + 63 + 8]byte{0x80}
+ pad := (55 - d.len) % 64 // calculate number of padding bytes
+ binary.LittleEndian.PutUint64(tmp[1+pad:], d.len<<3) // append length in bits
+ d.Write(tmp[:1+pad+8])
+
+ // The previous write ensures that a whole number of
+ // blocks (i.e. a multiple of 64 bytes) have been hashed.
if d.nx != 0 {
panic("d.nx != 0")
}
var digest [Size]byte
- for i, s := range d.s {
- digest[i*4] = byte(s)
- digest[i*4+1] = byte(s >> 8)
- digest[i*4+2] = byte(s >> 16)
- digest[i*4+3] = byte(s >> 24)
- }
-
+ binary.LittleEndian.PutUint32(digest[0:], d.s[0])
+ binary.LittleEndian.PutUint32(digest[4:], d.s[1])
+ binary.LittleEndian.PutUint32(digest[8:], d.s[2])
+ binary.LittleEndian.PutUint32(digest[12:], d.s[3])
return digest
}