aboutsummaryrefslogtreecommitdiffstats
path: root/src/hash/sha1_sse2
diff options
context:
space:
mode:
authorlloyd <[email protected]>2009-10-28 22:55:12 +0000
committerlloyd <[email protected]>2009-10-28 22:55:12 +0000
commit3623be3fd05d890309cc3da4b3a1e319e357df65 (patch)
tree34ca43fcf8a7007cc01a3919f63e9ab6763cb673 /src/hash/sha1_sse2
parentfc1e61500e77fcabe67e6d2607810c1ba071bbdd (diff)
parent9462f875b13a321f42a127166d49670ca04afcde (diff)
propagate from branch 'net.randombit.botan.1_8' (head 3158f8272a3582dd44dfb771665eb71f7d005339)
to branch 'net.randombit.botan' (head bf629b13dd132b263e76a72b7eca0f7e4ab19aac)
Diffstat (limited to 'src/hash/sha1_sse2')
-rw-r--r--src/hash/sha1_sse2/info.txt20
-rw-r--r--src/hash/sha1_sse2/sha1_sse2_imp.cpp135
2 files changed, 54 insertions, 101 deletions
diff --git a/src/hash/sha1_sse2/info.txt b/src/hash/sha1_sse2/info.txt
index b8d693b70..4a7a1b5e9 100644
--- a/src/hash/sha1_sse2/info.txt
+++ b/src/hash/sha1_sse2/info.txt
@@ -2,26 +2,6 @@ realname "SHA-1 (SSE2)"
define SHA1_SSE2
-load_on auto
-
-<add>
-sha1_sse2_imp.cpp
-sha1_sse2.cpp
-sha1_sse2.h
-</add>
-
-<arch>
-pentium-m
-pentium4
-prescott
-amd64
-</arch>
-
-<cc>
-gcc
-icc
-</cc>
-
<requires>
sha1
sse2_eng
diff --git a/src/hash/sha1_sse2/sha1_sse2_imp.cpp b/src/hash/sha1_sse2/sha1_sse2_imp.cpp
index 90a8dccd5..5ee222cca 100644
--- a/src/hash/sha1_sse2/sha1_sse2_imp.cpp
+++ b/src/hash/sha1_sse2/sha1_sse2_imp.cpp
@@ -1,27 +1,18 @@
-/* this code is public domain.
-
- * dean gaudet <[email protected]>
-
- * this code was inspired by this paper:
-
- * SHA: A Design for Parallel Architectures?
- * Antoon Bosselaers, Ren�e Govaerts and Joos Vandewalle
- * <http://www.esat.kuleuven.ac.be/~cosicart/pdf/AB-9700.pdf>
-
- * more information available on this implementation here:
-
- * http://arctic.org/~dean/crypto/sha1.html
-
- * version: 2
- */
+/*
+* SHA-1 using SSE2
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
/*
- * Lightly modified for Botan, tested under GCC 4.1.1 and ICC 9.1
- * on a Linux/Core2 system.
+* Based on public domain code by Dean Gaudet <[email protected]>
+* http://arctic.org/~dean/crypto/sha1.html
+*/
- */
#include <botan/sha1_sse2.h>
-#include <xmmintrin.h>
+#include <botan/rotate.h>
+#include <emmintrin.h>
namespace Botan {
@@ -30,21 +21,13 @@ namespace {
typedef union {
u32bit u32[4];
__m128i u128;
- } v4si __attribute__((aligned(16)));
+ } v4si;
static const v4si K00_19 = { { 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999 } };
static const v4si K20_39 = { { 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1 } };
static const v4si K40_59 = { { 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc } };
static const v4si K60_79 = { { 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6 } };
-#define UNALIGNED 1
-#if UNALIGNED
-#define load(p) _mm_loadu_si128(p)
-#else
-#define load(p) (*p)
-#endif
-
-
/*
the first 16 bytes only need byte swapping
@@ -57,19 +40,15 @@ and is overwritten with the swapped bytes
__m128i r1, r2; \
\
r1 = (W); \
- if (1) { \
r1 = _mm_shufflehi_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \
r1 = _mm_shufflelo_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \
r2 = _mm_slli_epi16(r1, 8); \
r1 = _mm_srli_epi16(r1, 8); \
r1 = _mm_or_si128(r1, r2); \
(W) = r1; \
- } \
(prep).u128 = _mm_add_epi32(K00_19.u128, r1); \
} while(0)
-
-
/*
for each multiple of 4, t, we want to calculate this:
@@ -115,45 +94,38 @@ W0 = W[t]..W[t+3]
* efficeon, pentium-m, and opteron but shifts are available in
* only one unit.
*/
-#define prep(prep, XW0, XW1, XW2, XW3, K) do { \
- __m128i r0, r1, r2, r3; \
- \
- /* load W[t-4] 16-byte aligned, and shift */ \
- r3 = _mm_srli_si128((XW3), 4); \
- r0 = (XW0); \
- /* get high 64-bits of XW0 into low 64-bits */ \
- r1 = _mm_shuffle_epi32((XW0), _MM_SHUFFLE(1,0,3,2)); \
- /* load high 64-bits of r1 */ \
- r1 = _mm_unpacklo_epi64(r1, (XW1)); \
- r2 = (XW2); \
- \
- r0 = _mm_xor_si128(r1, r0); \
- r2 = _mm_xor_si128(r3, r2); \
- r0 = _mm_xor_si128(r2, r0); \
- /* unrotated W[t]..W[t+2] in r0 ... still need W[t+3] */ \
- \
- r2 = _mm_slli_si128(r0, 12); \
- r1 = _mm_cmplt_epi32(r0, _mm_setzero_si128()); \
- r0 = _mm_add_epi32(r0, r0); /* shift left by 1 */ \
- r0 = _mm_sub_epi32(r0, r1); /* r0 has W[t]..W[t+2] */ \
- \
- r3 = _mm_srli_epi32(r2, 30); \
- r2 = _mm_slli_epi32(r2, 2); \
- \
- r0 = _mm_xor_si128(r0, r3); \
- r0 = _mm_xor_si128(r0, r2); /* r0 now has W[t+3] */ \
- \
- (XW0) = r0; \
- (prep).u128 = _mm_add_epi32(r0, (K).u128); \
- } while(0)
-
-
-static inline u32bit rol(u32bit src, u32bit amt)
- {
- /* gcc and icc appear to turn this into a rotate */
- return (src << amt) | (src >> (32 - amt));
- }
-
+#define prep(prep, XW0, XW1, XW2, XW3, K) \
+ do { \
+ __m128i r0, r1, r2, r3; \
+ \
+ /* load W[t-4] 16-byte aligned, and shift */ \
+ r3 = _mm_srli_si128((XW3), 4); \
+ r0 = (XW0); \
+ /* get high 64-bits of XW0 into low 64-bits */ \
+ r1 = _mm_shuffle_epi32((XW0), _MM_SHUFFLE(1,0,3,2)); \
+ /* load high 64-bits of r1 */ \
+ r1 = _mm_unpacklo_epi64(r1, (XW1)); \
+ r2 = (XW2); \
+ \
+ r0 = _mm_xor_si128(r1, r0); \
+ r2 = _mm_xor_si128(r3, r2); \
+ r0 = _mm_xor_si128(r2, r0); \
+ /* unrotated W[t]..W[t+2] in r0 ... still need W[t+3] */ \
+ \
+ r2 = _mm_slli_si128(r0, 12); \
+ r1 = _mm_cmplt_epi32(r0, _mm_setzero_si128()); \
+ r0 = _mm_add_epi32(r0, r0); /* shift left by 1 */ \
+ r0 = _mm_sub_epi32(r0, r1); /* r0 has W[t]..W[t+2] */ \
+ \
+ r3 = _mm_srli_epi32(r2, 30); \
+ r2 = _mm_slli_epi32(r2, 2); \
+ \
+ r0 = _mm_xor_si128(r0, r3); \
+ r0 = _mm_xor_si128(r0, r2); /* r0 now has W[t+3] */ \
+ \
+ (XW0) = r0; \
+ (prep).u128 = _mm_add_epi32(r0, (K).u128); \
+ } while(0)
static inline u32bit f00_19(u32bit x, u32bit y, u32bit z)
{
@@ -184,11 +156,12 @@ static inline u32bit f60_79(u32bit x, u32bit y, u32bit z)
return f20_39(x, y, z);
}
-#define step(nn_mm, xa, xb, xc, xd, xe, xt, input) do { \
- (xt) = (input) + f##nn_mm((xb), (xc), (xd)); \
- (xb) = rol((xb), 30); \
- (xt) += ((xe) + rol((xa), 5)); \
- } while(0)
+#define step(nn_mm, xa, xb, xc, xd, xe, xt, input) \
+ do { \
+ (xt) = (input) + f##nn_mm((xb), (xc), (xd)); \
+ (xb) = rotate_left((xb), 30); \
+ (xt) += ((xe) + rotate_left((xa), 5)); \
+ } while(0)
}
@@ -210,14 +183,14 @@ extern "C" void botan_sha1_sse2_compress(u32bit H[5],
* steps ahead of the integer code. 12 steps ahead seems
* to produce the best performance. -dean
*/
- W0 = load(&input[0]);
+ W0 = _mm_loadu_si128(&input[0]);
prep00_15(prep0, W0); /* prepare for 00 through 03 */
- W1 = load(&input[1]);
+ W1 = _mm_loadu_si128(&input[1]);
prep00_15(prep1, W1); /* prepare for 04 through 07 */
- W2 = load(&input[2]);
+ W2 = _mm_loadu_si128(&input[2]);
prep00_15(prep2, W2); /* prepare for 08 through 11 */
- W3 = load(&input[3]);
+ W3 = _mm_loadu_si128(&input[3]);
step(00_19, a, b, c, d, e, t, prep0.u32[0]); /* 00 */
step(00_19, t, a, b, c, d, e, prep0.u32[1]); /* 01 */
step(00_19, e, t, a, b, c, d, prep0.u32[2]); /* 02 */