Skip to content
Snippets Groups Projects
Commit 49da2d43 authored by Niels Möller's avatar Niels Möller
Browse files

(gcm_gf_mul): Rewrote. Still uses the bitwise algorithm from the

specification, but with separate byte and bit loops. Improves gmac
performance a bit further, to 227 cycles/byte.

Rev: nettle/gcm.c:1.3
parent 4e268816
No related branches found
No related tags found
No related merge requests found
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
* *
* Contributed by Nikos Mavrogiannopoulos * Contributed by Nikos Mavrogiannopoulos
* *
* A few functions copied from Tom S. Dennis' libtomcrypt, which is in
* the public domain.
*
* The nettle library is free software; you can redistribute it and/or modify * The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your * the Free Software Foundation; either version 2.1 of the License, or (at your
...@@ -48,12 +45,16 @@ ...@@ -48,12 +45,16 @@
#include "nettle-internal.h" #include "nettle-internal.h"
#include "macros.h" #include "macros.h"
#define GHASH_POLYNOMIAL 0xE1
/* Big-endian shift right. The argument must be properly aligned for /* Big-endian shift right. The argument must be properly aligned for
word accesses. */ word accesses. */
/* FIXME: Move the reduction/wraparound into this functions as
well. */
static void static void
gcm_rightshift (uint8_t *a) gcm_rightshift (uint8_t *x)
{ {
unsigned long *w = (unsigned long *) a; unsigned long *w = (unsigned long *) x;
/* Shift uses big-endian representation. */ /* Shift uses big-endian representation. */
#if WORDS_BIGENDIAN #if WORDS_BIGENDIAN
...@@ -88,39 +89,34 @@ gcm_rightshift (uint8_t *a) ...@@ -88,39 +89,34 @@ gcm_rightshift (uint8_t *a)
# endif # endif
#endif /* ! WORDS_BIGENDIAN */ #endif /* ! WORDS_BIGENDIAN */
} }
/* The function gcm_gf_mul was copied from
* libtomcrypt, which is under public domain.
* Written by Tom S. Dennis.
*/
/** /* Sets a <- a * b mod r, using the plain bitwise algorithm from the
GCM GF multiplier (internal use only) bitserial specification. */
@param a First value (and destination)
@param b Second value
*/
static void static void
gcm_gf_mul (uint8_t * a, const uint8_t * b) gcm_gf_mul (uint8_t *x, const uint8_t *y)
{ {
static const uint8_t mask[] = uint8_t V[GCM_BLOCK_SIZE];
{ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; uint8_t Z[GCM_BLOCK_SIZE];
static const uint8_t poly[] = { 0x00, 0xE1 };
uint8_t Z[16], V[16]; unsigned i;
unsigned x, z; memcpy(V, x, sizeof(V));
memset(Z, 0, sizeof(Z));
memset (Z, 0, 16); for (i = 0; i < GCM_BLOCK_SIZE; i++)
memcpy (V, a, 16);
for (x = 0; x < 128; x++)
{ {
if (b[x >> 3] & mask[x & 7]) uint8_t b = y[i];
{ unsigned j;
memxor (Z, V, 16); for (j = 0; j < 8; j++, b <<= 1)
} {
z = V[15] & 0x01; int mask;
gcm_rightshift (V); if (b & 0x80)
V[0] ^= poly[z]; memxor(Z, V, sizeof(V));
mask = - (V[15] & 1);
gcm_rightshift(V);
V[0] ^= mask & GHASH_POLYNOMIAL;
}
} }
memcpy (a, Z, 16); memcpy (x, Z, sizeof(Z));
} }
/* Increment the rightmost 32 bits. */ /* Increment the rightmost 32 bits. */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment