diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-01-18 19:04:36 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-01-18 19:04:36 +0000 |
commit | 4f4a855d82a889cebcfca150a7a43909bcb6a346 (patch) | |
tree | f12bae0781920fa34669fe30b6f4615a86d9fb80 /libgo/go/crypto/md5 | |
parent | 225220d668dafb8262db7012bced688acbe63b33 (diff) | |
download | gcc-4f4a855d82a889cebcfca150a7a43909bcb6a346.tar.gz |
libgo: update to Go1.12beta2
Reviewed-on: https://go-review.googlesource.com/c/158019
gotools/:
* Makefile.am (go_cmd_vet_files): Update for Go1.12beta2 release.
(GOTOOLS_TEST_TIMEOUT): Increase to 600.
(check-runtime): Export LD_LIBRARY_PATH before computing GOARCH
and GOOS.
(check-vet): Copy golang.org/x/tools into check-vet-dir.
* Makefile.in: Regenerate.
gcc/testsuite/:
* go.go-torture/execute/names-1.go: Stop using debug/xcoff, which
is no longer externally visible.
From-SVN: r268084
Diffstat (limited to 'libgo/go/crypto/md5')
-rw-r--r-- | libgo/go/crypto/md5/gen.go | 195 | ||||
-rw-r--r-- | libgo/go/crypto/md5/md5.go | 100 | ||||
-rw-r--r-- | libgo/go/crypto/md5/md5_test.go | 58 | ||||
-rw-r--r-- | libgo/go/crypto/md5/md5block.go | 347 | ||||
-rw-r--r-- | libgo/go/crypto/md5/md5block_decl.go | 4 | ||||
-rw-r--r-- | libgo/go/crypto/md5/md5block_generic.go | 4 |
6 files changed, 273 insertions, 435 deletions
diff --git a/libgo/go/crypto/md5/gen.go b/libgo/go/crypto/md5/gen.go index a815dc29f6a..a11f22059fa 100644 --- a/libgo/go/crypto/md5/gen.go +++ b/libgo/go/crypto/md5/gen.go @@ -7,10 +7,7 @@ // This program generates md5block.go // Invoke as // -// go run gen.go [-full] -output md5block.go -// -// The -full flag causes the generated code to do a full -// (16x) unrolling instead of a 4x unrolling. +// go run gen.go -output md5block.go package main @@ -56,13 +53,14 @@ type Data struct { Table2 []uint32 Table3 []uint32 Table4 []uint32 - Full bool } var funcs = template.FuncMap{ "dup": dup, "relabel": relabel, "rotate": rotate, + "idx": idx, + "seq": seq, } func dup(count int, x []int) []int { @@ -74,7 +72,7 @@ func dup(count int, x []int) []int { } func relabel(s string) string { - return strings.NewReplacer("a", data.a, "b", data.b, "c", data.c, "d", data.d).Replace(s) + return strings.NewReplacer("arg0", data.a, "arg1", data.b, "arg2", data.c, "arg3", data.d).Replace(s) } func rotate() string { @@ -82,8 +80,27 @@ func rotate() string { return "" // no output } -func init() { - flag.BoolVar(&data.Full, "full", false, "complete unrolling") +func idx(round, index int) int { + v := 0 + switch round { + case 1: + v = index + case 2: + v = (1 + 5*index) & 15 + case 3: + v = (5 + 3*index) & 15 + case 4: + v = (7 * index) & 15 + } + return v +} + +func seq(i int) []int { + s := make([]int, i) + for i := range s { + s[i] = i + } + return s } var data = Data{ @@ -179,152 +196,64 @@ var program = `// Copyright 2013 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. -// Code generated by go run gen.go{{if .Full}} -full{{end}} -output md5block.go; DO NOT EDIT. +// Code generated by go run gen.go -output md5block.go; DO NOT EDIT. package md5 import ( - "unsafe" - "runtime" + "encoding/binary" + "math/bits" ) -{{if not .Full}} - var t1 = [...]uint32{ - {{range .Table1}}{{printf "\t%#x,\n" .}}{{end}} - } - - var t2 = [...]uint32{ - {{range .Table2}}{{printf "\t%#x,\n" .}}{{end}} - } - - var t3 = [...]uint32{ - {{range .Table3}}{{printf "\t%#x,\n" .}}{{end}} - } - - var t4 = [...]uint32{ - {{range .Table4}}{{printf "\t%#x,\n" .}}{{end}} - } -{{end}} - -const x86 = runtime.GOARCH == "amd64" || runtime.GOARCH == "386" - -var littleEndian bool +func blockGeneric(dig *digest, p []byte) { + // load state + a, b, c, d := dig.s[0], dig.s[1], dig.s[2], dig.s[3] -func init() { - x := uint32(0x04030201) - y := [4]byte{0x1, 0x2, 0x3, 0x4} - littleEndian = *(*[4]byte)(unsafe.Pointer(&x)) == y -} + for i := 0; i <= len(p)-BlockSize; i += BlockSize { + // eliminate bounds checks on p + q := p[i:] + q = q[:BlockSize:BlockSize] -func blockGeneric(dig *digest, p []byte) { - a := dig.s[0] - b := dig.s[1] - c := dig.s[2] - d := dig.s[3] - var X *[16]uint32 - var xbuf [16]uint32 - for len(p) >= chunk { + // save current state aa, bb, cc, dd := a, b, c, d - // This is a constant condition - it is not evaluated on each iteration. - if x86 { - // MD5 was designed so that x86 processors can just iterate - // over the block data directly as uint32s, and we generate - // less code and run 1.3x faster if we take advantage of that. - // My apologies. - X = (*[16]uint32)(unsafe.Pointer(&p[0])) - } else if littleEndian && uintptr(unsafe.Pointer(&p[0]))&(unsafe.Alignof(uint32(0))-1) == 0 { - X = (*[16]uint32)(unsafe.Pointer(&p[0])) - } else { - X = &xbuf - j := 0 - for i := 0; i < 16; i++ { - X[i&15] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24 - j += 4 - } - } + // load input block + {{range $i := seq 16 -}} + {{printf "x%x := binary.LittleEndian.Uint32(q[4*%#x:])" $i $i}} + {{end}} - {{if .Full}} - // Round 1. - {{range $i, $s := dup 4 .Shift1}} - {{index $.Table1 $i | printf "a += (((c^d)&b)^d) + X[%d] + %d" $i | relabel}} - {{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}} - {{rotate}} - {{end}} - - // Round 2. - {{range $i, $s := dup 4 .Shift2}} - {{index $.Table2 $i | printf "a += (((b^c)&d)^c) + X[(1+5*%d)&15] + %d" $i | relabel}} - {{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}} - {{rotate}} - {{end}} - - // Round 3. - {{range $i, $s := dup 4 .Shift3}} - {{index $.Table3 $i | printf "a += (b^c^d) + X[(5+3*%d)&15] + %d" $i | relabel}} - {{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}} - {{rotate}} - {{end}} - - // Round 4. - {{range $i, $s := dup 4 .Shift4}} - {{index $.Table4 $i | printf "a += (c^(b|^d)) + X[(7*%d)&15] + %d" $i | relabel}} - {{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}} - {{rotate}} - {{end}} - {{else}} - // Round 1. - for i := uint(0); i < 16; { - {{range $s := .Shift1}} - {{printf "a += (((c^d)&b)^d) + X[i&15] + t1[i&15]" | relabel}} - {{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}} - i++ - {{rotate}} - {{end}} - } + // round 1 + {{range $i, $s := dup 4 .Shift1 -}} + {{printf "arg0 = arg1 + bits.RotateLeft32((((arg2^arg3)&arg1)^arg3)+arg0+x%x+%#08x, %d)" (idx 1 $i) (index $.Table1 $i) $s | relabel}} + {{rotate -}} + {{end}} - // Round 2. - for i := uint(0); i < 16; { - {{range $s := .Shift2}} - {{printf "a += (((b^c)&d)^c) + X[(1+5*i)&15] + t2[i&15]" | relabel}} - {{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}} - i++ - {{rotate}} - {{end}} - } + // round 2 + {{range $i, $s := dup 4 .Shift2 -}} + {{printf "arg0 = arg1 + bits.RotateLeft32((((arg1^arg2)&arg3)^arg2)+arg0+x%x+%#08x, %d)" (idx 2 $i) (index $.Table2 $i) $s | relabel}} + {{rotate -}} + {{end}} - // Round 3. - for i := uint(0); i < 16; { - {{range $s := .Shift3}} - {{printf "a += (b^c^d) + X[(5+3*i)&15] + t3[i&15]" | relabel}} - {{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}} - i++ - {{rotate}} - {{end}} - } + // round 3 + {{range $i, $s := dup 4 .Shift3 -}} + {{printf "arg0 = arg1 + bits.RotateLeft32((arg1^arg2^arg3)+arg0+x%x+%#08x, %d)" (idx 3 $i) (index $.Table3 $i) $s | relabel}} + {{rotate -}} + {{end}} - // Round 4. - for i := uint(0); i < 16; { - {{range $s := .Shift4}} - {{printf "a += (c^(b|^d)) + X[(7*i)&15] + t4[i&15]" | relabel}} - {{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}} - i++ - {{rotate}} - {{end}} - } + // round 4 + {{range $i, $s := dup 4 .Shift4 -}} + {{printf "arg0 = arg1 + bits.RotateLeft32((arg2^(arg1|^arg3))+arg0+x%x+%#08x, %d)" (idx 4 $i) (index $.Table4 $i) $s | relabel}} + {{rotate -}} {{end}} + // add saved state a += aa b += bb c += cc d += dd - - p = p[chunk:] } - dig.s[0] = a - dig.s[1] = b - dig.s[2] = c - dig.s[3] = d + // save state + dig.s[0], dig.s[1], dig.s[2], dig.s[3] = a, b, c, d } ` 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 } diff --git a/libgo/go/crypto/md5/md5_test.go b/libgo/go/crypto/md5/md5_test.go index 64a62e47305..34c7f541c57 100644 --- a/libgo/go/crypto/md5/md5_test.go +++ b/libgo/go/crypto/md5/md5_test.go @@ -9,6 +9,7 @@ import ( "crypto/rand" "encoding" "fmt" + "hash" "io" "testing" "unsafe" @@ -153,6 +154,63 @@ func TestBlockGeneric(t *testing.T) { } } +// Tests for unmarshaling hashes that have hashed a large amount of data +// The initial hash generation is omitted from the test, because it takes a long time. +// The test contains some already-generated states, and their expected sums +// Tests a problem that is outlined in Github issue #29541 +// The problem is triggered when an amount of data has been hashed for which +// the data length has a 1 in the 32nd bit. When casted to int, this changes +// the sign of the value, and causes the modulus operation to return a +// different result. +type unmarshalTest struct { + state string + sum string +} + +var largeUnmarshalTests = []unmarshalTest{ + // Data length: 7_102_415_735 + unmarshalTest{ + state: "md5\x01\xa5\xf7\xf0=\xd6S\x85\xd9M\n}\xc3\u0601\x89\xe7@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuv\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xa7VCw", + sum: "cddefcf74ffec709a0b45a6a987564d5", + }, + // Data length: 6_565_544_823 + unmarshalTest{ + state: "md5\x01{\xda\x1a\xc7\xc9'?\x83EX\xe0\x88q\xfeG\x18@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuv\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x87VCw", + sum: "fd9f41874ab240698e7bc9c3ae70c8e4", + }, +} + +func safeSum(h hash.Hash) (sum []byte, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("sum panic: %v", r) + } + }() + + return h.Sum(nil), nil +} + +func TestLargeHashes(t *testing.T) { + for i, test := range largeUnmarshalTests { + + h := New() + if err := h.(encoding.BinaryUnmarshaler).UnmarshalBinary([]byte(test.state)); err != nil { + t.Errorf("test %d could not unmarshal: %v", i, err) + continue + } + + sum, err := safeSum(h) + if err != nil { + t.Errorf("test %d could not sum: %v", i, err) + continue + } + + if fmt.Sprintf("%x", sum) != test.sum { + t.Errorf("test %d sum mismatch: expect %s got %x", i, test.sum, sum) + } + } +} + var bench = New() var buf = make([]byte, 8192+1) var sum = make([]byte, bench.Size()) diff --git a/libgo/go/crypto/md5/md5block.go b/libgo/go/crypto/md5/md5block.go index 8ac32ffeb78..4ff289e860f 100644 --- a/libgo/go/crypto/md5/md5block.go +++ b/libgo/go/crypto/md5/md5block.go @@ -2,263 +2,124 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Code generated by go run gen.go -full -output md5block.go; DO NOT EDIT. +// Code generated by go run gen.go -output md5block.go; DO NOT EDIT. package md5 import ( - "runtime" - "unsafe" + "encoding/binary" + "math/bits" ) -const x86 = runtime.GOARCH == "amd64" || runtime.GOARCH == "386" - -var littleEndian bool - -func init() { - x := uint32(0x04030201) - y := [4]byte{0x1, 0x2, 0x3, 0x4} - littleEndian = *(*[4]byte)(unsafe.Pointer(&x)) == y -} - func blockGeneric(dig *digest, p []byte) { - a := dig.s[0] - b := dig.s[1] - c := dig.s[2] - d := dig.s[3] - var X *[16]uint32 - var xbuf [16]uint32 - for len(p) >= chunk { - aa, bb, cc, dd := a, b, c, d - - // This is a constant condition - it is not evaluated on each iteration. - if x86 { - // MD5 was designed so that x86 processors can just iterate - // over the block data directly as uint32s, and we generate - // less code and run 1.3x faster if we take advantage of that. - // My apologies. - X = (*[16]uint32)(unsafe.Pointer(&p[0])) - } else if littleEndian && uintptr(unsafe.Pointer(&p[0]))&(unsafe.Alignof(uint32(0))-1) == 0 { - X = (*[16]uint32)(unsafe.Pointer(&p[0])) - } else { - X = &xbuf - j := 0 - for i := 0; i < 16; i++ { - X[i&15] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24 - j += 4 - } - } - - // Round 1. - - a += (((c ^ d) & b) ^ d) + X[0] + 3614090360 - a = a<<7 | a>>(32-7) + b - - d += (((b ^ c) & a) ^ c) + X[1] + 3905402710 - d = d<<12 | d>>(32-12) + a - - c += (((a ^ b) & d) ^ b) + X[2] + 606105819 - c = c<<17 | c>>(32-17) + d - - b += (((d ^ a) & c) ^ a) + X[3] + 3250441966 - b = b<<22 | b>>(32-22) + c - - a += (((c ^ d) & b) ^ d) + X[4] + 4118548399 - a = a<<7 | a>>(32-7) + b - - d += (((b ^ c) & a) ^ c) + X[5] + 1200080426 - d = d<<12 | d>>(32-12) + a - - c += (((a ^ b) & d) ^ b) + X[6] + 2821735955 - c = c<<17 | c>>(32-17) + d - - b += (((d ^ a) & c) ^ a) + X[7] + 4249261313 - b = b<<22 | b>>(32-22) + c - - a += (((c ^ d) & b) ^ d) + X[8] + 1770035416 - a = a<<7 | a>>(32-7) + b - - d += (((b ^ c) & a) ^ c) + X[9] + 2336552879 - d = d<<12 | d>>(32-12) + a - - c += (((a ^ b) & d) ^ b) + X[10] + 4294925233 - c = c<<17 | c>>(32-17) + d - - b += (((d ^ a) & c) ^ a) + X[11] + 2304563134 - b = b<<22 | b>>(32-22) + c - - a += (((c ^ d) & b) ^ d) + X[12] + 1804603682 - a = a<<7 | a>>(32-7) + b - - d += (((b ^ c) & a) ^ c) + X[13] + 4254626195 - d = d<<12 | d>>(32-12) + a - - c += (((a ^ b) & d) ^ b) + X[14] + 2792965006 - c = c<<17 | c>>(32-17) + d - - b += (((d ^ a) & c) ^ a) + X[15] + 1236535329 - b = b<<22 | b>>(32-22) + c - - // Round 2. - - a += (((b ^ c) & d) ^ c) + X[(1+5*0)&15] + 4129170786 - a = a<<5 | a>>(32-5) + b - - d += (((a ^ b) & c) ^ b) + X[(1+5*1)&15] + 3225465664 - d = d<<9 | d>>(32-9) + a - - c += (((d ^ a) & b) ^ a) + X[(1+5*2)&15] + 643717713 - c = c<<14 | c>>(32-14) + d - - b += (((c ^ d) & a) ^ d) + X[(1+5*3)&15] + 3921069994 - b = b<<20 | b>>(32-20) + c - - a += (((b ^ c) & d) ^ c) + X[(1+5*4)&15] + 3593408605 - a = a<<5 | a>>(32-5) + b - - d += (((a ^ b) & c) ^ b) + X[(1+5*5)&15] + 38016083 - d = d<<9 | d>>(32-9) + a - - c += (((d ^ a) & b) ^ a) + X[(1+5*6)&15] + 3634488961 - c = c<<14 | c>>(32-14) + d - - b += (((c ^ d) & a) ^ d) + X[(1+5*7)&15] + 3889429448 - b = b<<20 | b>>(32-20) + c - - a += (((b ^ c) & d) ^ c) + X[(1+5*8)&15] + 568446438 - a = a<<5 | a>>(32-5) + b - - d += (((a ^ b) & c) ^ b) + X[(1+5*9)&15] + 3275163606 - d = d<<9 | d>>(32-9) + a - - c += (((d ^ a) & b) ^ a) + X[(1+5*10)&15] + 4107603335 - c = c<<14 | c>>(32-14) + d - - b += (((c ^ d) & a) ^ d) + X[(1+5*11)&15] + 1163531501 - b = b<<20 | b>>(32-20) + c - - a += (((b ^ c) & d) ^ c) + X[(1+5*12)&15] + 2850285829 - a = a<<5 | a>>(32-5) + b + // load state + a, b, c, d := dig.s[0], dig.s[1], dig.s[2], dig.s[3] - d += (((a ^ b) & c) ^ b) + X[(1+5*13)&15] + 4243563512 - d = d<<9 | d>>(32-9) + a + for i := 0; i <= len(p)-BlockSize; i += BlockSize { + // eliminate bounds checks on p + q := p[i:] + q = q[:BlockSize:BlockSize] - c += (((d ^ a) & b) ^ a) + X[(1+5*14)&15] + 1735328473 - c = c<<14 | c>>(32-14) + d - - b += (((c ^ d) & a) ^ d) + X[(1+5*15)&15] + 2368359562 - b = b<<20 | b>>(32-20) + c - - // Round 3. - - a += (b ^ c ^ d) + X[(5+3*0)&15] + 4294588738 - a = a<<4 | a>>(32-4) + b - - d += (a ^ b ^ c) + X[(5+3*1)&15] + 2272392833 - d = d<<11 | d>>(32-11) + a - - c += (d ^ a ^ b) + X[(5+3*2)&15] + 1839030562 - c = c<<16 | c>>(32-16) + d - - b += (c ^ d ^ a) + X[(5+3*3)&15] + 4259657740 - b = b<<23 | b>>(32-23) + c - - a += (b ^ c ^ d) + X[(5+3*4)&15] + 2763975236 - a = a<<4 | a>>(32-4) + b - - d += (a ^ b ^ c) + X[(5+3*5)&15] + 1272893353 - d = d<<11 | d>>(32-11) + a - - c += (d ^ a ^ b) + X[(5+3*6)&15] + 4139469664 - c = c<<16 | c>>(32-16) + d - - b += (c ^ d ^ a) + X[(5+3*7)&15] + 3200236656 - b = b<<23 | b>>(32-23) + c - - a += (b ^ c ^ d) + X[(5+3*8)&15] + 681279174 - a = a<<4 | a>>(32-4) + b - - d += (a ^ b ^ c) + X[(5+3*9)&15] + 3936430074 - d = d<<11 | d>>(32-11) + a - - c += (d ^ a ^ b) + X[(5+3*10)&15] + 3572445317 - c = c<<16 | c>>(32-16) + d - - b += (c ^ d ^ a) + X[(5+3*11)&15] + 76029189 - b = b<<23 | b>>(32-23) + c - - a += (b ^ c ^ d) + X[(5+3*12)&15] + 3654602809 - a = a<<4 | a>>(32-4) + b - - d += (a ^ b ^ c) + X[(5+3*13)&15] + 3873151461 - d = d<<11 | d>>(32-11) + a - - c += (d ^ a ^ b) + X[(5+3*14)&15] + 530742520 - c = c<<16 | c>>(32-16) + d - - b += (c ^ d ^ a) + X[(5+3*15)&15] + 3299628645 - b = b<<23 | b>>(32-23) + c - - // Round 4. - - a += (c ^ (b | ^d)) + X[(7*0)&15] + 4096336452 - a = a<<6 | a>>(32-6) + b - - d += (b ^ (a | ^c)) + X[(7*1)&15] + 1126891415 - d = d<<10 | d>>(32-10) + a - - c += (a ^ (d | ^b)) + X[(7*2)&15] + 2878612391 - c = c<<15 | c>>(32-15) + d - - b += (d ^ (c | ^a)) + X[(7*3)&15] + 4237533241 - b = b<<21 | b>>(32-21) + c - - a += (c ^ (b | ^d)) + X[(7*4)&15] + 1700485571 - a = a<<6 | a>>(32-6) + b - - d += (b ^ (a | ^c)) + X[(7*5)&15] + 2399980690 - d = d<<10 | d>>(32-10) + a - - c += (a ^ (d | ^b)) + X[(7*6)&15] + 4293915773 - c = c<<15 | c>>(32-15) + d - - b += (d ^ (c | ^a)) + X[(7*7)&15] + 2240044497 - b = b<<21 | b>>(32-21) + c - - a += (c ^ (b | ^d)) + X[(7*8)&15] + 1873313359 - a = a<<6 | a>>(32-6) + b - - d += (b ^ (a | ^c)) + X[(7*9)&15] + 4264355552 - d = d<<10 | d>>(32-10) + a - - c += (a ^ (d | ^b)) + X[(7*10)&15] + 2734768916 - c = c<<15 | c>>(32-15) + d - - b += (d ^ (c | ^a)) + X[(7*11)&15] + 1309151649 - b = b<<21 | b>>(32-21) + c - - a += (c ^ (b | ^d)) + X[(7*12)&15] + 4149444226 - a = a<<6 | a>>(32-6) + b - - d += (b ^ (a | ^c)) + X[(7*13)&15] + 3174756917 - d = d<<10 | d>>(32-10) + a - - c += (a ^ (d | ^b)) + X[(7*14)&15] + 718787259 - c = c<<15 | c>>(32-15) + d - - b += (d ^ (c | ^a)) + X[(7*15)&15] + 3951481745 - b = b<<21 | b>>(32-21) + c + // save current state + aa, bb, cc, dd := a, b, c, d + // load input block + x0 := binary.LittleEndian.Uint32(q[4*0x0:]) + x1 := binary.LittleEndian.Uint32(q[4*0x1:]) + x2 := binary.LittleEndian.Uint32(q[4*0x2:]) + x3 := binary.LittleEndian.Uint32(q[4*0x3:]) + x4 := binary.LittleEndian.Uint32(q[4*0x4:]) + x5 := binary.LittleEndian.Uint32(q[4*0x5:]) + x6 := binary.LittleEndian.Uint32(q[4*0x6:]) + x7 := binary.LittleEndian.Uint32(q[4*0x7:]) + x8 := binary.LittleEndian.Uint32(q[4*0x8:]) + x9 := binary.LittleEndian.Uint32(q[4*0x9:]) + xa := binary.LittleEndian.Uint32(q[4*0xa:]) + xb := binary.LittleEndian.Uint32(q[4*0xb:]) + xc := binary.LittleEndian.Uint32(q[4*0xc:]) + xd := binary.LittleEndian.Uint32(q[4*0xd:]) + xe := binary.LittleEndian.Uint32(q[4*0xe:]) + xf := binary.LittleEndian.Uint32(q[4*0xf:]) + + // round 1 + a = b + bits.RotateLeft32((((c^d)&b)^d)+a+x0+0xd76aa478, 7) + d = a + bits.RotateLeft32((((b^c)&a)^c)+d+x1+0xe8c7b756, 12) + c = d + bits.RotateLeft32((((a^b)&d)^b)+c+x2+0x242070db, 17) + b = c + bits.RotateLeft32((((d^a)&c)^a)+b+x3+0xc1bdceee, 22) + a = b + bits.RotateLeft32((((c^d)&b)^d)+a+x4+0xf57c0faf, 7) + d = a + bits.RotateLeft32((((b^c)&a)^c)+d+x5+0x4787c62a, 12) + c = d + bits.RotateLeft32((((a^b)&d)^b)+c+x6+0xa8304613, 17) + b = c + bits.RotateLeft32((((d^a)&c)^a)+b+x7+0xfd469501, 22) + a = b + bits.RotateLeft32((((c^d)&b)^d)+a+x8+0x698098d8, 7) + d = a + bits.RotateLeft32((((b^c)&a)^c)+d+x9+0x8b44f7af, 12) + c = d + bits.RotateLeft32((((a^b)&d)^b)+c+xa+0xffff5bb1, 17) + b = c + bits.RotateLeft32((((d^a)&c)^a)+b+xb+0x895cd7be, 22) + a = b + bits.RotateLeft32((((c^d)&b)^d)+a+xc+0x6b901122, 7) + d = a + bits.RotateLeft32((((b^c)&a)^c)+d+xd+0xfd987193, 12) + c = d + bits.RotateLeft32((((a^b)&d)^b)+c+xe+0xa679438e, 17) + b = c + bits.RotateLeft32((((d^a)&c)^a)+b+xf+0x49b40821, 22) + + // round 2 + a = b + bits.RotateLeft32((((b^c)&d)^c)+a+x1+0xf61e2562, 5) + d = a + bits.RotateLeft32((((a^b)&c)^b)+d+x6+0xc040b340, 9) + c = d + bits.RotateLeft32((((d^a)&b)^a)+c+xb+0x265e5a51, 14) + b = c + bits.RotateLeft32((((c^d)&a)^d)+b+x0+0xe9b6c7aa, 20) + a = b + bits.RotateLeft32((((b^c)&d)^c)+a+x5+0xd62f105d, 5) + d = a + bits.RotateLeft32((((a^b)&c)^b)+d+xa+0x02441453, 9) + c = d + bits.RotateLeft32((((d^a)&b)^a)+c+xf+0xd8a1e681, 14) + b = c + bits.RotateLeft32((((c^d)&a)^d)+b+x4+0xe7d3fbc8, 20) + a = b + bits.RotateLeft32((((b^c)&d)^c)+a+x9+0x21e1cde6, 5) + d = a + bits.RotateLeft32((((a^b)&c)^b)+d+xe+0xc33707d6, 9) + c = d + bits.RotateLeft32((((d^a)&b)^a)+c+x3+0xf4d50d87, 14) + b = c + bits.RotateLeft32((((c^d)&a)^d)+b+x8+0x455a14ed, 20) + a = b + bits.RotateLeft32((((b^c)&d)^c)+a+xd+0xa9e3e905, 5) + d = a + bits.RotateLeft32((((a^b)&c)^b)+d+x2+0xfcefa3f8, 9) + c = d + bits.RotateLeft32((((d^a)&b)^a)+c+x7+0x676f02d9, 14) + b = c + bits.RotateLeft32((((c^d)&a)^d)+b+xc+0x8d2a4c8a, 20) + + // round 3 + a = b + bits.RotateLeft32((b^c^d)+a+x5+0xfffa3942, 4) + d = a + bits.RotateLeft32((a^b^c)+d+x8+0x8771f681, 11) + c = d + bits.RotateLeft32((d^a^b)+c+xb+0x6d9d6122, 16) + b = c + bits.RotateLeft32((c^d^a)+b+xe+0xfde5380c, 23) + a = b + bits.RotateLeft32((b^c^d)+a+x1+0xa4beea44, 4) + d = a + bits.RotateLeft32((a^b^c)+d+x4+0x4bdecfa9, 11) + c = d + bits.RotateLeft32((d^a^b)+c+x7+0xf6bb4b60, 16) + b = c + bits.RotateLeft32((c^d^a)+b+xa+0xbebfbc70, 23) + a = b + bits.RotateLeft32((b^c^d)+a+xd+0x289b7ec6, 4) + d = a + bits.RotateLeft32((a^b^c)+d+x0+0xeaa127fa, 11) + c = d + bits.RotateLeft32((d^a^b)+c+x3+0xd4ef3085, 16) + b = c + bits.RotateLeft32((c^d^a)+b+x6+0x04881d05, 23) + a = b + bits.RotateLeft32((b^c^d)+a+x9+0xd9d4d039, 4) + d = a + bits.RotateLeft32((a^b^c)+d+xc+0xe6db99e5, 11) + c = d + bits.RotateLeft32((d^a^b)+c+xf+0x1fa27cf8, 16) + b = c + bits.RotateLeft32((c^d^a)+b+x2+0xc4ac5665, 23) + + // round 4 + a = b + bits.RotateLeft32((c^(b|^d))+a+x0+0xf4292244, 6) + d = a + bits.RotateLeft32((b^(a|^c))+d+x7+0x432aff97, 10) + c = d + bits.RotateLeft32((a^(d|^b))+c+xe+0xab9423a7, 15) + b = c + bits.RotateLeft32((d^(c|^a))+b+x5+0xfc93a039, 21) + a = b + bits.RotateLeft32((c^(b|^d))+a+xc+0x655b59c3, 6) + d = a + bits.RotateLeft32((b^(a|^c))+d+x3+0x8f0ccc92, 10) + c = d + bits.RotateLeft32((a^(d|^b))+c+xa+0xffeff47d, 15) + b = c + bits.RotateLeft32((d^(c|^a))+b+x1+0x85845dd1, 21) + a = b + bits.RotateLeft32((c^(b|^d))+a+x8+0x6fa87e4f, 6) + d = a + bits.RotateLeft32((b^(a|^c))+d+xf+0xfe2ce6e0, 10) + c = d + bits.RotateLeft32((a^(d|^b))+c+x6+0xa3014314, 15) + b = c + bits.RotateLeft32((d^(c|^a))+b+xd+0x4e0811a1, 21) + a = b + bits.RotateLeft32((c^(b|^d))+a+x4+0xf7537e82, 6) + d = a + bits.RotateLeft32((b^(a|^c))+d+xb+0xbd3af235, 10) + c = d + bits.RotateLeft32((a^(d|^b))+c+x2+0x2ad7d2bb, 15) + b = c + bits.RotateLeft32((d^(c|^a))+b+x9+0xeb86d391, 21) + + // add saved state a += aa b += bb c += cc d += dd - - p = p[chunk:] } - dig.s[0] = a - dig.s[1] = b - dig.s[2] = c - dig.s[3] = d + // save state + dig.s[0], dig.s[1], dig.s[2], dig.s[3] = a, b, c, d } diff --git a/libgo/go/crypto/md5/md5block_decl.go b/libgo/go/crypto/md5/md5block_decl.go index 5f9d7aba487..761398f38e9 100644 --- a/libgo/go/crypto/md5/md5block_decl.go +++ b/libgo/go/crypto/md5/md5block_decl.go @@ -3,10 +3,12 @@ // license that can be found in the LICENSE file. // +build ignore -// -build amd64 amd64p32 386 arm ppc64le s390x arm64 +// +build amd64 amd64p32 386 arm ppc64le ppc64 s390x arm64 package md5 +const haveAsm = true + //go:noescape func block(dig *digest, p []byte) diff --git a/libgo/go/crypto/md5/md5block_generic.go b/libgo/go/crypto/md5/md5block_generic.go index c580bc6d094..69c4456a4bd 100644 --- a/libgo/go/crypto/md5/md5block_generic.go +++ b/libgo/go/crypto/md5/md5block_generic.go @@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// -build !amd64,!amd64p32,!386,!arm,!ppc64le,!s390x,!arm64 +// -build !amd64,!amd64p32,!386,!arm,!ppc64le,!ppc64,!s390x,!arm64 package md5 +const haveAsm = false + var block = blockGeneric |