Commit 24a29728 authored by Michael Munday's avatar Michael Munday

crypto/sha512: 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  7.13MB/s ± 2%  19.89MB/s ± 1%  +178.82%   (p=0.000 n=9+10)
Hash1K       121MB/s ± 1%    661MB/s ± 1%  +444.54%   (p=0.000 n=10+9)
Hash8K       137MB/s ± 0%    918MB/s ± 1%  +569.29%  (p=0.000 n=10+10)

Change-Id: Id65dd6e943f14eeffe39a904dc88065fc6a60179
Reviewed-on: https://go-review.googlesource.com/22402Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Michael Munday <munday@ca.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 98b99d56
// 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 sha512
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 := "6922e319366d677f34c504af31bfcb29" +
"e531c125ecd08679362bffbd6b6ebfb9" +
"0dcc27dfc1f3d3b16a16c0763cf43b91" +
"40bbf9bbb7233724e9a0c6655b185d76"
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 sha512
import (
"crypto/rand"
"encoding/hex"
"hash"
"io"
......@@ -304,6 +305,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 !amd64
// SHA512 block step.
// In its own file so that a faster assembly or C version
// can be substituted easily.
......@@ -93,7 +91,7 @@ var _K = []uint64{
0x6c44198c4a475817,
}
func block(dig *digest, p []byte) {
func blockGeneric(dig *digest, p []byte) {
var w [80]uint64
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 amd64
// +build amd64 s390x
package sha512
......
// 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,!s390x
package sha512
var block = blockGeneric
// 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 sha512
// featureCheck reports whether the CPU supports the
// SHA512 compute intermediate message digest (KIMD)
// function code.
func featureCheck() bool
var useAsm = featureCheck()
// 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 $0x10, R4 // bit 3 (big endian) for SHA512
CMPBEQ R4, $0, nosha512
MOVB $1, ret+0(FP)
RET
nosha512:
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 $3, R0 // SHA512 function code
loop:
WORD $0xB93E0002 // KIMD R2
BVS loop // continue if interrupted
done:
XOR R0, R0 // restore R0
RET
generic:
BR ·blockGeneric(SB)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment