From be504402637b10ed0823c99bb496306a046760c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se> Date: Sun, 6 Feb 2011 18:15:04 +0100 Subject: [PATCH] * gcm.c (gcm_rightshift): Moved the reduction of the shifted out bit here. (gcm_gf_mul): Updated for gcm_rightshift change. Improves gmac performance to 181 cycles/byte. Rev: nettle/gcm.c:1.4 --- gcm.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/gcm.c b/gcm.c index 018ccd5b..1f065f11 100644 --- a/gcm.c +++ b/gcm.c @@ -47,25 +47,26 @@ #define GHASH_POLYNOMIAL 0xE1 -/* Big-endian shift right. The argument must be properly aligned for - word accesses. */ -/* FIXME: Move the reduction/wraparound into this functions as - well. */ +/* Multiplication by 010...0; a big-endian shift right. If the bit + shifted out is one, the defining polynomial is added to cancel it + out. */ static void gcm_rightshift (uint8_t *x) { unsigned long *w = (unsigned long *) x; - + long mask; /* Shift uses big-endian representation. */ #if WORDS_BIGENDIAN # if SIZEOF_LONG == 4 + mask = - (w[3] & 1); w[3] = (w[3] >> 1) | ((w[2] & 1) << 31); w[2] = (w[2] >> 1) | ((w[1] & 1) << 31); w[1] = (w[1] >> 1) | ((w[0] & 1) << 31); - w[0] = (w[0] >> 1); + w[0] = (w[0] >> 1) ^ (mask & (GHASH_POLYNOMIAL << 24)); # elif SIZEOF_LONG == 8 + mask = - (w[1] & 1); w[1] = (w[1] >> 1) | ((w[0] & 1) << 63); - w[0] = (w[0] >> 1); + w[0] = (w[0] >> 1) ^ (mask & (GHASH_POLYNOMIAL << 56)); # else # error Unsupported word size. */ #endif @@ -74,16 +75,18 @@ gcm_rightshift (uint8_t *x) #define RSHIFT_WORD(x) \ ((((x) & 0xfefefefeUL) >> 1) \ | (((x) & 0x01010101) << 15)) + mask = - ((w[3] >> 24) & 1); w[3] = RSHIFT_WORD(w[3]) | ((w[2] >> 17) & 0x80); w[2] = RSHIFT_WORD(w[2]) | ((w[1] >> 17) & 0x80); w[1] = RSHIFT_WORD(w[1]) | ((w[0] >> 17) & 0x80); - w[0] = RSHIFT_WORD(w[0]); + w[0] = RSHIFT_WORD(w[0]) ^ (mask & GHASH_POLYNOMIAL); # elif SIZEOF_LONG == 8 #define RSHIFT_WORD(x) \ ((((x) & 0xfefefefefefefefeUL) >> 1) \ | (((x) & 0x0101010101010101UL) << 15)) + mask = - ((w[1] >> 56) & 1); w[1] = RSHIFT_WORD(w[1]) | ((w[0] >> 49) & 0x80); - w[0] = RSHIFT_WORD(w[0]); + w[0] = RSHIFT_WORD(w[0]) ^ (mask & GHASH_POLYNOMIAL); # else # error Unsupported word size. */ # endif @@ -108,12 +111,10 @@ gcm_gf_mul (uint8_t *x, const uint8_t *y) unsigned j; for (j = 0; j < 8; j++, b <<= 1) { - int mask; if (b & 0x80) memxor(Z, V, sizeof(V)); - mask = - (V[15] & 1); + gcm_rightshift(V); - V[0] ^= mask & GHASH_POLYNOMIAL; } } memcpy (x, Z, sizeof(Z)); -- GitLab