mirror of
https://github.com/golang/go
synced 2024-11-12 04:40:22 -07:00
crypto/sha256: add s390x assembly implementation
Renames block to blockGeneric so that it can be called when the assembly feature check fails. This means making block a var on platforms without an assembly implementation (similar to the sha1 package). Also adds a test to check that the fallback path works correctly when the feature check fails. name old speed new speed delta Hash8Bytes 6.42MB/s ± 1% 27.14MB/s ± 0% +323.01% (p=0.000 n=10+10) Hash1K 53.9MB/s ± 0% 511.1MB/s ± 0% +847.57% (p=0.000 n=10+9) Hash8K 57.1MB/s ± 1% 609.7MB/s ± 0% +967.04% (p=0.000 n=10+10) Change-Id: If962b2a5c9160b3a0b76ccee53b2fd809468ed3d Reviewed-on: https://go-review.googlesource.com/22460 Run-TryBot: Michael Munday <munday@ca.ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Bill O'Farrell <billotosyr@gmail.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
2a889b9d93
commit
525ae3f897
35
src/crypto/sha256/fallback_test.go
Normal file
35
src/crypto/sha256/fallback_test.go
Normal file
@ -0,0 +1,35 @@
|
||||
// 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)
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
package sha256
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
@ -150,6 +151,18 @@ func TestBlockSize(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
|
@ -2,8 +2,6 @@
|
||||
// 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.
|
||||
@ -77,7 +75,7 @@ var _K = []uint32{
|
||||
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 {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// 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
|
||||
|
||||
|
9
src/crypto/sha256/sha256block_generic.go
Normal file
9
src/crypto/sha256/sha256block_generic.go
Normal file
@ -0,0 +1,9 @@
|
||||
// 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
|
12
src/crypto/sha256/sha256block_s390x.go
Normal file
12
src/crypto/sha256/sha256block_s390x.go
Normal file
@ -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.
|
||||
|
||||
package sha256
|
||||
|
||||
// featureCheck reports whether the CPU supports the
|
||||
// SHA256 compute intermediate message digest (KIMD)
|
||||
// function code.
|
||||
func featureCheck() bool
|
||||
|
||||
var useAsm = featureCheck()
|
34
src/crypto/sha256/sha256block_s390x.s
Normal file
34
src/crypto/sha256/sha256block_s390x.s
Normal file
@ -0,0 +1,34 @@
|
||||
// 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)
|
Loading…
Reference in New Issue
Block a user