--- /dev/null
+// 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.
+
+// +build s390x
+
+package sha256
+
+import (
+ "fmt"
+ "io"
+ "testing"
+)
+
+// Tests the fallback code path in case the optimized asm
+// implementation cannot be used.
+// See also TestBlockGeneric.
+func TestGenericPath(t *testing.T) {
+ if useAsm == false {
+ t.Skipf("assembly implementation unavailable")
+ }
+ useAsm = false
+ defer func() { useAsm = true }()
+ c := New()
+ in := "ΑΒΓΔΕϜΖΗΘΙΚΛΜΝΞΟΠϺϘΡΣΤΥΦΧΨΩ"
+ gold := "e93d84ec2b22383123be9f713697fb25" +
+ "338c86e2f7d8d1ddc2d89d332dd9d76c"
+ if _, err := io.WriteString(c, in); err != nil {
+ t.Fatalf("could not write to c: %v", err)
+ }
+ out := fmt.Sprintf("%x", c.Sum(nil))
+ if out != gold {
+ t.Fatalf("mismatch: got %s, wanted %s", out, gold)
+ }
+}
package sha256
import (
+ "crypto/rand"
"fmt"
"io"
"testing"
}
}
+// 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")
+ }
+}
+
var bench = New()
var buf = make([]byte, 8192)
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !386,!amd64
-
// SHA256 block step.
// In its own file so that a faster assembly or C version
// can be substituted easily.
0xc67178f2,
}
-func block(dig *digest, p []byte) {
+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 {
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build 386 amd64
+// +build 386 amd64 s390x
package sha256
--- /dev/null
+// 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.
+
+// +build !amd64,!386,!s390x
+
+package sha256
+
+var block = blockGeneric
--- /dev/null
+// 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 sha256
+
+// featureCheck reports whether the CPU supports the
+// SHA256 compute intermediate message digest (KIMD)
+// function code.
+func featureCheck() bool
+
+var useAsm = featureCheck()
--- /dev/null
+// 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.
+
+#include "textflag.h"
+
+// func featureCheck() bool
+TEXT ·featureCheck(SB),NOSPLIT,$16-1
+ LA tmp-16(SP), R1
+ XOR R0, R0 // query function code is 0
+ WORD $0xB93E0006 // KIMD (R6 is ignored)
+ MOVBZ tmp-16(SP), R4 // get the first byte
+ AND $0x20, R4 // bit 2 (big endian) for SHA256
+ CMPBEQ R4, $0, nosha256
+ MOVB $1, ret+0(FP)
+ RET
+nosha256:
+ MOVB $0, ret+0(FP)
+ RET
+
+// func block(dig *digest, p []byte)
+TEXT ·block(SB),NOSPLIT,$0-32
+ MOVBZ ·useAsm(SB), R4
+ LMG dig+0(FP), R1, R3 // R2 = &p[0], R3 = len(p)
+ CMPBNE R4, $1, generic
+ MOVBZ $2, R0 // SHA256 function code
+loop:
+ WORD $0xB93E0002 // KIMD R2
+ BVS loop // continue if interrupted
+done:
+ XOR R0, R0 // restore R0
+ RET
+generic:
+ BR ·blockGeneric(SB)