diff options
Diffstat (limited to 'src/pkg/crypto/sha1')
-rw-r--r-- | src/pkg/crypto/sha1/example_test.go | 9 | ||||
-rw-r--r-- | src/pkg/crypto/sha1/sha1.go | 10 | ||||
-rw-r--r-- | src/pkg/crypto/sha1/sha1_test.go | 27 | ||||
-rw-r--r-- | src/pkg/crypto/sha1/sha1block.go | 10 | ||||
-rw-r--r-- | src/pkg/crypto/sha1/sha1block_386.s | 10 | ||||
-rw-r--r-- | src/pkg/crypto/sha1/sha1block_amd64.s | 10 | ||||
-rw-r--r-- | src/pkg/crypto/sha1/sha1block_amd64p32.s | 216 | ||||
-rw-r--r-- | src/pkg/crypto/sha1/sha1block_arm.s | 217 | ||||
-rw-r--r-- | src/pkg/crypto/sha1/sha1block_decl.go | 2 | ||||
-rw-r--r-- | src/pkg/crypto/sha1/sha1block_generic.go | 9 |
10 files changed, 491 insertions, 29 deletions
diff --git a/src/pkg/crypto/sha1/example_test.go b/src/pkg/crypto/sha1/example_test.go index 25fe5f308..42aec8afa 100644 --- a/src/pkg/crypto/sha1/example_test.go +++ b/src/pkg/crypto/sha1/example_test.go @@ -12,7 +12,14 @@ import ( func ExampleNew() { h := sha1.New() - io.WriteString(h, "His money is twice tainted: 'taint yours and 'taint mine.") + io.WriteString(h, "His money is twice tainted:") + io.WriteString(h, " 'taint yours and 'taint mine.") fmt.Printf("% x", h.Sum(nil)) // Output: 59 7f 6a 54 00 10 f9 4c 15 d7 18 06 a9 9a 2c 87 10 e7 47 bd } + +func ExampleSum() { + data := []byte("This page intentionally left blank.") + fmt.Printf("% x", sha1.Sum(data)) + // Output: af 06 49 23 bb f2 30 15 96 aa c4 c2 73 ba 32 17 8e bc 4a 96 +} diff --git a/src/pkg/crypto/sha1/sha1.go b/src/pkg/crypto/sha1/sha1.go index 8eb3f7a79..9f1a96e36 100644 --- a/src/pkg/crypto/sha1/sha1.go +++ b/src/pkg/crypto/sha1/sha1.go @@ -62,16 +62,10 @@ func (d *digest) Write(p []byte) (nn int, err error) { nn = len(p) d.len += uint64(nn) if d.nx > 0 { - n := len(p) - if n > chunk-d.nx { - n = chunk - d.nx - } - for i := 0; i < n; i++ { - d.x[d.nx+i] = p[i] - } + n := copy(d.x[d.nx:], p) d.nx += n if d.nx == chunk { - block(d, d.x[0:]) + block(d, d.x[:]) d.nx = 0 } p = p[n:] diff --git a/src/pkg/crypto/sha1/sha1_test.go b/src/pkg/crypto/sha1/sha1_test.go index c3868d702..4a629518b 100644 --- a/src/pkg/crypto/sha1/sha1_test.go +++ b/src/pkg/crypto/sha1/sha1_test.go @@ -7,6 +7,7 @@ package sha1 import ( + "crypto/rand" "fmt" "io" "testing" @@ -76,6 +77,32 @@ func TestGolden(t *testing.T) { } } +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 amd64, 386, arm) 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) diff --git a/src/pkg/crypto/sha1/sha1block.go b/src/pkg/crypto/sha1/sha1block.go index 92224fc0e..fde3c981c 100644 --- a/src/pkg/crypto/sha1/sha1block.go +++ b/src/pkg/crypto/sha1/sha1block.go @@ -2,12 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !amd64,!386 - -// SHA1 block step. -// In its own file so that a faster assembly or C version -// can be substituted easily. - package sha1 const ( @@ -17,7 +11,9 @@ const ( _K3 = 0xCA62C1D6 ) -func block(dig *digest, p []byte) { +// blockGeneric is a portable, pure Go version of the SHA1 block step. +// It's used by sha1block_generic.go and tests. +func blockGeneric(dig *digest, p []byte) { var w [16]uint32 h0, h1, h2, h3, h4 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4] diff --git a/src/pkg/crypto/sha1/sha1block_386.s b/src/pkg/crypto/sha1/sha1block_386.s index 890b3ae81..688851c31 100644 --- a/src/pkg/crypto/sha1/sha1block_386.s +++ b/src/pkg/crypto/sha1/sha1block_386.s @@ -46,12 +46,10 @@ ADDL DI, e #define FUNC1(a, b, c, d, e) \ - MOVL b, SI; \ - ANDL c, SI; \ - MOVL b, DI; \ - NOTL DI; \ - ANDL d, DI; \ - ORL SI, DI + MOVL d, DI; \ + XORL c, DI; \ + ANDL b, DI; \ + XORL d, DI #define FUNC2(a, b, c, d, e) \ MOVL b, DI; \ diff --git a/src/pkg/crypto/sha1/sha1block_amd64.s b/src/pkg/crypto/sha1/sha1block_amd64.s index 0bb6c204c..8ffb9d5d6 100644 --- a/src/pkg/crypto/sha1/sha1block_amd64.s +++ b/src/pkg/crypto/sha1/sha1block_amd64.s @@ -34,12 +34,10 @@ MOVL R10, (((index)&0xf)*4)(SP) #define FUNC1(a, b, c, d, e) \ - MOVL b, R8; \ - ANDL c, R8; \ - MOVL b, R9; \ - NOTL R9; \ - ANDL d, R9; \ - ORL R8, R9 + MOVL d, R9; \ + XORL c, R9; \ + ANDL b, R9; \ + XORL d, R9 #define FUNC2(a, b, c, d, e) \ MOVL b, R9; \ diff --git a/src/pkg/crypto/sha1/sha1block_amd64p32.s b/src/pkg/crypto/sha1/sha1block_amd64p32.s new file mode 100644 index 000000000..3c589d94f --- /dev/null +++ b/src/pkg/crypto/sha1/sha1block_amd64p32.s @@ -0,0 +1,216 @@ +// 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 "../../../cmd/ld/textflag.h" + +// SHA1 block routine. See sha1block.go for Go equivalent. +// +// There are 80 rounds of 4 types: +// - rounds 0-15 are type 1 and load data (ROUND1 macro). +// - rounds 16-19 are type 1 and do not load data (ROUND1x macro). +// - rounds 20-39 are type 2 and do not load data (ROUND2 macro). +// - rounds 40-59 are type 3 and do not load data (ROUND3 macro). +// - rounds 60-79 are type 4 and do not load data (ROUND4 macro). +// +// Each round loads or shuffles the data, then computes a per-round +// function of b, c, d, and then mixes the result into and rotates the +// five registers a, b, c, d, e holding the intermediate results. +// +// The register rotation is implemented by rotating the arguments to +// the round macros instead of by explicit move instructions. +// +// amd64p32 version. +// To ensure safety for Native Client, avoids use of BP and R15 +// as well as two-register addressing modes. + +#define LOAD(index) \ + MOVL (index*4)(SI), R10; \ + BSWAPL R10; \ + MOVL R10, (index*4)(SP) + +#define SHUFFLE(index) \ + MOVL (((index)&0xf)*4)(SP), R10; \ + XORL (((index-3)&0xf)*4)(SP), R10; \ + XORL (((index-8)&0xf)*4)(SP), R10; \ + XORL (((index-14)&0xf)*4)(SP), R10; \ + ROLL $1, R10; \ + MOVL R10, (((index)&0xf)*4)(SP) + +#define FUNC1(a, b, c, d, e) \ + MOVL d, R9; \ + XORL c, R9; \ + ANDL b, R9; \ + XORL d, R9 + +#define FUNC2(a, b, c, d, e) \ + MOVL b, R9; \ + XORL c, R9; \ + XORL d, R9 + +#define FUNC3(a, b, c, d, e) \ + MOVL b, R8; \ + ORL c, R8; \ + ANDL d, R8; \ + MOVL b, R9; \ + ANDL c, R9; \ + ORL R8, R9 + +#define FUNC4 FUNC2 + +#define MIX(a, b, c, d, e, const) \ + ROLL $30, b; \ + ADDL R9, e; \ + MOVL a, R8; \ + ROLL $5, R8; \ + LEAL const(e)(R10*1), e; \ + ADDL R8, e + +#define ROUND1(a, b, c, d, e, index) \ + LOAD(index); \ + FUNC1(a, b, c, d, e); \ + MIX(a, b, c, d, e, 0x5A827999) + +#define ROUND1x(a, b, c, d, e, index) \ + SHUFFLE(index); \ + FUNC1(a, b, c, d, e); \ + MIX(a, b, c, d, e, 0x5A827999) + +#define ROUND2(a, b, c, d, e, index) \ + SHUFFLE(index); \ + FUNC2(a, b, c, d, e); \ + MIX(a, b, c, d, e, 0x6ED9EBA1) + +#define ROUND3(a, b, c, d, e, index) \ + SHUFFLE(index); \ + FUNC3(a, b, c, d, e); \ + MIX(a, b, c, d, e, 0x8F1BBCDC) + +#define ROUND4(a, b, c, d, e, index) \ + SHUFFLE(index); \ + FUNC4(a, b, c, d, e); \ + MIX(a, b, c, d, e, 0xCA62C1D6) + +TEXT ·block(SB),NOSPLIT,$64-32 + MOVL dig+0(FP), R14 + MOVL p_base+4(FP), SI + MOVL p_len+8(FP), DX + SHRQ $6, DX + SHLQ $6, DX + + LEAQ (SI)(DX*1), DI + MOVL (0*4)(R14), AX + MOVL (1*4)(R14), BX + MOVL (2*4)(R14), CX + MOVL (3*4)(R14), DX + MOVL (4*4)(R14), R13 + + CMPQ SI, DI + JEQ end + +loop: +#define BP R13 /* keep diff from sha1block_amd64.s small */ + ROUND1(AX, BX, CX, DX, BP, 0) + ROUND1(BP, AX, BX, CX, DX, 1) + ROUND1(DX, BP, AX, BX, CX, 2) + ROUND1(CX, DX, BP, AX, BX, 3) + ROUND1(BX, CX, DX, BP, AX, 4) + ROUND1(AX, BX, CX, DX, BP, 5) + ROUND1(BP, AX, BX, CX, DX, 6) + ROUND1(DX, BP, AX, BX, CX, 7) + ROUND1(CX, DX, BP, AX, BX, 8) + ROUND1(BX, CX, DX, BP, AX, 9) + ROUND1(AX, BX, CX, DX, BP, 10) + ROUND1(BP, AX, BX, CX, DX, 11) + ROUND1(DX, BP, AX, BX, CX, 12) + ROUND1(CX, DX, BP, AX, BX, 13) + ROUND1(BX, CX, DX, BP, AX, 14) + ROUND1(AX, BX, CX, DX, BP, 15) + + ROUND1x(BP, AX, BX, CX, DX, 16) + ROUND1x(DX, BP, AX, BX, CX, 17) + ROUND1x(CX, DX, BP, AX, BX, 18) + ROUND1x(BX, CX, DX, BP, AX, 19) + + ROUND2(AX, BX, CX, DX, BP, 20) + ROUND2(BP, AX, BX, CX, DX, 21) + ROUND2(DX, BP, AX, BX, CX, 22) + ROUND2(CX, DX, BP, AX, BX, 23) + ROUND2(BX, CX, DX, BP, AX, 24) + ROUND2(AX, BX, CX, DX, BP, 25) + ROUND2(BP, AX, BX, CX, DX, 26) + ROUND2(DX, BP, AX, BX, CX, 27) + ROUND2(CX, DX, BP, AX, BX, 28) + ROUND2(BX, CX, DX, BP, AX, 29) + ROUND2(AX, BX, CX, DX, BP, 30) + ROUND2(BP, AX, BX, CX, DX, 31) + ROUND2(DX, BP, AX, BX, CX, 32) + ROUND2(CX, DX, BP, AX, BX, 33) + ROUND2(BX, CX, DX, BP, AX, 34) + ROUND2(AX, BX, CX, DX, BP, 35) + ROUND2(BP, AX, BX, CX, DX, 36) + ROUND2(DX, BP, AX, BX, CX, 37) + ROUND2(CX, DX, BP, AX, BX, 38) + ROUND2(BX, CX, DX, BP, AX, 39) + + ROUND3(AX, BX, CX, DX, BP, 40) + ROUND3(BP, AX, BX, CX, DX, 41) + ROUND3(DX, BP, AX, BX, CX, 42) + ROUND3(CX, DX, BP, AX, BX, 43) + ROUND3(BX, CX, DX, BP, AX, 44) + ROUND3(AX, BX, CX, DX, BP, 45) + ROUND3(BP, AX, BX, CX, DX, 46) + ROUND3(DX, BP, AX, BX, CX, 47) + ROUND3(CX, DX, BP, AX, BX, 48) + ROUND3(BX, CX, DX, BP, AX, 49) + ROUND3(AX, BX, CX, DX, BP, 50) + ROUND3(BP, AX, BX, CX, DX, 51) + ROUND3(DX, BP, AX, BX, CX, 52) + ROUND3(CX, DX, BP, AX, BX, 53) + ROUND3(BX, CX, DX, BP, AX, 54) + ROUND3(AX, BX, CX, DX, BP, 55) + ROUND3(BP, AX, BX, CX, DX, 56) + ROUND3(DX, BP, AX, BX, CX, 57) + ROUND3(CX, DX, BP, AX, BX, 58) + ROUND3(BX, CX, DX, BP, AX, 59) + + ROUND4(AX, BX, CX, DX, BP, 60) + ROUND4(BP, AX, BX, CX, DX, 61) + ROUND4(DX, BP, AX, BX, CX, 62) + ROUND4(CX, DX, BP, AX, BX, 63) + ROUND4(BX, CX, DX, BP, AX, 64) + ROUND4(AX, BX, CX, DX, BP, 65) + ROUND4(BP, AX, BX, CX, DX, 66) + ROUND4(DX, BP, AX, BX, CX, 67) + ROUND4(CX, DX, BP, AX, BX, 68) + ROUND4(BX, CX, DX, BP, AX, 69) + ROUND4(AX, BX, CX, DX, BP, 70) + ROUND4(BP, AX, BX, CX, DX, 71) + ROUND4(DX, BP, AX, BX, CX, 72) + ROUND4(CX, DX, BP, AX, BX, 73) + ROUND4(BX, CX, DX, BP, AX, 74) + ROUND4(AX, BX, CX, DX, BP, 75) + ROUND4(BP, AX, BX, CX, DX, 76) + ROUND4(DX, BP, AX, BX, CX, 77) + ROUND4(CX, DX, BP, AX, BX, 78) + ROUND4(BX, CX, DX, BP, AX, 79) +#undef BP + + ADDL (0*4)(R14), AX + ADDL (1*4)(R14), BX + ADDL (2*4)(R14), CX + ADDL (3*4)(R14), DX + ADDL (4*4)(R14), R13 + + MOVL AX, (0*4)(R14) + MOVL BX, (1*4)(R14) + MOVL CX, (2*4)(R14) + MOVL DX, (3*4)(R14) + MOVL R13, (4*4)(R14) + + ADDQ $64, SI + CMPQ SI, DI + JB loop + +end: + RET diff --git a/src/pkg/crypto/sha1/sha1block_arm.s b/src/pkg/crypto/sha1/sha1block_arm.s new file mode 100644 index 000000000..5917e8b24 --- /dev/null +++ b/src/pkg/crypto/sha1/sha1block_arm.s @@ -0,0 +1,217 @@ +// Copyright 2014 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. +// +// ARM version of md5block.go + +#include "../../../cmd/ld/textflag.h" + +// SHA1 block routine. See sha1block.go for Go equivalent. +// +// There are 80 rounds of 4 types: +// - rounds 0-15 are type 1 and load data (ROUND1 macro). +// - rounds 16-19 are type 1 and do not load data (ROUND1x macro). +// - rounds 20-39 are type 2 and do not load data (ROUND2 macro). +// - rounds 40-59 are type 3 and do not load data (ROUND3 macro). +// - rounds 60-79 are type 4 and do not load data (ROUND4 macro). +// +// Each round loads or shuffles the data, then computes a per-round +// function of b, c, d, and then mixes the result into and rotates the +// five registers a, b, c, d, e holding the intermediate results. +// +// The register rotation is implemented by rotating the arguments to +// the round macros instead of by explicit move instructions. + +// Register definitions +data = 0 // Pointer to incoming data +const = 1 // Current constant for SHA round +a = 2 // SHA1 accumulator +b = 3 // SHA1 accumulator +c = 4 // SHA1 accumulator +d = 5 // SHA1 accumulator +e = 6 // SHA1 accumulator +t0 = 7 // Temporary +t1 = 8 // Temporary +// r9, r10 are forbidden +// r11 is OK provided you check the assembler that no synthetic instructions use it +t2 = 11 // Temporary +ctr = 12 // loop counter +w = 14 // point to w buffer + +// func block(dig *digest, p []byte) +// 0(FP) is *digest +// 4(FP) is p.array (struct Slice) +// 8(FP) is p.len +//12(FP) is p.cap +// +// Stack frame +p_end = -4 // -4(SP) pointer to the end of data +p_data = p_end - 4 // -8(SP) current data pointer +w_buf = p_data - 4*80 // -328(SP) 80 words temporary buffer w uint32[80] +saved = w_buf - 4*5 // -348(SP) saved sha1 registers a,b,c,d,e - these must be last +// Total size +4 for saved LR is 352 + + // w[i] = p[j]<<24 | p[j+1]<<16 | p[j+2]<<8 | p[j+3] + // e += w[i] +#define LOAD(e) \ + MOVBU 2(R(data)), R(t0) ; \ + MOVBU 3(R(data)), R(t1) ; \ + MOVBU 1(R(data)), R(t2) ; \ + ORR R(t0)<<8, R(t1), R(t0) ; \ + MOVBU.P 4(R(data)), R(t1) ; \ + ORR R(t2)<<16, R(t0), R(t0) ; \ + ORR R(t1)<<24, R(t0), R(t0) ; \ + MOVW.P R(t0), 4(R(w)) ; \ + ADD R(t0), R(e), R(e) + + // tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf] + // w[i&0xf] = tmp<<1 | tmp>>(32-1) + // e += w[i&0xf] +#define SHUFFLE(e) \ + MOVW (-16*4)(R(w)), R(t0) ; \ + MOVW (-14*4)(R(w)), R(t1) ; \ + MOVW (-8*4)(R(w)), R(t2) ; \ + EOR R(t0), R(t1), R(t0) ; \ + MOVW (-3*4)(R(w)), R(t1) ; \ + EOR R(t2), R(t0), R(t0) ; \ + EOR R(t0), R(t1), R(t0) ; \ + MOVW R(t0)@>(32-1), R(t0) ; \ + MOVW.P R(t0), 4(R(w)) ; \ + ADD R(t0), R(e), R(e) + + // t1 = (b & c) | ((~b) & d) +#define FUNC1(a, b, c, d, e) \ + MVN R(b), R(t1) ; \ + AND R(b), R(c), R(t0) ; \ + AND R(d), R(t1), R(t1) ; \ + ORR R(t0), R(t1), R(t1) + + // t1 = b ^ c ^ d +#define FUNC2(a, b, c, d, e) \ + EOR R(b), R(c), R(t1) ; \ + EOR R(d), R(t1), R(t1) + + // t1 = (b & c) | (b & d) | (c & d) = + // t1 = (b & c) | ((b | c) & d) +#define FUNC3(a, b, c, d, e) \ + ORR R(b), R(c), R(t0) ; \ + AND R(b), R(c), R(t1) ; \ + AND R(d), R(t0), R(t0) ; \ + ORR R(t0), R(t1), R(t1) + +#define FUNC4 FUNC2 + + // a5 := a<<5 | a>>(32-5) + // b = b<<30 | b>>(32-30) + // e = a5 + t1 + e + const +#define MIX(a, b, c, d, e) \ + ADD R(t1), R(e), R(e) ; \ + MOVW R(b)@>(32-30), R(b) ; \ + ADD R(a)@>(32-5), R(e), R(e) ; \ + ADD R(const), R(e), R(e) + +#define ROUND1(a, b, c, d, e) \ + LOAD(e) ; \ + FUNC1(a, b, c, d, e) ; \ + MIX(a, b, c, d, e) + +#define ROUND1x(a, b, c, d, e) \ + SHUFFLE(e) ; \ + FUNC1(a, b, c, d, e) ; \ + MIX(a, b, c, d, e) + +#define ROUND2(a, b, c, d, e) \ + SHUFFLE(e) ; \ + FUNC2(a, b, c, d, e) ; \ + MIX(a, b, c, d, e) + +#define ROUND3(a, b, c, d, e) \ + SHUFFLE(e) ; \ + FUNC3(a, b, c, d, e) ; \ + MIX(a, b, c, d, e) + +#define ROUND4(a, b, c, d, e) \ + SHUFFLE(e) ; \ + FUNC4(a, b, c, d, e) ; \ + MIX(a, b, c, d, e) + + +// func block(dig *digest, p []byte) +TEXT ·block(SB), 0, $352-16 + MOVW p+4(FP), R(data) // pointer to the data + MOVW p_len+8(FP), R(t0) // number of bytes + ADD R(data), R(t0) + MOVW R(t0), p_end(SP) // pointer to end of data + + // Load up initial SHA1 accumulator + MOVW dig+0(FP), R(t0) + MOVM.IA (R(t0)), [R(a),R(b),R(c),R(d),R(e)] + +loop: + // Save registers at SP+4 onwards + MOVM.IB [R(a),R(b),R(c),R(d),R(e)], (R13) + + MOVW $w_buf(SP), R(w) + MOVW $0x5A827999, R(const) + MOVW $3, R(ctr) +loop1: ROUND1(a, b, c, d, e) + ROUND1(e, a, b, c, d) + ROUND1(d, e, a, b, c) + ROUND1(c, d, e, a, b) + ROUND1(b, c, d, e, a) + SUB.S $1, R(ctr) + BNE loop1 + + ROUND1(a, b, c, d, e) + ROUND1x(e, a, b, c, d) + ROUND1x(d, e, a, b, c) + ROUND1x(c, d, e, a, b) + ROUND1x(b, c, d, e, a) + + MOVW $0x6ED9EBA1, R(const) + MOVW $4, R(ctr) +loop2: ROUND2(a, b, c, d, e) + ROUND2(e, a, b, c, d) + ROUND2(d, e, a, b, c) + ROUND2(c, d, e, a, b) + ROUND2(b, c, d, e, a) + SUB.S $1, R(ctr) + BNE loop2 + + MOVW $0x8F1BBCDC, R(const) + MOVW $4, R(ctr) +loop3: ROUND3(a, b, c, d, e) + ROUND3(e, a, b, c, d) + ROUND3(d, e, a, b, c) + ROUND3(c, d, e, a, b) + ROUND3(b, c, d, e, a) + SUB.S $1, R(ctr) + BNE loop3 + + MOVW $0xCA62C1D6, R(const) + MOVW $4, R(ctr) +loop4: ROUND4(a, b, c, d, e) + ROUND4(e, a, b, c, d) + ROUND4(d, e, a, b, c) + ROUND4(c, d, e, a, b) + ROUND4(b, c, d, e, a) + SUB.S $1, R(ctr) + BNE loop4 + + // Accumulate - restoring registers from SP+4 + MOVM.IB (R13), [R(t0),R(t1),R(t2),R(ctr),R(w)] + ADD R(t0), R(a) + ADD R(t1), R(b) + ADD R(t2), R(c) + ADD R(ctr), R(d) + ADD R(w), R(e) + + MOVW p_end(SP), R(t0) + CMP R(t0), R(data) + BLO loop + + // Save final SHA1 accumulator + MOVW dig+0(FP), R(t0) + MOVM.IA [R(a),R(b),R(c),R(d),R(e)], (R(t0)) + + RET diff --git a/src/pkg/crypto/sha1/sha1block_decl.go b/src/pkg/crypto/sha1/sha1block_decl.go index 4cb157fff..24e521af1 100644 --- a/src/pkg/crypto/sha1/sha1block_decl.go +++ b/src/pkg/crypto/sha1/sha1block_decl.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. -// +build amd64 386 +// +build amd64 amd64p32 arm 386 package sha1 diff --git a/src/pkg/crypto/sha1/sha1block_generic.go b/src/pkg/crypto/sha1/sha1block_generic.go new file mode 100644 index 000000000..696e26b62 --- /dev/null +++ b/src/pkg/crypto/sha1/sha1block_generic.go @@ -0,0 +1,9 @@ +// Copyright 2014 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,!amd64p32,!386,!arm + +package sha1 + +var block = blockGeneric |