[dev.boringcrypto] cmd/internal/notsha256: add new package

Package notsha256 implements the NOTSHA256 hash,
defined as bitwise NOT of SHA-256.

It will be used from the Go compiler toolchain where an
arbitrary hash is needed and the code currently reaches
for MD5, SHA1, or SHA256. The problem with all of those
is that when we add GOEXPERIMENT=boringcrypto, the
bootstrap process will not converge if the compiler itself
depends on the boringcrypto cgo code.
Using notsha256 avoids boringcrypto.

It is possible that I don't fully understand the convergence
problem and that there is a way to make the compiler converge
when using cgo, but keeping cgo out of the compiler seems safest.
It also makes clear that (except for the hack in codesign)
the code using this package doesn't care which hash is used.

For #51940.

Change-Id: Ie7c661183eacf8413a9d2074c96cbb9361e125ef
Reviewed-on: https://go-review.googlesource.com/c/go/+/402594
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/src/cmd/internal/notsha256/example_test.go b/src/cmd/internal/notsha256/example_test.go
new file mode 100644
index 0000000..06e9c37
--- /dev/null
+++ b/src/cmd/internal/notsha256/example_test.go
@@ -0,0 +1,41 @@
+// Copyright 2016 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 notsha256_test
+
+import (
+	"crypto/sha256"
+	"fmt"
+	"io"
+	"log"
+	"os"
+)
+
+func ExampleSum256() {
+	sum := sha256.Sum256([]byte("hello world\n"))
+	fmt.Printf("%x", sum)
+	// Output: a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192a447
+}
+
+func ExampleNew() {
+	h := sha256.New()
+	h.Write([]byte("hello world\n"))
+	fmt.Printf("%x", h.Sum(nil))
+	// Output: a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192a447
+}
+
+func ExampleNew_file() {
+	f, err := os.Open("file.txt")
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer f.Close()
+
+	h := sha256.New()
+	if _, err := io.Copy(h, f); err != nil {
+		log.Fatal(err)
+	}
+
+	fmt.Printf("%x", h.Sum(nil))
+}
diff --git a/src/cmd/internal/notsha256/sha256.go b/src/cmd/internal/notsha256/sha256.go
new file mode 100644
index 0000000..080b344
--- /dev/null
+++ b/src/cmd/internal/notsha256/sha256.go
@@ -0,0 +1,141 @@
+// 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 notsha256 implements the NOTSHA256 algorithm,
+// a hash defined as bitwise NOT of SHA256.
+// It is used in situations where exact fidelity to SHA256 is unnecessary.
+// In particular, it is used in the compiler toolchain,
+// which cannot depend directly on cgo when GOEXPERIMENT=boringcrypto
+// (and in that mode the real sha256 uses cgo).
+package notsha256
+
+import (
+	"encoding/binary"
+	"hash"
+)
+
+// The size of a checksum in bytes.
+const Size = 32
+
+// The blocksize in bytes.
+const BlockSize = 64
+
+const (
+	chunk = 64
+	init0 = 0x6A09E667
+	init1 = 0xBB67AE85
+	init2 = 0x3C6EF372
+	init3 = 0xA54FF53A
+	init4 = 0x510E527F
+	init5 = 0x9B05688C
+	init6 = 0x1F83D9AB
+	init7 = 0x5BE0CD19
+)
+
+// digest represents the partial evaluation of a checksum.
+type digest struct {
+	h   [8]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
+	d.h[5] = init5
+	d.h[6] = init6
+	d.h[7] = init7
+	d.nx = 0
+	d.len = 0
+}
+
+// New returns a new hash.Hash computing the NOTSHA256 checksum.
+// state of the hash.
+func New() hash.Hash {
+	d := new(digest)
+	d.Reset()
+	return d
+}
+
+func (d *digest) Size() int {
+	return Size
+}
+
+func (d *digest) BlockSize() int { return BlockSize }
+
+func (d *digest) Write(p []byte) (nn int, err error) {
+	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[:])
+			d.nx = 0
+		}
+		p = p[n:]
+	}
+	if len(p) >= chunk {
+		n := len(p) &^ (chunk - 1)
+		block(d, p[:n])
+		p = p[n:]
+	}
+	if len(p) > 0 {
+		d.nx = copy(d.x[:], p)
+	}
+	return
+}
+
+func (d *digest) Sum(in []byte) []byte {
+	// Make a copy of d so that caller can keep writing and summing.
+	d0 := *d
+	hash := d0.checkSum()
+	return append(in, hash[:]...)
+}
+
+func (d *digest) checkSum() [Size]byte {
+	len := d.len
+	// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
+	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
+	binary.BigEndian.PutUint64(tmp[:], len)
+	d.Write(tmp[0:8])
+
+	if d.nx != 0 {
+		panic("d.nx != 0")
+	}
+
+	var digest [Size]byte
+
+	binary.BigEndian.PutUint32(digest[0:], d.h[0]^0xFFFFFFFF)
+	binary.BigEndian.PutUint32(digest[4:], d.h[1]^0xFFFFFFFF)
+	binary.BigEndian.PutUint32(digest[8:], d.h[2]^0xFFFFFFFF)
+	binary.BigEndian.PutUint32(digest[12:], d.h[3]^0xFFFFFFFF)
+	binary.BigEndian.PutUint32(digest[16:], d.h[4]^0xFFFFFFFF)
+	binary.BigEndian.PutUint32(digest[20:], d.h[5]^0xFFFFFFFF)
+	binary.BigEndian.PutUint32(digest[24:], d.h[6]^0xFFFFFFFF)
+	binary.BigEndian.PutUint32(digest[28:], d.h[7]^0xFFFFFFFF)
+
+	return digest
+}
+
+// Sum256 returns the SHA256 checksum of the data.
+func Sum256(data []byte) [Size]byte {
+	var d digest
+	d.Reset()
+	d.Write(data)
+	return d.checkSum()
+}
diff --git a/src/cmd/internal/notsha256/sha256_test.go b/src/cmd/internal/notsha256/sha256_test.go
new file mode 100644
index 0000000..fa38e56
--- /dev/null
+++ b/src/cmd/internal/notsha256/sha256_test.go
@@ -0,0 +1,175 @@
+// 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.
+
+// SHA256 hash algorithm. See FIPS 180-2.
+
+package notsha256
+
+import (
+	"crypto/rand"
+	"fmt"
+	"io"
+	"strings"
+	"testing"
+)
+
+type sha256Test struct {
+	out    string
+	in     string
+	unused string // marshal state, to keep table in sync with crypto/sha256
+}
+
+var golden = []sha256Test{
+	{"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+	{"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "a", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
+	{"fb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603", "ab", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
+	{"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", "abc", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
+	{"88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589", "abcd", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"},
+	{"36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c", "abcde", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"},
+	{"bef57ec7f53a6d40beb640a780a639c83bc29ac8a9816f1fc6c5c6dcd93c4721", "abcdef", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"},
+	{"7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a", "abcdefg", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"},
+	{"9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab", "abcdefgh", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"},
+	{"19cc02f26df43cc571bc9ed7b0c4d29224a3ec229529221725ef76d021c8326f", "abcdefghi", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"},
+	{"72399361da6a7754fec986dca5b7cbaf1c810a28ded4abaf56b2106d06cb78b0", "abcdefghij", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abcde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05"},
+	{"a144061c271f152da4d151034508fed1c138b8c976339de229c3bb6d4bbb4fce", "Discard medicine more than two years old.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Discard medicine mor\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14"},
+	{"6dae5caa713a10ad04b46028bf6dad68837c581616a1589a265a11288d4bb5c4", "He who has a shady past knows that nice guys finish last.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19He who has a shady past know\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"ae7a702a9509039ddbf29f0765e70d0001177914b86459284dab8b348c2dce3f", "I wouldn't marry him with a ten foot pole.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19I wouldn't marry him \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15"},
+	{"6748450b01c568586715291dfa3ee018da07d36bb7ea6f180c1af6270215c64f", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Free! Free!/A trip/to Mars/f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"14b82014ad2b11f661b5ae6a99b75105c2ffac278cd071cd6c05832793635774", "The days of the digital watch are numbered.  -Tom Stoppard", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19The days of the digital watch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d"},
+	{"7102cfd76e2e324889eece5d6c41921b1e142a4ac5a2692be78803097f6a48d8", "Nepal premier won't resign.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Nepal premier\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r"},
+	{"23b1018cd81db1d67983c5f7417c44da9deb582459e378d7a068552ea649dc9f", "For every action there is an equal and opposite government program.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19For every action there is an equa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!"},
+	{"8001f190dfb527261c4cfcab70c98e8097a7a1922129bc4096950e57c7999a5a", "His money is twice tainted: 'taint yours and 'taint mine.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19His money is twice tainted: \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+	{"8c87deb65505c3993eb24b7a150c4155e82eee6960cf0c3a8114ff736d69cad5", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19There is no reason for any individual to hav\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,"},
+	{"bfb0a67a19cdec3646498b2e0f751bddc41bba4b7f30081b0b932aad214d16d7", "It's a tiny change to the code and not completely disgusting. - Bob Manchek", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19It's a tiny change to the code and no\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%"},
+	{"7f9a0b9bf56332e19f5a0ec1ad9c1425a153da1c624868fda44561d6b74daf36", "size:  a.out:  bad magic", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19size:  a.out\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f"},
+	{"b13f81b8aad9e3666879af19886140904f7f429ef083286195982a7588858cfc", "The major problem is with sendmail.  -Mark Horton", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19The major problem is wit\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18"},
+	{"b26c38d61519e894480c70c8374ea35aa0ad05b2ae3d6674eec5f52a69305ed4", "Give me a rock, paper and scissors and I will move the world.  CCFestoon", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Give me a rock, paper and scissors a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$"},
+	{"049d5e26d4f10222cd841a119e38bd8d2e0d1129728688449575d4ff42b842c1", "If the enemy is within range, then so are you.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19If the enemy is within \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17"},
+	{"0e116838e3cc1c1a14cd045397e29b4d087aa11b0853fc69ec82e90330d60949", "It's well we cannot hear the screams/That we create in others' dreams.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19It's well we cannot hear the scream\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#"},
+	{"4f7d8eb5bcf11de2a56b971021a444aa4eafd6ecd0f307b5109e4e776cd0fe46", "You remind me of a TV show, but that's all right: I watch it anyway.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19You remind me of a TV show, but th\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\""},
+	{"61c0cc4c4bd8406d5120b3fb4ebc31ce87667c162f29468b3c779675a85aebce", "C is as portable as Stonehedge!!", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19C is as portable\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10"},
+	{"1fb2eb3688093c4a3f80cd87a5547e2ce940a4f923243a79a2a1e242220693ac", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Even if I could be Shakespeare, I think I sh\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,"},
+	{"395585ce30617b62c80b93e8208ce866d4edc811a177fdb4b82d3911d8696423", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule", "sha\x03\x93\x14\xc8z\x87\x0e\vo\xf1E\x0f\xa4V\xb2a\x00\x87\xb5ǔ\xfc\xeaV\u009eg\xbc\x17\xb1\x85њem\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B"},
+	{"4f9b189a13d030838269dce846b16a1ce9ce81fe63e65de2f636863336a98fe6", "How can you write a big system without C++?  -Paul Glick", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19How can you write a big syst\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
+}
+
+var not = strings.NewReplacer(
+	"0", "f",
+	"1", "e",
+	"2", "d",
+	"3", "c",
+	"4", "b",
+	"5", "a",
+	"6", "9",
+	"7", "8",
+	"8", "7",
+	"9", "6",
+	"a", "5",
+	"b", "4",
+	"c", "3",
+	"d", "2",
+	"e", "1",
+	"f", "0",
+)
+
+func TestGolden(t *testing.T) {
+	for i := 0; i < len(golden); i++ {
+		g := golden[i]
+		gout := not.Replace(g.out)
+		s := fmt.Sprintf("%x", Sum256([]byte(g.in)))
+		if s != gout {
+			t.Fatalf("Sum256 function: sha256(%s) = %s want %s", g.in, s, gout)
+		}
+		c := New()
+		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(nil)
+				io.WriteString(c, g.in[len(g.in)/2:])
+			}
+			s := fmt.Sprintf("%x", c.Sum(nil))
+			if s != gout {
+				t.Fatalf("sha256[%d](%s) = %s want %s", j, g.in, s, gout)
+			}
+			c.Reset()
+		}
+	}
+}
+
+func TestSize(t *testing.T) {
+	c := New()
+	if got := c.Size(); got != Size {
+		t.Errorf("Size = %d; want %d", got, Size)
+	}
+}
+
+func TestBlockSize(t *testing.T) {
+	c := New()
+	if got := c.BlockSize(); got != BlockSize {
+		t.Errorf("BlockSize = %d want %d", got, BlockSize)
+	}
+}
+
+// Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
+func TestBlockGeneric(t *testing.T) {
+	gen, asm := New().(*digest), New().(*digest)
+	buf := make([]byte, BlockSize*20) // arbitrary factor
+	rand.Read(buf)
+	blockGeneric(gen, buf)
+	block(asm, buf)
+	if *gen != *asm {
+		t.Error("block and blockGeneric resulted in different states")
+	}
+}
+
+func TestAllocations(t *testing.T) {
+	in := []byte("hello, world!")
+	out := make([]byte, 0, Size)
+	h := New()
+	n := int(testing.AllocsPerRun(10, func() {
+		h.Reset()
+		h.Write(in)
+		out = h.Sum(out[:0])
+	}))
+	if n > 0 {
+		t.Errorf("allocs = %d, want 0", n)
+	}
+}
+
+var bench = New()
+var buf = make([]byte, 8192)
+
+func benchmarkSize(b *testing.B, size int) {
+	sum := make([]byte, bench.Size())
+	b.Run("New", func(b *testing.B) {
+		b.ReportAllocs()
+		b.SetBytes(int64(size))
+		for i := 0; i < b.N; i++ {
+			bench.Reset()
+			bench.Write(buf[:size])
+			bench.Sum(sum[:0])
+		}
+	})
+	b.Run("Sum256", func(b *testing.B) {
+		b.ReportAllocs()
+		b.SetBytes(int64(size))
+		for i := 0; i < b.N; i++ {
+			Sum256(buf[:size])
+		}
+	})
+}
+
+func BenchmarkHash8Bytes(b *testing.B) {
+	benchmarkSize(b, 8)
+}
+
+func BenchmarkHash1K(b *testing.B) {
+	benchmarkSize(b, 1024)
+}
+
+func BenchmarkHash8K(b *testing.B) {
+	benchmarkSize(b, 8192)
+}
diff --git a/src/cmd/internal/notsha256/sha256block.go b/src/cmd/internal/notsha256/sha256block.go
new file mode 100644
index 0000000..57cdf2e
--- /dev/null
+++ b/src/cmd/internal/notsha256/sha256block.go
@@ -0,0 +1,128 @@
+// 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.
+
+// SHA256 block step.
+// In its own file so that a faster assembly or C version
+// can be substituted easily.
+
+package notsha256
+
+import "math/bits"
+
+var _K = []uint32{
+	0x428a2f98,
+	0x71374491,
+	0xb5c0fbcf,
+	0xe9b5dba5,
+	0x3956c25b,
+	0x59f111f1,
+	0x923f82a4,
+	0xab1c5ed5,
+	0xd807aa98,
+	0x12835b01,
+	0x243185be,
+	0x550c7dc3,
+	0x72be5d74,
+	0x80deb1fe,
+	0x9bdc06a7,
+	0xc19bf174,
+	0xe49b69c1,
+	0xefbe4786,
+	0x0fc19dc6,
+	0x240ca1cc,
+	0x2de92c6f,
+	0x4a7484aa,
+	0x5cb0a9dc,
+	0x76f988da,
+	0x983e5152,
+	0xa831c66d,
+	0xb00327c8,
+	0xbf597fc7,
+	0xc6e00bf3,
+	0xd5a79147,
+	0x06ca6351,
+	0x14292967,
+	0x27b70a85,
+	0x2e1b2138,
+	0x4d2c6dfc,
+	0x53380d13,
+	0x650a7354,
+	0x766a0abb,
+	0x81c2c92e,
+	0x92722c85,
+	0xa2bfe8a1,
+	0xa81a664b,
+	0xc24b8b70,
+	0xc76c51a3,
+	0xd192e819,
+	0xd6990624,
+	0xf40e3585,
+	0x106aa070,
+	0x19a4c116,
+	0x1e376c08,
+	0x2748774c,
+	0x34b0bcb5,
+	0x391c0cb3,
+	0x4ed8aa4a,
+	0x5b9cca4f,
+	0x682e6ff3,
+	0x748f82ee,
+	0x78a5636f,
+	0x84c87814,
+	0x8cc70208,
+	0x90befffa,
+	0xa4506ceb,
+	0xbef9a3f7,
+	0xc67178f2,
+}
+
+func blockGeneric(dig *digest, p []byte) {
+	var w [64]uint32
+	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 {
+		// 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 < 64; i++ {
+			v1 := w[i-2]
+			t1 := (bits.RotateLeft32(v1, -17)) ^ (bits.RotateLeft32(v1, -19)) ^ (v1 >> 10)
+			v2 := w[i-15]
+			t2 := (bits.RotateLeft32(v2, -7)) ^ (bits.RotateLeft32(v2, -18)) ^ (v2 >> 3)
+			w[i] = t1 + w[i-7] + t2 + w[i-16]
+		}
+
+		a, b, c, d, e, f, g, h := h0, h1, h2, h3, h4, h5, h6, h7
+
+		for i := 0; i < 64; i++ {
+			t1 := h + ((bits.RotateLeft32(e, -6)) ^ (bits.RotateLeft32(e, -11)) ^ (bits.RotateLeft32(e, -25))) + ((e & f) ^ (^e & g)) + _K[i] + w[i]
+
+			t2 := ((bits.RotateLeft32(a, -2)) ^ (bits.RotateLeft32(a, -13)) ^ (bits.RotateLeft32(a, -22))) + ((a & b) ^ (a & c) ^ (b & c))
+
+			h = g
+			g = f
+			f = e
+			e = d + t1
+			d = c
+			c = b
+			b = a
+			a = t1 + t2
+		}
+
+		h0 += a
+		h1 += b
+		h2 += c
+		h3 += d
+		h4 += e
+		h5 += f
+		h6 += g
+		h7 += h
+
+		p = p[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
+}
diff --git a/src/cmd/internal/notsha256/sha256block_386.s b/src/cmd/internal/notsha256/sha256block_386.s
new file mode 100644
index 0000000..086a0ab
--- /dev/null
+++ b/src/cmd/internal/notsha256/sha256block_386.s
@@ -0,0 +1,283 @@
+// 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.
+
+// SHA256 block routine. See sha256block.go for Go equivalent.
+//
+// The algorithm is detailed in FIPS 180-4:
+//
+//  https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
+//
+// Wt = Mt; for 0 <= t <= 15
+// Wt = SIGMA1(Wt-2) + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
+//
+// a = H0
+// b = H1
+// c = H2
+// d = H3
+// e = H4
+// f = H5
+// g = H6
+// h = H7
+//
+// for t = 0 to 63 {
+//    T1 = h + BIGSIGMA1(e) + Ch(e,f,g) + Kt + Wt
+//    T2 = BIGSIGMA0(a) + Maj(a,b,c)
+//    h = g
+//    g = f
+//    f = e
+//    e = d + T1
+//    d = c
+//    c = b
+//    b = a
+//    a = T1 + T2
+// }
+//
+// H0 = a + H0
+// H1 = b + H1
+// H2 = c + H2
+// H3 = d + H3
+// H4 = e + H4
+// H5 = f + H5
+// H6 = g + H6
+// H7 = h + H7
+
+// Wt = Mt; for 0 <= t <= 15
+#define MSGSCHEDULE0(index) \
+	MOVL	(index*4)(SI), AX; \
+	BSWAPL	AX; \
+	MOVL	AX, (index*4)(BP)
+
+// Wt = SIGMA1(Wt-2) + Wt-7 + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
+//   SIGMA0(x) = ROTR(7,x) XOR ROTR(18,x) XOR SHR(3,x)
+//   SIGMA1(x) = ROTR(17,x) XOR ROTR(19,x) XOR SHR(10,x)
+#define MSGSCHEDULE1(index) \
+	MOVL	((index-2)*4)(BP), AX; \
+	MOVL	AX, CX; \
+	RORL	$17, AX; \
+	MOVL	CX, DX; \
+	RORL	$19, CX; \
+	SHRL	$10, DX; \
+	MOVL	((index-15)*4)(BP), BX; \
+	XORL	CX, AX; \
+	MOVL	BX, CX; \
+	XORL	DX, AX; \
+	RORL	$7, BX; \
+	MOVL	CX, DX; \
+	SHRL	$3, DX; \
+	RORL	$18, CX; \
+	ADDL	((index-7)*4)(BP), AX; \
+	XORL	CX, BX; \
+	XORL	DX, BX; \
+	ADDL	((index-16)*4)(BP), BX; \
+	ADDL	BX, AX; \
+	MOVL	AX, ((index)*4)(BP)
+
+// Calculate T1 in AX - uses AX, BX, CX and DX registers.
+// Wt is passed in AX.
+//   T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + Kt + Wt
+//     BIGSIGMA1(x) = ROTR(6,x) XOR ROTR(11,x) XOR ROTR(25,x)
+//     Ch(x, y, z) = (x AND y) XOR (NOT x AND z)
+#define SHA256T1(const, e, f, g, h) \
+	MOVL	(h*4)(DI), BX; \
+	ADDL	AX, BX; \
+	MOVL	(e*4)(DI), AX; \
+	ADDL	$const, BX; \
+	MOVL	(e*4)(DI), CX; \
+	RORL	$6, AX; \
+	MOVL	(e*4)(DI), DX; \
+	RORL	$11, CX; \
+	XORL	CX, AX; \
+	MOVL	(e*4)(DI), CX; \
+	RORL	$25, DX; \
+	ANDL	(f*4)(DI), CX; \
+	XORL	AX, DX; \
+	MOVL	(e*4)(DI), AX; \
+	NOTL	AX; \
+	ADDL	DX, BX; \
+	ANDL	(g*4)(DI), AX; \
+	XORL	CX, AX; \
+	ADDL	BX, AX
+
+// Calculate T2 in BX - uses AX, BX, CX and DX registers.
+//   T2 = BIGSIGMA0(a) + Maj(a, b, c)
+//     BIGSIGMA0(x) = ROTR(2,x) XOR ROTR(13,x) XOR ROTR(22,x)
+//     Maj(x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
+#define SHA256T2(a, b, c) \
+	MOVL	(a*4)(DI), AX; \
+	MOVL	(c*4)(DI), BX; \
+	RORL	$2, AX; \
+	MOVL	(a*4)(DI), DX; \
+	ANDL	(b*4)(DI), BX; \
+	RORL	$13, DX; \
+	MOVL	(a*4)(DI), CX; \
+	ANDL	(c*4)(DI), CX; \
+	XORL	DX, AX; \
+	XORL	CX, BX; \
+	MOVL	(a*4)(DI), DX; \
+	MOVL	(b*4)(DI), CX; \
+	RORL	$22, DX; \
+	ANDL	(a*4)(DI), CX; \
+	XORL	CX, BX; \
+	XORL	DX, AX; \
+	ADDL	AX, BX
+
+// Calculate T1 and T2, then e = d + T1 and a = T1 + T2.
+// The values for e and a are stored in d and h, ready for rotation.
+#define SHA256ROUND(index, const, a, b, c, d, e, f, g, h) \
+	SHA256T1(const, e, f, g, h); \
+	MOVL	AX, 292(SP); \
+	SHA256T2(a, b, c); \
+	MOVL	292(SP), AX; \
+	ADDL	AX, BX; \
+	ADDL	AX, (d*4)(DI); \
+	MOVL	BX, (h*4)(DI)
+
+#define SHA256ROUND0(index, const, a, b, c, d, e, f, g, h) \
+	MSGSCHEDULE0(index); \
+	SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
+
+#define SHA256ROUND1(index, const, a, b, c, d, e, f, g, h) \
+	MSGSCHEDULE1(index); \
+	SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
+
+TEXT ·block(SB),0,$296-16
+	MOVL	p_base+4(FP), SI
+	MOVL	p_len+8(FP), DX
+	SHRL	$6, DX
+	SHLL	$6, DX
+
+	LEAL	(SI)(DX*1), DI
+	MOVL	DI, 288(SP)
+	CMPL	SI, DI
+	JEQ	end
+
+	LEAL	256(SP), DI		// variables
+
+	MOVL	dig+0(FP), BP
+	MOVL	(0*4)(BP), AX		// a = H0
+	MOVL	AX, (0*4)(DI)
+	MOVL	(1*4)(BP), BX		// b = H1
+	MOVL	BX, (1*4)(DI)
+	MOVL	(2*4)(BP), CX		// c = H2
+	MOVL	CX, (2*4)(DI)
+	MOVL	(3*4)(BP), DX		// d = H3
+	MOVL	DX, (3*4)(DI)
+	MOVL	(4*4)(BP), AX		// e = H4
+	MOVL	AX, (4*4)(DI)
+	MOVL	(5*4)(BP), BX		// f = H5
+	MOVL	BX, (5*4)(DI)
+	MOVL	(6*4)(BP), CX		// g = H6
+	MOVL	CX, (6*4)(DI)
+	MOVL	(7*4)(BP), DX		// h = H7
+	MOVL	DX, (7*4)(DI)
+
+loop:
+	MOVL	SP, BP			// message schedule
+
+	SHA256ROUND0(0, 0x428a2f98, 0, 1, 2, 3, 4, 5, 6, 7)
+	SHA256ROUND0(1, 0x71374491, 7, 0, 1, 2, 3, 4, 5, 6)
+	SHA256ROUND0(2, 0xb5c0fbcf, 6, 7, 0, 1, 2, 3, 4, 5)
+	SHA256ROUND0(3, 0xe9b5dba5, 5, 6, 7, 0, 1, 2, 3, 4)
+	SHA256ROUND0(4, 0x3956c25b, 4, 5, 6, 7, 0, 1, 2, 3)
+	SHA256ROUND0(5, 0x59f111f1, 3, 4, 5, 6, 7, 0, 1, 2)
+	SHA256ROUND0(6, 0x923f82a4, 2, 3, 4, 5, 6, 7, 0, 1)
+	SHA256ROUND0(7, 0xab1c5ed5, 1, 2, 3, 4, 5, 6, 7, 0)
+	SHA256ROUND0(8, 0xd807aa98, 0, 1, 2, 3, 4, 5, 6, 7)
+	SHA256ROUND0(9, 0x12835b01, 7, 0, 1, 2, 3, 4, 5, 6)
+	SHA256ROUND0(10, 0x243185be, 6, 7, 0, 1, 2, 3, 4, 5)
+	SHA256ROUND0(11, 0x550c7dc3, 5, 6, 7, 0, 1, 2, 3, 4)
+	SHA256ROUND0(12, 0x72be5d74, 4, 5, 6, 7, 0, 1, 2, 3)
+	SHA256ROUND0(13, 0x80deb1fe, 3, 4, 5, 6, 7, 0, 1, 2)
+	SHA256ROUND0(14, 0x9bdc06a7, 2, 3, 4, 5, 6, 7, 0, 1)
+	SHA256ROUND0(15, 0xc19bf174, 1, 2, 3, 4, 5, 6, 7, 0)
+
+	SHA256ROUND1(16, 0xe49b69c1, 0, 1, 2, 3, 4, 5, 6, 7)
+	SHA256ROUND1(17, 0xefbe4786, 7, 0, 1, 2, 3, 4, 5, 6)
+	SHA256ROUND1(18, 0x0fc19dc6, 6, 7, 0, 1, 2, 3, 4, 5)
+	SHA256ROUND1(19, 0x240ca1cc, 5, 6, 7, 0, 1, 2, 3, 4)
+	SHA256ROUND1(20, 0x2de92c6f, 4, 5, 6, 7, 0, 1, 2, 3)
+	SHA256ROUND1(21, 0x4a7484aa, 3, 4, 5, 6, 7, 0, 1, 2)
+	SHA256ROUND1(22, 0x5cb0a9dc, 2, 3, 4, 5, 6, 7, 0, 1)
+	SHA256ROUND1(23, 0x76f988da, 1, 2, 3, 4, 5, 6, 7, 0)
+	SHA256ROUND1(24, 0x983e5152, 0, 1, 2, 3, 4, 5, 6, 7)
+	SHA256ROUND1(25, 0xa831c66d, 7, 0, 1, 2, 3, 4, 5, 6)
+	SHA256ROUND1(26, 0xb00327c8, 6, 7, 0, 1, 2, 3, 4, 5)
+	SHA256ROUND1(27, 0xbf597fc7, 5, 6, 7, 0, 1, 2, 3, 4)
+	SHA256ROUND1(28, 0xc6e00bf3, 4, 5, 6, 7, 0, 1, 2, 3)
+	SHA256ROUND1(29, 0xd5a79147, 3, 4, 5, 6, 7, 0, 1, 2)
+	SHA256ROUND1(30, 0x06ca6351, 2, 3, 4, 5, 6, 7, 0, 1)
+	SHA256ROUND1(31, 0x14292967, 1, 2, 3, 4, 5, 6, 7, 0)
+	SHA256ROUND1(32, 0x27b70a85, 0, 1, 2, 3, 4, 5, 6, 7)
+	SHA256ROUND1(33, 0x2e1b2138, 7, 0, 1, 2, 3, 4, 5, 6)
+	SHA256ROUND1(34, 0x4d2c6dfc, 6, 7, 0, 1, 2, 3, 4, 5)
+	SHA256ROUND1(35, 0x53380d13, 5, 6, 7, 0, 1, 2, 3, 4)
+	SHA256ROUND1(36, 0x650a7354, 4, 5, 6, 7, 0, 1, 2, 3)
+	SHA256ROUND1(37, 0x766a0abb, 3, 4, 5, 6, 7, 0, 1, 2)
+	SHA256ROUND1(38, 0x81c2c92e, 2, 3, 4, 5, 6, 7, 0, 1)
+	SHA256ROUND1(39, 0x92722c85, 1, 2, 3, 4, 5, 6, 7, 0)
+	SHA256ROUND1(40, 0xa2bfe8a1, 0, 1, 2, 3, 4, 5, 6, 7)
+	SHA256ROUND1(41, 0xa81a664b, 7, 0, 1, 2, 3, 4, 5, 6)
+	SHA256ROUND1(42, 0xc24b8b70, 6, 7, 0, 1, 2, 3, 4, 5)
+	SHA256ROUND1(43, 0xc76c51a3, 5, 6, 7, 0, 1, 2, 3, 4)
+	SHA256ROUND1(44, 0xd192e819, 4, 5, 6, 7, 0, 1, 2, 3)
+	SHA256ROUND1(45, 0xd6990624, 3, 4, 5, 6, 7, 0, 1, 2)
+	SHA256ROUND1(46, 0xf40e3585, 2, 3, 4, 5, 6, 7, 0, 1)
+	SHA256ROUND1(47, 0x106aa070, 1, 2, 3, 4, 5, 6, 7, 0)
+	SHA256ROUND1(48, 0x19a4c116, 0, 1, 2, 3, 4, 5, 6, 7)
+	SHA256ROUND1(49, 0x1e376c08, 7, 0, 1, 2, 3, 4, 5, 6)
+	SHA256ROUND1(50, 0x2748774c, 6, 7, 0, 1, 2, 3, 4, 5)
+	SHA256ROUND1(51, 0x34b0bcb5, 5, 6, 7, 0, 1, 2, 3, 4)
+	SHA256ROUND1(52, 0x391c0cb3, 4, 5, 6, 7, 0, 1, 2, 3)
+	SHA256ROUND1(53, 0x4ed8aa4a, 3, 4, 5, 6, 7, 0, 1, 2)
+	SHA256ROUND1(54, 0x5b9cca4f, 2, 3, 4, 5, 6, 7, 0, 1)
+	SHA256ROUND1(55, 0x682e6ff3, 1, 2, 3, 4, 5, 6, 7, 0)
+	SHA256ROUND1(56, 0x748f82ee, 0, 1, 2, 3, 4, 5, 6, 7)
+	SHA256ROUND1(57, 0x78a5636f, 7, 0, 1, 2, 3, 4, 5, 6)
+	SHA256ROUND1(58, 0x84c87814, 6, 7, 0, 1, 2, 3, 4, 5)
+	SHA256ROUND1(59, 0x8cc70208, 5, 6, 7, 0, 1, 2, 3, 4)
+	SHA256ROUND1(60, 0x90befffa, 4, 5, 6, 7, 0, 1, 2, 3)
+	SHA256ROUND1(61, 0xa4506ceb, 3, 4, 5, 6, 7, 0, 1, 2)
+	SHA256ROUND1(62, 0xbef9a3f7, 2, 3, 4, 5, 6, 7, 0, 1)
+	SHA256ROUND1(63, 0xc67178f2, 1, 2, 3, 4, 5, 6, 7, 0)
+
+	MOVL	dig+0(FP), BP
+	MOVL	(0*4)(BP), AX		// H0 = a + H0
+	ADDL	(0*4)(DI), AX
+	MOVL	AX, (0*4)(DI)
+	MOVL	AX, (0*4)(BP)
+	MOVL	(1*4)(BP), BX		// H1 = b + H1
+	ADDL	(1*4)(DI), BX
+	MOVL	BX, (1*4)(DI)
+	MOVL	BX, (1*4)(BP)
+	MOVL	(2*4)(BP), CX		// H2 = c + H2
+	ADDL	(2*4)(DI), CX
+	MOVL	CX, (2*4)(DI)
+	MOVL	CX, (2*4)(BP)
+	MOVL	(3*4)(BP), DX		// H3 = d + H3
+	ADDL	(3*4)(DI), DX
+	MOVL	DX, (3*4)(DI)
+	MOVL	DX, (3*4)(BP)
+	MOVL	(4*4)(BP), AX		// H4 = e + H4
+	ADDL	(4*4)(DI), AX
+	MOVL	AX, (4*4)(DI)
+	MOVL	AX, (4*4)(BP)
+	MOVL	(5*4)(BP), BX		// H5 = f + H5
+	ADDL	(5*4)(DI), BX
+	MOVL	BX, (5*4)(DI)
+	MOVL	BX, (5*4)(BP)
+	MOVL	(6*4)(BP), CX		// H6 = g + H6
+	ADDL	(6*4)(DI), CX
+	MOVL	CX, (6*4)(DI)
+	MOVL	CX, (6*4)(BP)
+	MOVL	(7*4)(BP), DX		// H7 = h + H7
+	ADDL	(7*4)(DI), DX
+	MOVL	DX, (7*4)(DI)
+	MOVL	DX, (7*4)(BP)
+
+	ADDL	$64, SI
+	CMPL	SI, 288(SP)
+	JB	loop
+
+end:
+	RET
diff --git a/src/cmd/internal/notsha256/sha256block_amd64.go b/src/cmd/internal/notsha256/sha256block_amd64.go
new file mode 100644
index 0000000..676c4f7
--- /dev/null
+++ b/src/cmd/internal/notsha256/sha256block_amd64.go
@@ -0,0 +1,7 @@
+// Copyright 2017 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 notsha256
+
+var useAVX2 = false
diff --git a/src/cmd/internal/notsha256/sha256block_amd64.s b/src/cmd/internal/notsha256/sha256block_amd64.s
new file mode 100644
index 0000000..b2ae7c5
--- /dev/null
+++ b/src/cmd/internal/notsha256/sha256block_amd64.s
@@ -0,0 +1,424 @@
+// 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.
+
+#include "textflag.h"
+
+// SHA256 block routine. See sha256block.go for Go equivalent.
+//
+// The algorithm is detailed in FIPS 180-4:
+//
+//  https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
+
+// Wt = Mt; for 0 <= t <= 15
+// Wt = SIGMA1(Wt-2) + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
+//
+// a = H0
+// b = H1
+// c = H2
+// d = H3
+// e = H4
+// f = H5
+// g = H6
+// h = H7
+//
+// for t = 0 to 63 {
+//    T1 = h + BIGSIGMA1(e) + Ch(e,f,g) + Kt + Wt
+//    T2 = BIGSIGMA0(a) + Maj(a,b,c)
+//    h = g
+//    g = f
+//    f = e
+//    e = d + T1
+//    d = c
+//    c = b
+//    b = a
+//    a = T1 + T2
+// }
+//
+// H0 = a + H0
+// H1 = b + H1
+// H2 = c + H2
+// H3 = d + H3
+// H4 = e + H4
+// H5 = f + H5
+// H6 = g + H6
+// H7 = h + H7
+
+// Wt = Mt; for 0 <= t <= 15
+#define MSGSCHEDULE0(index) \
+	MOVL	(index*4)(SI), AX; \
+	BSWAPL	AX; \
+	MOVL	AX, (index*4)(BP)
+
+// Wt = SIGMA1(Wt-2) + Wt-7 + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
+//   SIGMA0(x) = ROTR(7,x) XOR ROTR(18,x) XOR SHR(3,x)
+//   SIGMA1(x) = ROTR(17,x) XOR ROTR(19,x) XOR SHR(10,x)
+#define MSGSCHEDULE1(index) \
+	MOVL	((index-2)*4)(BP), AX; \
+	MOVL	AX, CX; \
+	RORL	$17, AX; \
+	MOVL	CX, DX; \
+	RORL	$19, CX; \
+	SHRL	$10, DX; \
+	MOVL	((index-15)*4)(BP), BX; \
+	XORL	CX, AX; \
+	MOVL	BX, CX; \
+	XORL	DX, AX; \
+	RORL	$7, BX; \
+	MOVL	CX, DX; \
+	SHRL	$3, DX; \
+	RORL	$18, CX; \
+	ADDL	((index-7)*4)(BP), AX; \
+	XORL	CX, BX; \
+	XORL	DX, BX; \
+	ADDL	((index-16)*4)(BP), BX; \
+	ADDL	BX, AX; \
+	MOVL	AX, ((index)*4)(BP)
+
+// Calculate T1 in AX - uses AX, CX and DX registers.
+// h is also used as an accumulator. Wt is passed in AX.
+//   T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + Kt + Wt
+//     BIGSIGMA1(x) = ROTR(6,x) XOR ROTR(11,x) XOR ROTR(25,x)
+//     Ch(x, y, z) = (x AND y) XOR (NOT x AND z)
+#define SHA256T1(const, e, f, g, h) \
+	ADDL	AX, h; \
+	MOVL	e, AX; \
+	ADDL	$const, h; \
+	MOVL	e, CX; \
+	RORL	$6, AX; \
+	MOVL	e, DX; \
+	RORL	$11, CX; \
+	XORL	CX, AX; \
+	MOVL	e, CX; \
+	RORL	$25, DX; \
+	ANDL	f, CX; \
+	XORL	AX, DX; \
+	MOVL	e, AX; \
+	NOTL	AX; \
+	ADDL	DX, h; \
+	ANDL	g, AX; \
+	XORL	CX, AX; \
+	ADDL	h, AX
+
+// Calculate T2 in BX - uses BX, CX, DX and DI registers.
+//   T2 = BIGSIGMA0(a) + Maj(a, b, c)
+//     BIGSIGMA0(x) = ROTR(2,x) XOR ROTR(13,x) XOR ROTR(22,x)
+//     Maj(x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
+#define SHA256T2(a, b, c) \
+	MOVL	a, DI; \
+	MOVL	c, BX; \
+	RORL	$2, DI; \
+	MOVL	a, DX; \
+	ANDL	b, BX; \
+	RORL	$13, DX; \
+	MOVL	a, CX; \
+	ANDL	c, CX; \
+	XORL	DX, DI; \
+	XORL	CX, BX; \
+	MOVL	a, DX; \
+	MOVL	b, CX; \
+	RORL	$22, DX; \
+	ANDL	a, CX; \
+	XORL	CX, BX; \
+	XORL	DX, DI; \
+	ADDL	DI, BX
+
+// Calculate T1 and T2, then e = d + T1 and a = T1 + T2.
+// The values for e and a are stored in d and h, ready for rotation.
+#define SHA256ROUND(index, const, a, b, c, d, e, f, g, h) \
+	SHA256T1(const, e, f, g, h); \
+	SHA256T2(a, b, c); \
+	MOVL	BX, h; \
+	ADDL	AX, d; \
+	ADDL	AX, h
+
+#define SHA256ROUND0(index, const, a, b, c, d, e, f, g, h) \
+	MSGSCHEDULE0(index); \
+	SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
+
+#define SHA256ROUND1(index, const, a, b, c, d, e, f, g, h) \
+	MSGSCHEDULE1(index); \
+	SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
+
+TEXT ·block(SB), 0, $536-32
+	MOVQ p_base+8(FP), SI
+	MOVQ p_len+16(FP), DX
+	SHRQ $6, DX
+	SHLQ $6, DX
+
+	LEAQ (SI)(DX*1), DI
+	MOVQ DI, 256(SP)
+	CMPQ SI, DI
+	JEQ  end
+
+	MOVQ dig+0(FP), BP
+	MOVL (0*4)(BP), R8  // a = H0
+	MOVL (1*4)(BP), R9  // b = H1
+	MOVL (2*4)(BP), R10 // c = H2
+	MOVL (3*4)(BP), R11 // d = H3
+	MOVL (4*4)(BP), R12 // e = H4
+	MOVL (5*4)(BP), R13 // f = H5
+	MOVL (6*4)(BP), R14 // g = H6
+	MOVL (7*4)(BP), R15 // h = H7
+
+loop:
+	MOVQ SP, BP
+
+	SHA256ROUND0(0, 0x428a2f98, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND0(1, 0x71374491, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND0(2, 0xb5c0fbcf, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND0(3, 0xe9b5dba5, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND0(4, 0x3956c25b, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND0(5, 0x59f111f1, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND0(6, 0x923f82a4, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND0(7, 0xab1c5ed5, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA256ROUND0(8, 0xd807aa98, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND0(9, 0x12835b01, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND0(10, 0x243185be, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND0(11, 0x550c7dc3, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND0(12, 0x72be5d74, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND0(13, 0x80deb1fe, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND0(14, 0x9bdc06a7, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND0(15, 0xc19bf174, R9, R10, R11, R12, R13, R14, R15, R8)
+
+	SHA256ROUND1(16, 0xe49b69c1, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND1(17, 0xefbe4786, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND1(18, 0x0fc19dc6, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND1(19, 0x240ca1cc, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND1(20, 0x2de92c6f, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND1(21, 0x4a7484aa, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND1(22, 0x5cb0a9dc, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND1(23, 0x76f988da, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA256ROUND1(24, 0x983e5152, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND1(25, 0xa831c66d, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND1(26, 0xb00327c8, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND1(27, 0xbf597fc7, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND1(28, 0xc6e00bf3, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND1(29, 0xd5a79147, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND1(30, 0x06ca6351, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND1(31, 0x14292967, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA256ROUND1(32, 0x27b70a85, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND1(33, 0x2e1b2138, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND1(34, 0x4d2c6dfc, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND1(35, 0x53380d13, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND1(36, 0x650a7354, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND1(37, 0x766a0abb, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND1(38, 0x81c2c92e, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND1(39, 0x92722c85, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA256ROUND1(40, 0xa2bfe8a1, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND1(41, 0xa81a664b, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND1(42, 0xc24b8b70, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND1(43, 0xc76c51a3, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND1(44, 0xd192e819, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND1(45, 0xd6990624, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND1(46, 0xf40e3585, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND1(47, 0x106aa070, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA256ROUND1(48, 0x19a4c116, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND1(49, 0x1e376c08, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND1(50, 0x2748774c, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND1(51, 0x34b0bcb5, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND1(52, 0x391c0cb3, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND1(53, 0x4ed8aa4a, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND1(54, 0x5b9cca4f, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND1(55, 0x682e6ff3, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA256ROUND1(56, 0x748f82ee, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND1(57, 0x78a5636f, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND1(58, 0x84c87814, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND1(59, 0x8cc70208, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND1(60, 0x90befffa, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND1(61, 0xa4506ceb, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND1(62, 0xbef9a3f7, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND1(63, 0xc67178f2, R9, R10, R11, R12, R13, R14, R15, R8)
+
+	MOVQ dig+0(FP), BP
+	ADDL (0*4)(BP), R8  // H0 = a + H0
+	MOVL R8, (0*4)(BP)
+	ADDL (1*4)(BP), R9  // H1 = b + H1
+	MOVL R9, (1*4)(BP)
+	ADDL (2*4)(BP), R10 // H2 = c + H2
+	MOVL R10, (2*4)(BP)
+	ADDL (3*4)(BP), R11 // H3 = d + H3
+	MOVL R11, (3*4)(BP)
+	ADDL (4*4)(BP), R12 // H4 = e + H4
+	MOVL R12, (4*4)(BP)
+	ADDL (5*4)(BP), R13 // H5 = f + H5
+	MOVL R13, (5*4)(BP)
+	ADDL (6*4)(BP), R14 // H6 = g + H6
+	MOVL R14, (6*4)(BP)
+	ADDL (7*4)(BP), R15 // H7 = h + H7
+	MOVL R15, (7*4)(BP)
+
+	ADDQ $64, SI
+	CMPQ SI, 256(SP)
+	JB   loop
+
+end:
+	RET
+
+// shuffle byte order from LE to BE
+DATA flip_mask<>+0x00(SB)/8, $0x0405060700010203
+DATA flip_mask<>+0x08(SB)/8, $0x0c0d0e0f08090a0b
+DATA flip_mask<>+0x10(SB)/8, $0x0405060700010203
+DATA flip_mask<>+0x18(SB)/8, $0x0c0d0e0f08090a0b
+GLOBL flip_mask<>(SB), 8, $32
+
+// shuffle xBxA -> 00BA
+DATA shuff_00BA<>+0x00(SB)/8, $0x0b0a090803020100
+DATA shuff_00BA<>+0x08(SB)/8, $0xFFFFFFFFFFFFFFFF
+DATA shuff_00BA<>+0x10(SB)/8, $0x0b0a090803020100
+DATA shuff_00BA<>+0x18(SB)/8, $0xFFFFFFFFFFFFFFFF
+GLOBL shuff_00BA<>(SB), 8, $32
+
+// shuffle xDxC -> DC00
+DATA shuff_DC00<>+0x00(SB)/8, $0xFFFFFFFFFFFFFFFF
+DATA shuff_DC00<>+0x08(SB)/8, $0x0b0a090803020100
+DATA shuff_DC00<>+0x10(SB)/8, $0xFFFFFFFFFFFFFFFF
+DATA shuff_DC00<>+0x18(SB)/8, $0x0b0a090803020100
+GLOBL shuff_DC00<>(SB), 8, $32
+
+// Round specific constants
+DATA K256<>+0x00(SB)/4, $0x428a2f98 // k1
+DATA K256<>+0x04(SB)/4, $0x71374491 // k2
+DATA K256<>+0x08(SB)/4, $0xb5c0fbcf // k3
+DATA K256<>+0x0c(SB)/4, $0xe9b5dba5 // k4
+DATA K256<>+0x10(SB)/4, $0x428a2f98 // k1
+DATA K256<>+0x14(SB)/4, $0x71374491 // k2
+DATA K256<>+0x18(SB)/4, $0xb5c0fbcf // k3
+DATA K256<>+0x1c(SB)/4, $0xe9b5dba5 // k4
+
+DATA K256<>+0x20(SB)/4, $0x3956c25b // k5 - k8
+DATA K256<>+0x24(SB)/4, $0x59f111f1
+DATA K256<>+0x28(SB)/4, $0x923f82a4
+DATA K256<>+0x2c(SB)/4, $0xab1c5ed5
+DATA K256<>+0x30(SB)/4, $0x3956c25b
+DATA K256<>+0x34(SB)/4, $0x59f111f1
+DATA K256<>+0x38(SB)/4, $0x923f82a4
+DATA K256<>+0x3c(SB)/4, $0xab1c5ed5
+
+DATA K256<>+0x40(SB)/4, $0xd807aa98 // k9 - k12
+DATA K256<>+0x44(SB)/4, $0x12835b01
+DATA K256<>+0x48(SB)/4, $0x243185be
+DATA K256<>+0x4c(SB)/4, $0x550c7dc3
+DATA K256<>+0x50(SB)/4, $0xd807aa98
+DATA K256<>+0x54(SB)/4, $0x12835b01
+DATA K256<>+0x58(SB)/4, $0x243185be
+DATA K256<>+0x5c(SB)/4, $0x550c7dc3
+
+DATA K256<>+0x60(SB)/4, $0x72be5d74 // k13 - k16
+DATA K256<>+0x64(SB)/4, $0x80deb1fe
+DATA K256<>+0x68(SB)/4, $0x9bdc06a7
+DATA K256<>+0x6c(SB)/4, $0xc19bf174
+DATA K256<>+0x70(SB)/4, $0x72be5d74
+DATA K256<>+0x74(SB)/4, $0x80deb1fe
+DATA K256<>+0x78(SB)/4, $0x9bdc06a7
+DATA K256<>+0x7c(SB)/4, $0xc19bf174
+
+DATA K256<>+0x80(SB)/4, $0xe49b69c1 // k17 - k20
+DATA K256<>+0x84(SB)/4, $0xefbe4786
+DATA K256<>+0x88(SB)/4, $0x0fc19dc6
+DATA K256<>+0x8c(SB)/4, $0x240ca1cc
+DATA K256<>+0x90(SB)/4, $0xe49b69c1
+DATA K256<>+0x94(SB)/4, $0xefbe4786
+DATA K256<>+0x98(SB)/4, $0x0fc19dc6
+DATA K256<>+0x9c(SB)/4, $0x240ca1cc
+
+DATA K256<>+0xa0(SB)/4, $0x2de92c6f // k21 - k24
+DATA K256<>+0xa4(SB)/4, $0x4a7484aa
+DATA K256<>+0xa8(SB)/4, $0x5cb0a9dc
+DATA K256<>+0xac(SB)/4, $0x76f988da
+DATA K256<>+0xb0(SB)/4, $0x2de92c6f
+DATA K256<>+0xb4(SB)/4, $0x4a7484aa
+DATA K256<>+0xb8(SB)/4, $0x5cb0a9dc
+DATA K256<>+0xbc(SB)/4, $0x76f988da
+
+DATA K256<>+0xc0(SB)/4, $0x983e5152 // k25 - k28
+DATA K256<>+0xc4(SB)/4, $0xa831c66d
+DATA K256<>+0xc8(SB)/4, $0xb00327c8
+DATA K256<>+0xcc(SB)/4, $0xbf597fc7
+DATA K256<>+0xd0(SB)/4, $0x983e5152
+DATA K256<>+0xd4(SB)/4, $0xa831c66d
+DATA K256<>+0xd8(SB)/4, $0xb00327c8
+DATA K256<>+0xdc(SB)/4, $0xbf597fc7
+
+DATA K256<>+0xe0(SB)/4, $0xc6e00bf3 // k29 - k32
+DATA K256<>+0xe4(SB)/4, $0xd5a79147
+DATA K256<>+0xe8(SB)/4, $0x06ca6351
+DATA K256<>+0xec(SB)/4, $0x14292967
+DATA K256<>+0xf0(SB)/4, $0xc6e00bf3
+DATA K256<>+0xf4(SB)/4, $0xd5a79147
+DATA K256<>+0xf8(SB)/4, $0x06ca6351
+DATA K256<>+0xfc(SB)/4, $0x14292967
+
+DATA K256<>+0x100(SB)/4, $0x27b70a85
+DATA K256<>+0x104(SB)/4, $0x2e1b2138
+DATA K256<>+0x108(SB)/4, $0x4d2c6dfc
+DATA K256<>+0x10c(SB)/4, $0x53380d13
+DATA K256<>+0x110(SB)/4, $0x27b70a85
+DATA K256<>+0x114(SB)/4, $0x2e1b2138
+DATA K256<>+0x118(SB)/4, $0x4d2c6dfc
+DATA K256<>+0x11c(SB)/4, $0x53380d13
+
+DATA K256<>+0x120(SB)/4, $0x650a7354
+DATA K256<>+0x124(SB)/4, $0x766a0abb
+DATA K256<>+0x128(SB)/4, $0x81c2c92e
+DATA K256<>+0x12c(SB)/4, $0x92722c85
+DATA K256<>+0x130(SB)/4, $0x650a7354
+DATA K256<>+0x134(SB)/4, $0x766a0abb
+DATA K256<>+0x138(SB)/4, $0x81c2c92e
+DATA K256<>+0x13c(SB)/4, $0x92722c85
+
+DATA K256<>+0x140(SB)/4, $0xa2bfe8a1
+DATA K256<>+0x144(SB)/4, $0xa81a664b
+DATA K256<>+0x148(SB)/4, $0xc24b8b70
+DATA K256<>+0x14c(SB)/4, $0xc76c51a3
+DATA K256<>+0x150(SB)/4, $0xa2bfe8a1
+DATA K256<>+0x154(SB)/4, $0xa81a664b
+DATA K256<>+0x158(SB)/4, $0xc24b8b70
+DATA K256<>+0x15c(SB)/4, $0xc76c51a3
+
+DATA K256<>+0x160(SB)/4, $0xd192e819
+DATA K256<>+0x164(SB)/4, $0xd6990624
+DATA K256<>+0x168(SB)/4, $0xf40e3585
+DATA K256<>+0x16c(SB)/4, $0x106aa070
+DATA K256<>+0x170(SB)/4, $0xd192e819
+DATA K256<>+0x174(SB)/4, $0xd6990624
+DATA K256<>+0x178(SB)/4, $0xf40e3585
+DATA K256<>+0x17c(SB)/4, $0x106aa070
+
+DATA K256<>+0x180(SB)/4, $0x19a4c116
+DATA K256<>+0x184(SB)/4, $0x1e376c08
+DATA K256<>+0x188(SB)/4, $0x2748774c
+DATA K256<>+0x18c(SB)/4, $0x34b0bcb5
+DATA K256<>+0x190(SB)/4, $0x19a4c116
+DATA K256<>+0x194(SB)/4, $0x1e376c08
+DATA K256<>+0x198(SB)/4, $0x2748774c
+DATA K256<>+0x19c(SB)/4, $0x34b0bcb5
+
+DATA K256<>+0x1a0(SB)/4, $0x391c0cb3
+DATA K256<>+0x1a4(SB)/4, $0x4ed8aa4a
+DATA K256<>+0x1a8(SB)/4, $0x5b9cca4f
+DATA K256<>+0x1ac(SB)/4, $0x682e6ff3
+DATA K256<>+0x1b0(SB)/4, $0x391c0cb3
+DATA K256<>+0x1b4(SB)/4, $0x4ed8aa4a
+DATA K256<>+0x1b8(SB)/4, $0x5b9cca4f
+DATA K256<>+0x1bc(SB)/4, $0x682e6ff3
+
+DATA K256<>+0x1c0(SB)/4, $0x748f82ee
+DATA K256<>+0x1c4(SB)/4, $0x78a5636f
+DATA K256<>+0x1c8(SB)/4, $0x84c87814
+DATA K256<>+0x1cc(SB)/4, $0x8cc70208
+DATA K256<>+0x1d0(SB)/4, $0x748f82ee
+DATA K256<>+0x1d4(SB)/4, $0x78a5636f
+DATA K256<>+0x1d8(SB)/4, $0x84c87814
+DATA K256<>+0x1dc(SB)/4, $0x8cc70208
+
+DATA K256<>+0x1e0(SB)/4, $0x90befffa
+DATA K256<>+0x1e4(SB)/4, $0xa4506ceb
+DATA K256<>+0x1e8(SB)/4, $0xbef9a3f7
+DATA K256<>+0x1ec(SB)/4, $0xc67178f2
+DATA K256<>+0x1f0(SB)/4, $0x90befffa
+DATA K256<>+0x1f4(SB)/4, $0xa4506ceb
+DATA K256<>+0x1f8(SB)/4, $0xbef9a3f7
+DATA K256<>+0x1fc(SB)/4, $0xc67178f2
+
+GLOBL K256<>(SB), (NOPTR + RODATA), $512
diff --git a/src/cmd/internal/notsha256/sha256block_arm64.s b/src/cmd/internal/notsha256/sha256block_arm64.s
new file mode 100644
index 0000000..d5c1eb0b
--- /dev/null
+++ b/src/cmd/internal/notsha256/sha256block_arm64.s
@@ -0,0 +1,119 @@
+// Copyright 2017 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.
+
+#include "textflag.h"
+
+#define HASHUPDATE \
+	SHA256H	V9.S4, V3, V2 \
+	SHA256H2	V9.S4, V8, V3 \
+	VMOV	V2.B16, V8.B16
+
+// func sha256block(h []uint32, p []byte, k []uint32)
+TEXT ·sha256block(SB),NOSPLIT,$0
+	MOVD	h_base+0(FP), R0                           // Hash value first address
+	MOVD	p_base+24(FP), R1                          // message first address
+	MOVD	k_base+48(FP), R2                          // k constants first address
+	MOVD	p_len+32(FP), R3                           // message length
+	VLD1	(R0), [V0.S4, V1.S4]                       // load h(a,b,c,d,e,f,g,h)
+	VLD1.P	64(R2), [V16.S4, V17.S4, V18.S4, V19.S4]
+	VLD1.P	64(R2), [V20.S4, V21.S4, V22.S4, V23.S4]
+	VLD1.P	64(R2), [V24.S4, V25.S4, V26.S4, V27.S4]
+	VLD1	(R2), [V28.S4, V29.S4, V30.S4, V31.S4]     //load 64*4bytes K constant(K0-K63)
+
+blockloop:
+
+	VLD1.P	16(R1), [V4.B16]                            // load 16bytes message
+	VLD1.P	16(R1), [V5.B16]                            // load 16bytes message
+	VLD1.P	16(R1), [V6.B16]                            // load 16bytes message
+	VLD1.P	16(R1), [V7.B16]                            // load 16bytes message
+	VMOV	V0.B16, V2.B16                              // backup: VO h(dcba)
+	VMOV	V1.B16, V3.B16                              // backup: V1 h(hgfe)
+	VMOV	V2.B16, V8.B16
+	VREV32	V4.B16, V4.B16                              // prepare for using message in Byte format
+	VREV32	V5.B16, V5.B16
+	VREV32	V6.B16, V6.B16
+	VREV32	V7.B16, V7.B16
+
+	VADD	V16.S4, V4.S4, V9.S4                        // V18(W0+K0...W3+K3)
+	SHA256SU0	V5.S4, V4.S4                        // V4: (su0(W1)+W0,...,su0(W4)+W3)
+	HASHUPDATE                                          // H4
+
+	VADD	V17.S4, V5.S4, V9.S4                        // V18(W4+K4...W7+K7)
+	SHA256SU0	V6.S4, V5.S4                        // V5: (su0(W5)+W4,...,su0(W8)+W7)
+	SHA256SU1	V7.S4, V6.S4, V4.S4                 // V4: W16-W19
+	HASHUPDATE                                          // H8
+
+	VADD	V18.S4, V6.S4, V9.S4                        // V18(W8+K8...W11+K11)
+	SHA256SU0	V7.S4, V6.S4                        // V6: (su0(W9)+W8,...,su0(W12)+W11)
+	SHA256SU1	V4.S4, V7.S4, V5.S4                 // V5: W20-W23
+	HASHUPDATE                                          // H12
+
+	VADD	V19.S4, V7.S4, V9.S4                        // V18(W12+K12...W15+K15)
+	SHA256SU0	V4.S4, V7.S4                        // V7: (su0(W13)+W12,...,su0(W16)+W15)
+	SHA256SU1	V5.S4, V4.S4, V6.S4                 // V6: W24-W27
+	HASHUPDATE                                          // H16
+
+	VADD	V20.S4, V4.S4, V9.S4                        // V18(W16+K16...W19+K19)
+	SHA256SU0	V5.S4, V4.S4                        // V4: (su0(W17)+W16,...,su0(W20)+W19)
+	SHA256SU1	V6.S4, V5.S4, V7.S4                 // V7: W28-W31
+	HASHUPDATE                                          // H20
+
+	VADD	V21.S4, V5.S4, V9.S4                        // V18(W20+K20...W23+K23)
+	SHA256SU0	V6.S4, V5.S4                        // V5: (su0(W21)+W20,...,su0(W24)+W23)
+	SHA256SU1	V7.S4, V6.S4, V4.S4                 // V4: W32-W35
+	HASHUPDATE                                          // H24
+
+	VADD	V22.S4, V6.S4, V9.S4                        // V18(W24+K24...W27+K27)
+	SHA256SU0	V7.S4, V6.S4                        // V6: (su0(W25)+W24,...,su0(W28)+W27)
+	SHA256SU1	V4.S4, V7.S4, V5.S4                 // V5: W36-W39
+	HASHUPDATE                                          // H28
+
+	VADD	V23.S4, V7.S4, V9.S4                        // V18(W28+K28...W31+K31)
+	SHA256SU0	V4.S4, V7.S4                        // V7: (su0(W29)+W28,...,su0(W32)+W31)
+	SHA256SU1	V5.S4, V4.S4, V6.S4                 // V6: W40-W43
+	HASHUPDATE                                          // H32
+
+	VADD	V24.S4, V4.S4, V9.S4                        // V18(W32+K32...W35+K35)
+	SHA256SU0	V5.S4, V4.S4                        // V4: (su0(W33)+W32,...,su0(W36)+W35)
+	SHA256SU1	V6.S4, V5.S4, V7.S4                 // V7: W44-W47
+	HASHUPDATE                                          // H36
+
+	VADD	V25.S4, V5.S4, V9.S4                        // V18(W36+K36...W39+K39)
+	SHA256SU0	V6.S4, V5.S4                        // V5: (su0(W37)+W36,...,su0(W40)+W39)
+	SHA256SU1	V7.S4, V6.S4, V4.S4                 // V4: W48-W51
+	HASHUPDATE                                          // H40
+
+	VADD	V26.S4, V6.S4, V9.S4                        // V18(W40+K40...W43+K43)
+	SHA256SU0	V7.S4, V6.S4                        // V6: (su0(W41)+W40,...,su0(W44)+W43)
+	SHA256SU1	V4.S4, V7.S4, V5.S4                 // V5: W52-W55
+	HASHUPDATE                                          // H44
+
+	VADD	V27.S4, V7.S4, V9.S4                        // V18(W44+K44...W47+K47)
+	SHA256SU0	V4.S4, V7.S4                        // V7: (su0(W45)+W44,...,su0(W48)+W47)
+	SHA256SU1	V5.S4, V4.S4, V6.S4                 // V6: W56-W59
+	HASHUPDATE                                          // H48
+
+	VADD	V28.S4, V4.S4, V9.S4                        // V18(W48+K48,...,W51+K51)
+	HASHUPDATE                                          // H52
+	SHA256SU1	V6.S4, V5.S4, V7.S4                 // V7: W60-W63
+
+	VADD	V29.S4, V5.S4, V9.S4                        // V18(W52+K52,...,W55+K55)
+	HASHUPDATE                                          // H56
+
+	VADD	V30.S4, V6.S4, V9.S4                        // V18(W59+K59,...,W59+K59)
+	HASHUPDATE                                          // H60
+
+	VADD	V31.S4, V7.S4, V9.S4                        // V18(W60+K60,...,W63+K63)
+	HASHUPDATE                                          // H64
+
+	SUB	$64, R3, R3                                 // message length - 64bytes, then compare with 64bytes
+	VADD	V2.S4, V0.S4, V0.S4
+	VADD	V3.S4, V1.S4, V1.S4
+	CBNZ	R3, blockloop
+
+sha256ret:
+
+	VST1	[V0.S4, V1.S4], (R0)                       // store hash value H
+	RET
+
diff --git a/src/cmd/internal/notsha256/sha256block_decl.go b/src/cmd/internal/notsha256/sha256block_decl.go
new file mode 100644
index 0000000..5a822ee
--- /dev/null
+++ b/src/cmd/internal/notsha256/sha256block_decl.go
@@ -0,0 +1,12 @@
+// 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.
+
+//go:build 386 || amd64 || ppc64le || ppc64
+// +build 386 amd64 ppc64le ppc64
+
+package notsha256
+
+//go:noescape
+
+func block(dig *digest, p []byte)
diff --git a/src/cmd/internal/notsha256/sha256block_generic.go b/src/cmd/internal/notsha256/sha256block_generic.go
new file mode 100644
index 0000000..20ae841
--- /dev/null
+++ b/src/cmd/internal/notsha256/sha256block_generic.go
@@ -0,0 +1,12 @@
+// Copyright 2016 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.
+
+//go:build !amd64 && !386 && !ppc64le && !ppc64
+// +build !amd64,!386,!ppc64le,!ppc64
+
+package notsha256
+
+func block(dig *digest, p []byte) {
+	blockGeneric(dig, p)
+}
diff --git a/src/cmd/internal/notsha256/sha256block_ppc64x.s b/src/cmd/internal/notsha256/sha256block_ppc64x.s
new file mode 100644
index 0000000..f534c26
--- /dev/null
+++ b/src/cmd/internal/notsha256/sha256block_ppc64x.s
@@ -0,0 +1,424 @@
+// Copyright 2016 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.
+
+//go:build ppc64 || ppc64le
+// +build ppc64 ppc64le
+
+// Based on CRYPTOGAMS code with the following comment:
+// # ====================================================================
+// # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+// # project. The module is, however, dual licensed under OpenSSL and
+// # CRYPTOGAMS licenses depending on where you obtain it. For further
+// # details see http://www.openssl.org/~appro/cryptogams/.
+// # ====================================================================
+
+#include "textflag.h"
+
+// SHA256 block routine. See sha256block.go for Go equivalent.
+//
+// The algorithm is detailed in FIPS 180-4:
+//
+//  https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
+//
+// Wt = Mt; for 0 <= t <= 15
+// Wt = SIGMA1(Wt-2) + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
+//
+// a = H0
+// b = H1
+// c = H2
+// d = H3
+// e = H4
+// f = H5
+// g = H6
+// h = H7
+//
+// for t = 0 to 63 {
+//    T1 = h + BIGSIGMA1(e) + Ch(e,f,g) + Kt + Wt
+//    T2 = BIGSIGMA0(a) + Maj(a,b,c)
+//    h = g
+//    g = f
+//    f = e
+//    e = d + T1
+//    d = c
+//    c = b
+//    b = a
+//    a = T1 + T2
+// }
+//
+// H0 = a + H0
+// H1 = b + H1
+// H2 = c + H2
+// H3 = d + H3
+// H4 = e + H4
+// H5 = f + H5
+// H6 = g + H6
+// H7 = h + H7
+
+#define CTX	R3
+#define INP	R4
+#define END	R5
+#define TBL	R6
+#define IDX	R7
+#define LEN	R9
+#define TEMP	R12
+
+#define HEX00	R0
+#define HEX10	R10
+
+// V0-V7 are A-H
+// V8-V23 are used for the message schedule
+#define KI	V24
+#define FUNC	V25
+#define S0	V26
+#define S1	V27
+#define s0	V28
+#define s1	V29
+#define LEMASK	V31	// Permutation control register for little endian
+
+// 4 copies of each Kt, to fill all 4 words of a vector register
+DATA  ·kcon+0x000(SB)/8, $0x428a2f98428a2f98
+DATA  ·kcon+0x008(SB)/8, $0x428a2f98428a2f98
+DATA  ·kcon+0x010(SB)/8, $0x7137449171374491
+DATA  ·kcon+0x018(SB)/8, $0x7137449171374491
+DATA  ·kcon+0x020(SB)/8, $0xb5c0fbcfb5c0fbcf
+DATA  ·kcon+0x028(SB)/8, $0xb5c0fbcfb5c0fbcf
+DATA  ·kcon+0x030(SB)/8, $0xe9b5dba5e9b5dba5
+DATA  ·kcon+0x038(SB)/8, $0xe9b5dba5e9b5dba5
+DATA  ·kcon+0x040(SB)/8, $0x3956c25b3956c25b
+DATA  ·kcon+0x048(SB)/8, $0x3956c25b3956c25b
+DATA  ·kcon+0x050(SB)/8, $0x59f111f159f111f1
+DATA  ·kcon+0x058(SB)/8, $0x59f111f159f111f1
+DATA  ·kcon+0x060(SB)/8, $0x923f82a4923f82a4
+DATA  ·kcon+0x068(SB)/8, $0x923f82a4923f82a4
+DATA  ·kcon+0x070(SB)/8, $0xab1c5ed5ab1c5ed5
+DATA  ·kcon+0x078(SB)/8, $0xab1c5ed5ab1c5ed5
+DATA  ·kcon+0x080(SB)/8, $0xd807aa98d807aa98
+DATA  ·kcon+0x088(SB)/8, $0xd807aa98d807aa98
+DATA  ·kcon+0x090(SB)/8, $0x12835b0112835b01
+DATA  ·kcon+0x098(SB)/8, $0x12835b0112835b01
+DATA  ·kcon+0x0A0(SB)/8, $0x243185be243185be
+DATA  ·kcon+0x0A8(SB)/8, $0x243185be243185be
+DATA  ·kcon+0x0B0(SB)/8, $0x550c7dc3550c7dc3
+DATA  ·kcon+0x0B8(SB)/8, $0x550c7dc3550c7dc3
+DATA  ·kcon+0x0C0(SB)/8, $0x72be5d7472be5d74
+DATA  ·kcon+0x0C8(SB)/8, $0x72be5d7472be5d74
+DATA  ·kcon+0x0D0(SB)/8, $0x80deb1fe80deb1fe
+DATA  ·kcon+0x0D8(SB)/8, $0x80deb1fe80deb1fe
+DATA  ·kcon+0x0E0(SB)/8, $0x9bdc06a79bdc06a7
+DATA  ·kcon+0x0E8(SB)/8, $0x9bdc06a79bdc06a7
+DATA  ·kcon+0x0F0(SB)/8, $0xc19bf174c19bf174
+DATA  ·kcon+0x0F8(SB)/8, $0xc19bf174c19bf174
+DATA  ·kcon+0x100(SB)/8, $0xe49b69c1e49b69c1
+DATA  ·kcon+0x108(SB)/8, $0xe49b69c1e49b69c1
+DATA  ·kcon+0x110(SB)/8, $0xefbe4786efbe4786
+DATA  ·kcon+0x118(SB)/8, $0xefbe4786efbe4786
+DATA  ·kcon+0x120(SB)/8, $0x0fc19dc60fc19dc6
+DATA  ·kcon+0x128(SB)/8, $0x0fc19dc60fc19dc6
+DATA  ·kcon+0x130(SB)/8, $0x240ca1cc240ca1cc
+DATA  ·kcon+0x138(SB)/8, $0x240ca1cc240ca1cc
+DATA  ·kcon+0x140(SB)/8, $0x2de92c6f2de92c6f
+DATA  ·kcon+0x148(SB)/8, $0x2de92c6f2de92c6f
+DATA  ·kcon+0x150(SB)/8, $0x4a7484aa4a7484aa
+DATA  ·kcon+0x158(SB)/8, $0x4a7484aa4a7484aa
+DATA  ·kcon+0x160(SB)/8, $0x5cb0a9dc5cb0a9dc
+DATA  ·kcon+0x168(SB)/8, $0x5cb0a9dc5cb0a9dc
+DATA  ·kcon+0x170(SB)/8, $0x76f988da76f988da
+DATA  ·kcon+0x178(SB)/8, $0x76f988da76f988da
+DATA  ·kcon+0x180(SB)/8, $0x983e5152983e5152
+DATA  ·kcon+0x188(SB)/8, $0x983e5152983e5152
+DATA  ·kcon+0x190(SB)/8, $0xa831c66da831c66d
+DATA  ·kcon+0x198(SB)/8, $0xa831c66da831c66d
+DATA  ·kcon+0x1A0(SB)/8, $0xb00327c8b00327c8
+DATA  ·kcon+0x1A8(SB)/8, $0xb00327c8b00327c8
+DATA  ·kcon+0x1B0(SB)/8, $0xbf597fc7bf597fc7
+DATA  ·kcon+0x1B8(SB)/8, $0xbf597fc7bf597fc7
+DATA  ·kcon+0x1C0(SB)/8, $0xc6e00bf3c6e00bf3
+DATA  ·kcon+0x1C8(SB)/8, $0xc6e00bf3c6e00bf3
+DATA  ·kcon+0x1D0(SB)/8, $0xd5a79147d5a79147
+DATA  ·kcon+0x1D8(SB)/8, $0xd5a79147d5a79147
+DATA  ·kcon+0x1E0(SB)/8, $0x06ca635106ca6351
+DATA  ·kcon+0x1E8(SB)/8, $0x06ca635106ca6351
+DATA  ·kcon+0x1F0(SB)/8, $0x1429296714292967
+DATA  ·kcon+0x1F8(SB)/8, $0x1429296714292967
+DATA  ·kcon+0x200(SB)/8, $0x27b70a8527b70a85
+DATA  ·kcon+0x208(SB)/8, $0x27b70a8527b70a85
+DATA  ·kcon+0x210(SB)/8, $0x2e1b21382e1b2138
+DATA  ·kcon+0x218(SB)/8, $0x2e1b21382e1b2138
+DATA  ·kcon+0x220(SB)/8, $0x4d2c6dfc4d2c6dfc
+DATA  ·kcon+0x228(SB)/8, $0x4d2c6dfc4d2c6dfc
+DATA  ·kcon+0x230(SB)/8, $0x53380d1353380d13
+DATA  ·kcon+0x238(SB)/8, $0x53380d1353380d13
+DATA  ·kcon+0x240(SB)/8, $0x650a7354650a7354
+DATA  ·kcon+0x248(SB)/8, $0x650a7354650a7354
+DATA  ·kcon+0x250(SB)/8, $0x766a0abb766a0abb
+DATA  ·kcon+0x258(SB)/8, $0x766a0abb766a0abb
+DATA  ·kcon+0x260(SB)/8, $0x81c2c92e81c2c92e
+DATA  ·kcon+0x268(SB)/8, $0x81c2c92e81c2c92e
+DATA  ·kcon+0x270(SB)/8, $0x92722c8592722c85
+DATA  ·kcon+0x278(SB)/8, $0x92722c8592722c85
+DATA  ·kcon+0x280(SB)/8, $0xa2bfe8a1a2bfe8a1
+DATA  ·kcon+0x288(SB)/8, $0xa2bfe8a1a2bfe8a1
+DATA  ·kcon+0x290(SB)/8, $0xa81a664ba81a664b
+DATA  ·kcon+0x298(SB)/8, $0xa81a664ba81a664b
+DATA  ·kcon+0x2A0(SB)/8, $0xc24b8b70c24b8b70
+DATA  ·kcon+0x2A8(SB)/8, $0xc24b8b70c24b8b70
+DATA  ·kcon+0x2B0(SB)/8, $0xc76c51a3c76c51a3
+DATA  ·kcon+0x2B8(SB)/8, $0xc76c51a3c76c51a3
+DATA  ·kcon+0x2C0(SB)/8, $0xd192e819d192e819
+DATA  ·kcon+0x2C8(SB)/8, $0xd192e819d192e819
+DATA  ·kcon+0x2D0(SB)/8, $0xd6990624d6990624
+DATA  ·kcon+0x2D8(SB)/8, $0xd6990624d6990624
+DATA  ·kcon+0x2E0(SB)/8, $0xf40e3585f40e3585
+DATA  ·kcon+0x2E8(SB)/8, $0xf40e3585f40e3585
+DATA  ·kcon+0x2F0(SB)/8, $0x106aa070106aa070
+DATA  ·kcon+0x2F8(SB)/8, $0x106aa070106aa070
+DATA  ·kcon+0x300(SB)/8, $0x19a4c11619a4c116
+DATA  ·kcon+0x308(SB)/8, $0x19a4c11619a4c116
+DATA  ·kcon+0x310(SB)/8, $0x1e376c081e376c08
+DATA  ·kcon+0x318(SB)/8, $0x1e376c081e376c08
+DATA  ·kcon+0x320(SB)/8, $0x2748774c2748774c
+DATA  ·kcon+0x328(SB)/8, $0x2748774c2748774c
+DATA  ·kcon+0x330(SB)/8, $0x34b0bcb534b0bcb5
+DATA  ·kcon+0x338(SB)/8, $0x34b0bcb534b0bcb5
+DATA  ·kcon+0x340(SB)/8, $0x391c0cb3391c0cb3
+DATA  ·kcon+0x348(SB)/8, $0x391c0cb3391c0cb3
+DATA  ·kcon+0x350(SB)/8, $0x4ed8aa4a4ed8aa4a
+DATA  ·kcon+0x358(SB)/8, $0x4ed8aa4a4ed8aa4a
+DATA  ·kcon+0x360(SB)/8, $0x5b9cca4f5b9cca4f
+DATA  ·kcon+0x368(SB)/8, $0x5b9cca4f5b9cca4f
+DATA  ·kcon+0x370(SB)/8, $0x682e6ff3682e6ff3
+DATA  ·kcon+0x378(SB)/8, $0x682e6ff3682e6ff3
+DATA  ·kcon+0x380(SB)/8, $0x748f82ee748f82ee
+DATA  ·kcon+0x388(SB)/8, $0x748f82ee748f82ee
+DATA  ·kcon+0x390(SB)/8, $0x78a5636f78a5636f
+DATA  ·kcon+0x398(SB)/8, $0x78a5636f78a5636f
+DATA  ·kcon+0x3A0(SB)/8, $0x84c8781484c87814
+DATA  ·kcon+0x3A8(SB)/8, $0x84c8781484c87814
+DATA  ·kcon+0x3B0(SB)/8, $0x8cc702088cc70208
+DATA  ·kcon+0x3B8(SB)/8, $0x8cc702088cc70208
+DATA  ·kcon+0x3C0(SB)/8, $0x90befffa90befffa
+DATA  ·kcon+0x3C8(SB)/8, $0x90befffa90befffa
+DATA  ·kcon+0x3D0(SB)/8, $0xa4506ceba4506ceb
+DATA  ·kcon+0x3D8(SB)/8, $0xa4506ceba4506ceb
+DATA  ·kcon+0x3E0(SB)/8, $0xbef9a3f7bef9a3f7
+DATA  ·kcon+0x3E8(SB)/8, $0xbef9a3f7bef9a3f7
+DATA  ·kcon+0x3F0(SB)/8, $0xc67178f2c67178f2
+DATA  ·kcon+0x3F8(SB)/8, $0xc67178f2c67178f2
+DATA  ·kcon+0x400(SB)/8, $0x0000000000000000
+DATA  ·kcon+0x408(SB)/8, $0x0000000000000000
+
+#ifdef GOARCH_ppc64le
+DATA  ·kcon+0x410(SB)/8, $0x1011121310111213	// permutation control vectors
+DATA  ·kcon+0x418(SB)/8, $0x1011121300010203
+DATA  ·kcon+0x420(SB)/8, $0x1011121310111213
+DATA  ·kcon+0x428(SB)/8, $0x0405060700010203
+DATA  ·kcon+0x430(SB)/8, $0x1011121308090a0b
+DATA  ·kcon+0x438(SB)/8, $0x0405060700010203
+#else
+DATA  ·kcon+0x410(SB)/8, $0x1011121300010203
+DATA  ·kcon+0x418(SB)/8, $0x1011121310111213	// permutation control vectors
+DATA  ·kcon+0x420(SB)/8, $0x0405060700010203
+DATA  ·kcon+0x428(SB)/8, $0x1011121310111213
+DATA  ·kcon+0x430(SB)/8, $0x0001020304050607
+DATA  ·kcon+0x438(SB)/8, $0x08090a0b10111213
+#endif
+
+GLOBL ·kcon(SB), RODATA, $1088
+
+#define SHA256ROUND0(a, b, c, d, e, f, g, h, xi) \
+	VSEL		g, f, e, FUNC; \
+	VSHASIGMAW	$15, e, $1, S1; \
+	VADDUWM		xi, h, h; \
+	VSHASIGMAW	$0, a, $1, S0; \
+	VADDUWM		FUNC, h, h; \
+	VXOR		b, a, FUNC; \
+	VADDUWM		S1, h, h; \
+	VSEL		b, c, FUNC, FUNC; \
+	VADDUWM		KI, g, g; \
+	VADDUWM		h, d, d; \
+	VADDUWM		FUNC, S0, S0; \
+	LVX		(TBL)(IDX), KI; \
+	ADD		$16, IDX; \
+	VADDUWM		S0, h, h
+
+#define SHA256ROUND1(a, b, c, d, e, f, g, h, xi, xj, xj_1, xj_9, xj_14) \
+	VSHASIGMAW	$0, xj_1, $0, s0; \
+	VSEL		g, f, e, FUNC; \
+	VSHASIGMAW	$15, e, $1, S1; \
+	VADDUWM		xi, h, h; \
+	VSHASIGMAW	$0, a, $1, S0; \
+	VSHASIGMAW	$15, xj_14, $0, s1; \
+	VADDUWM		FUNC, h, h; \
+	VXOR		b, a, FUNC; \
+	VADDUWM		xj_9, xj, xj; \
+	VADDUWM		S1, h, h; \
+	VSEL		b, c, FUNC, FUNC; \
+	VADDUWM		KI, g, g; \
+	VADDUWM		h, d, d; \
+	VADDUWM		FUNC, S0, S0; \
+	VADDUWM		s0, xj, xj; \
+	LVX		(TBL)(IDX), KI; \
+	ADD		$16, IDX; \
+	VADDUWM		S0, h, h; \
+	VADDUWM		s1, xj, xj
+
+#ifdef GOARCH_ppc64le
+#define VPERMLE(va,vb,vc,vt) VPERM va, vb, vc, vt
+#else
+#define VPERMLE(va,vb,vc,vt)
+#endif
+
+// func block(dig *digest, p []byte)
+TEXT ·block(SB),0,$0-32
+	MOVD	dig+0(FP), CTX
+	MOVD	p_base+8(FP), INP
+	MOVD	p_len+16(FP), LEN
+
+	SRD	$6, LEN
+	SLD	$6, LEN
+	ADD	INP, LEN, END
+
+	CMP	INP, END
+	BEQ	end
+
+	MOVD	$·kcon(SB), TBL
+	MOVWZ	$0x10, HEX10
+	MOVWZ	$8, IDX
+
+#ifdef GOARCH_ppc64le
+	LVSL	(IDX)(R0), LEMASK
+	VSPLTISB	$0x0F, KI
+	VXOR	KI, LEMASK, LEMASK
+#endif
+
+	LXVW4X	(CTX)(HEX00), VS32	// v0 = vs32
+	LXVW4X	(CTX)(HEX10), VS36	// v4 = vs36
+
+	// unpack the input values into vector registers
+	VSLDOI	$4, V0, V0, V1
+	VSLDOI	$8, V0, V0, V2
+	VSLDOI	$12, V0, V0, V3
+	VSLDOI	$4, V4, V4, V5
+	VSLDOI	$8, V4, V4, V6
+	VSLDOI	$12, V4, V4, V7
+
+loop:
+	LVX	(TBL)(HEX00), KI
+	MOVWZ	$16, IDX
+
+	LXVD2X	(INP)(R0), VS40	// load v8 (=vs40) in advance
+	ADD	$16, INP
+
+	// Offload to VSR24-31 (aka FPR24-31)
+	XXLOR	V0, V0, VS24
+	XXLOR	V1, V1, VS25
+	XXLOR	V2, V2, VS26
+	XXLOR	V3, V3, VS27
+	XXLOR	V4, V4, VS28
+	XXLOR	V5, V5, VS29
+	XXLOR	V6, V6, VS30
+	XXLOR	V7, V7, VS31
+
+	VADDUWM	KI, V7, V7	// h+K[i]
+	LVX	(TBL)(IDX), KI
+	ADD	$16, IDX
+
+	VPERMLE(V8, V8, LEMASK, V8)
+	SHA256ROUND0(V0, V1, V2, V3, V4, V5, V6, V7, V8)
+	VSLDOI	$4, V8, V8, V9
+	SHA256ROUND0(V7, V0, V1, V2, V3, V4, V5, V6, V9)
+	VSLDOI	$4, V9, V9, V10
+	SHA256ROUND0(V6, V7, V0, V1, V2, V3, V4, V5, V10)
+	LXVD2X	(INP)(R0), VS44	// load v12 (=vs44) in advance
+	ADD	$16, INP, INP
+	VSLDOI	$4, V10, V10, V11
+	SHA256ROUND0(V5, V6, V7, V0, V1, V2, V3, V4, V11)
+	VPERMLE(V12, V12, LEMASK, V12)
+	SHA256ROUND0(V4, V5, V6, V7, V0, V1, V2, V3, V12)
+	VSLDOI	$4, V12, V12, V13
+	SHA256ROUND0(V3, V4, V5, V6, V7, V0, V1, V2, V13)
+	VSLDOI	$4, V13, V13, V14
+	SHA256ROUND0(V2, V3, V4, V5, V6, V7, V0, V1, V14)
+	LXVD2X	(INP)(R0), VS48	// load v16 (=vs48) in advance
+	ADD	$16, INP, INP
+	VSLDOI	$4, V14, V14, V15
+	SHA256ROUND0(V1, V2, V3, V4, V5, V6, V7, V0, V15)
+	VPERMLE(V16, V16, LEMASK, V16)
+	SHA256ROUND0(V0, V1, V2, V3, V4, V5, V6, V7, V16)
+	VSLDOI	$4, V16, V16, V17
+	SHA256ROUND0(V7, V0, V1, V2, V3, V4, V5, V6, V17)
+	VSLDOI	$4, V17, V17, V18
+	SHA256ROUND0(V6, V7, V0, V1, V2, V3, V4, V5, V18)
+	VSLDOI	$4, V18, V18, V19
+	LXVD2X	(INP)(R0), VS52	// load v20 (=vs52) in advance
+	ADD	$16, INP, INP
+	SHA256ROUND0(V5, V6, V7, V0, V1, V2, V3, V4, V19)
+	VPERMLE(V20, V20, LEMASK, V20)
+	SHA256ROUND0(V4, V5, V6, V7, V0, V1, V2, V3, V20)
+	VSLDOI	$4, V20, V20, V21
+	SHA256ROUND0(V3, V4, V5, V6, V7, V0, V1, V2, V21)
+	VSLDOI	$4, V21, V21, V22
+	SHA256ROUND0(V2, V3, V4, V5, V6, V7, V0, V1, V22)
+	VSLDOI	$4, V22, V22, V23
+	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V23, V8, V9, V17, V22)
+
+	MOVWZ	$3, TEMP
+	MOVWZ	TEMP, CTR
+
+L16_xx:
+	SHA256ROUND1(V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V18, V23)
+	SHA256ROUND1(V7, V0, V1, V2, V3, V4, V5, V6, V9, V10, V11, V19, V8)
+	SHA256ROUND1(V6, V7, V0, V1, V2, V3, V4, V5, V10, V11, V12, V20, V9)
+	SHA256ROUND1(V5, V6, V7, V0, V1, V2, V3, V4, V11, V12, V13, V21, V10)
+	SHA256ROUND1(V4, V5, V6, V7, V0, V1, V2, V3, V12, V13, V14, V22, V11)
+	SHA256ROUND1(V3, V4, V5, V6, V7, V0, V1, V2, V13, V14, V15, V23, V12)
+	SHA256ROUND1(V2, V3, V4, V5, V6, V7, V0, V1, V14, V15, V16, V8, V13)
+	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V15, V16, V17, V9, V14)
+	SHA256ROUND1(V0, V1, V2, V3, V4, V5, V6, V7, V16, V17, V18, V10, V15)
+	SHA256ROUND1(V7, V0, V1, V2, V3, V4, V5, V6, V17, V18, V19, V11, V16)
+	SHA256ROUND1(V6, V7, V0, V1, V2, V3, V4, V5, V18, V19, V20, V12, V17)
+	SHA256ROUND1(V5, V6, V7, V0, V1, V2, V3, V4, V19, V20, V21, V13, V18)
+	SHA256ROUND1(V4, V5, V6, V7, V0, V1, V2, V3, V20, V21, V22, V14, V19)
+	SHA256ROUND1(V3, V4, V5, V6, V7, V0, V1, V2, V21, V22, V23, V15, V20)
+	SHA256ROUND1(V2, V3, V4, V5, V6, V7, V0, V1, V22, V23, V8, V16, V21)
+	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V23, V8, V9, V17, V22)
+
+	BC	0x10, 0, L16_xx		// bdnz
+
+	XXLOR	VS24, VS24, V10
+
+	XXLOR	VS25, VS25, V11
+	VADDUWM	V10, V0, V0
+	XXLOR	VS26, VS26, V12
+	VADDUWM	V11, V1, V1
+	XXLOR	VS27, VS27, V13
+	VADDUWM	V12, V2, V2
+	XXLOR	VS28, VS28, V14
+	VADDUWM	V13, V3, V3
+	XXLOR	VS29, VS29, V15
+	VADDUWM	V14, V4, V4
+	XXLOR	VS30, VS30, V16
+	VADDUWM	V15, V5, V5
+	XXLOR	VS31, VS31, V17
+	VADDUWM	V16, V6, V6
+	VADDUWM	V17, V7, V7
+
+	CMPU	INP, END
+	BLT	loop
+
+	LVX	(TBL)(IDX), V8
+	ADD	$16, IDX
+	VPERM	V0, V1, KI, V0
+	LVX	(TBL)(IDX), V9
+	VPERM	V4, V5, KI, V4
+	VPERM	V0, V2, V8, V0
+	VPERM	V4, V6, V8, V4
+	VPERM	V0, V3, V9, V0
+	VPERM	V4, V7, V9, V4
+	STXVD2X	VS32, (CTX+HEX00)	// v0 = vs32
+	STXVD2X	VS36, (CTX+HEX10)	// v4 = vs36
+
+end:
+	RET
+