📄 gfmul.c
字号:
xor_8k( 8); xor_8k( 9); xor_8k(10); xor_8k(11);
xor_8k(12); xor_8k(13); xor_8k(14); xor_8k(15);
move_block_aligned(a, r);
}
#else
void GfMul128Tab (unsigned char a[CBLK_LEN], GfCtx8k *ctx)
{ unsigned __int32 r[CBLK_LEN >> 2], *p;
int i;
p = ctx->gf_t8k[0][a[0] & 15];
memcpy(r, p, CBLK_LEN);
p = ctx->gf_t8k[1][a[0] >> 4];
xor_block_aligned(r, p);
for(i = 1; i < CBLK_LEN; ++i)
{
xor_block_aligned(r, ctx->gf_t8k[i + i][a[i] & 15]);
xor_block_aligned(r, ctx->gf_t8k[i + i + 1][a[i] >> 4]);
}
memcpy(a, r, CBLK_LEN);
}
#endif
void compile_8k_table(unsigned __int8 *a, GfCtx8k *ctx)
{ int i, j, k;
memset(ctx->gf_t8k, 0, 32 * 16 * 16);
for(i = 0; i < 2 * CBLK_LEN; ++i)
{
if(i == 0)
{
memcpy(ctx->gf_t8k[1][8], a, CBLK_LEN);
for(j = 4; j > 0; j >>= 1)
{
memcpy(ctx->gf_t8k[1][j], ctx->gf_t8k[1][j + j], CBLK_LEN);
mul_x(ctx->gf_t8k[1][j]);
}
memcpy(ctx->gf_t8k[0][8], ctx->gf_t8k[1][1], CBLK_LEN);
mul_x(ctx->gf_t8k[0][8]);
for(j = 4; j > 0; j >>= 1)
{
memcpy(ctx->gf_t8k[0][j], ctx->gf_t8k[0][j + j], CBLK_LEN);
mul_x(ctx->gf_t8k[0][j]);
}
}
else if(i > 1)
for(j = 8; j > 0; j >>= 1)
{
memcpy(ctx->gf_t8k[i][j], ctx->gf_t8k[i - 2][j], CBLK_LEN);
mul_x8(ctx->gf_t8k[i][j]);
}
for(j = 2; j < 16; j += j)
{
mode(32t) *pj = ctx->gf_t8k[i][j];
mode(32t) *pk = ctx->gf_t8k[i][1];
mode(32t) *pl = ctx->gf_t8k[i][j + 1];
for(k = 1; k < j; ++k)
{
*pl++ = pj[0] ^ *pk++;
*pl++ = pj[1] ^ *pk++;
*pl++ = pj[2] ^ *pk++;
*pl++ = pj[3] ^ *pk++;
}
}
}
}
void compile_4k_table64(unsigned __int8 *a, GfCtx4k64 *ctx)
{ int i, j, k;
memset(ctx->gf_t4k, 0, sizeof(ctx->gf_t4k));
for(i = 0; i < 2 * CBLK_LEN8; ++i)
{
if(i == 0)
{
memcpy(ctx->gf_t4k[1][8], a, CBLK_LEN8);
for(j = 4; j > 0; j >>= 1)
{
memcpy(ctx->gf_t4k[1][j], ctx->gf_t4k[1][j + j], CBLK_LEN8);
mul_x64(ctx->gf_t4k[1][j]);
}
memcpy(ctx->gf_t4k[0][8], ctx->gf_t4k[1][1], CBLK_LEN8);
mul_x64(ctx->gf_t4k[0][8]);
for(j = 4; j > 0; j >>= 1)
{
memcpy(ctx->gf_t4k[0][j], ctx->gf_t4k[0][j + j], CBLK_LEN8);
mul_x64(ctx->gf_t4k[0][j]);
}
}
else if(i > 1)
for(j = 8; j > 0; j >>= 1)
{
memcpy(ctx->gf_t4k[i][j], ctx->gf_t4k[i - 2][j], CBLK_LEN8);
mul_x8_64(ctx->gf_t4k[i][j]);
}
for(j = 2; j < 16; j += j)
{
mode(32t) *pj = ctx->gf_t4k[i][j];
mode(32t) *pk = ctx->gf_t4k[i][1];
mode(32t) *pl = ctx->gf_t4k[i][j + 1];
for(k = 1; k < j; ++k)
{
*pl++ = pj[0] ^ *pk++;
*pl++ = pj[1] ^ *pk++;
*pl++ = pj[2] ^ *pk++;
*pl++ = pj[3] ^ *pk++;
}
}
}
}
static int IsBitSet128 (unsigned int bit, unsigned __int8 *a)
{
return a[(127 - bit) / 8] & (0x80 >> ((127 - bit) % 8));
}
static int IsBitSet64 (unsigned int bit, unsigned __int8 *a)
{
return a[(63 - bit) / 8] & (0x80 >> ((63 - bit) % 8));
}
static void SetBit128 (unsigned int bit, unsigned __int8 *a)
{
a[(127 - bit) / 8] |= 0x80 >> ((127 - bit) % 8);
}
static void SetBit64 (unsigned int bit, unsigned __int8 *a)
{
a[(63 - bit) / 8] |= 0x80 >> ((63 - bit) % 8);
}
void MirrorBits128 (unsigned __int8 *a)
{
unsigned __int8 t[128 / 8];
int i;
memset (t,0,16);
for (i = 0; i < 128; i++)
{
if (IsBitSet128(i, a))
SetBit128 (127 - i, t);
}
memcpy (a, t, sizeof (t));
burn (t,sizeof (t));
}
void MirrorBits64 (unsigned __int8 *a)
{
unsigned __int8 t[64 / 8];
int i;
memset (t,0,8);
for (i = 0; i < 64; i++)
{
if (IsBitSet64(i, a))
SetBit64 (63 - i, t);
}
memcpy (a, t, sizeof (t));
burn (t,sizeof (t));
}
/* Allocate and initialize speed optimization table
for multiplication by 64-bit operand in MSB-first mode */
int Gf128Tab64Init (unsigned __int8 *a, GfCtx *ctx)
{
GfCtx8k *ctx8k;
unsigned __int8 am[16];
int i, j;
ctx8k = (GfCtx8k *) TCalloc (sizeof (GfCtx8k));
if (!ctx8k)
return FALSE;
memcpy (am, a, 16);
MirrorBits128 (am);
compile_8k_table (am, ctx8k);
/* Convert 8k LSB-first table to 4k MSB-first */
for (i = 16; i < 32; i++)
{
for (j = 0; j < 16; j++)
{
int jm = 0;
jm |= (j & 0x1) << 3;
jm |= (j & 0x2) << 1;
jm |= (j & 0x4) >> 1;
jm |= (j & 0x8) >> 3;
memcpy (&ctx->gf_t128[i-16][jm], (unsigned char *)&ctx8k->gf_t8k[31-i][j], 16);
MirrorBits128 ((unsigned char *)&ctx->gf_t128[i-16][jm]);
}
}
burn (ctx8k ,sizeof (*ctx8k));
burn (am, sizeof (am));
TCfree (ctx8k);
return TRUE;
}
int Gf64TabInit (unsigned __int8 *a, GfCtx *ctx)
{
/* Deprecated/legacy */
GfCtx4k64 *ctx4k;
unsigned __int8 am[8];
int i, j;
ctx4k = (GfCtx4k64 *) TCalloc (sizeof (GfCtx4k64));
if (!ctx4k)
return FALSE;
memcpy (am, a, 8);
MirrorBits64 (am);
compile_4k_table64 (am, ctx4k);
/* Convert LSB-first table to MSB-first */
for (i = 0; i < 16; i++)
{
for (j = 0; j < 16; j++)
{
int jm = 0;
jm |= (j & 0x1) << 3;
jm |= (j & 0x2) << 1;
jm |= (j & 0x4) >> 1;
jm |= (j & 0x8) >> 3;
memcpy (&ctx->gf_t64[i][jm], (unsigned char *)&ctx4k->gf_t4k[15-i][j], 8);
MirrorBits64 ((unsigned char *)&ctx->gf_t64[i][jm]);
}
}
burn (ctx4k,sizeof (*ctx4k));
burn (am, sizeof (am));
TCfree (ctx4k);
return TRUE;
}
#define xor_8kt64(i) \
xor_block_aligned(r, ctx->gf_t128[i + i][a[i] & 15]); \
xor_block_aligned(r, ctx->gf_t128[i + i + 1][a[i] >> 4])
/* Multiply a 128-bit number by a 64-bit number in the finite field GF(2^128) */
void Gf128MulBy64Tab (unsigned __int8 a[8], unsigned __int8 p[16], GfCtx *ctx)
{
unsigned __int32 r[CBLK_LEN >> 2];
move_block_aligned(r, ctx->gf_t128[7*2][a[7] & 15]);
xor_block_aligned(r, ctx->gf_t128[7*2+1][a[7] >> 4]);
if (*(unsigned __int16 *)a)
{
xor_8kt64(0);
xor_8kt64(1);
}
if (a[2])
{
xor_8kt64(2);
}
xor_8kt64(3);
xor_8kt64(4);
xor_8kt64(5);
xor_8kt64(6);
move_block_aligned(p, r);
}
#define xor_8k64(i) \
xor_block_aligned64(r, ctx->gf_t64[i + i][a[i] & 15]); \
xor_block_aligned64(r, ctx->gf_t64[i + i + 1][a[i] >> 4])
/* Multiply two 64-bit numbers in the finite field GF(2^64) */
void Gf64MulTab (unsigned char a[8], unsigned char p[8], GfCtx *ctx)
{
/* Deprecated/legacy */
unsigned __int32 r[CBLK_LEN8 >> 2];
move_block_aligned64(r, ctx->gf_t64[7*2][a[7] & 15]);
xor_block_aligned64(r, ctx->gf_t64[7*2+1][a[7] >> 4]);
if (*(unsigned __int16 *)a)
{
xor_8k64(0);
xor_8k64(1);
}
if (a[2])
{
xor_8k64(2);
}
xor_8k64(3);
xor_8k64(4);
xor_8k64(5);
xor_8k64(6);
move_block_aligned64(p, r);
}
/* Basic algorithms for testing of optimized algorithms */
static void xor128 (unsigned __int64 *a, unsigned __int64 *b)
{
*a++ ^= *b++;
*a ^= *b;
}
static void shl128 (unsigned __int8 *a)
{
int i, x = 0, xx;
for (i = 15; i >= 0; i--)
{
xx = (a[i] & 0x80) >> 7;
a[i] = (a[i] << 1) | x;
x = xx;
}
}
static void GfMul128Basic (unsigned __int8 *a, unsigned __int8 *b, unsigned __int8 *p)
{
int i;
unsigned __int8 la[16];
memcpy (la, a, 16);
memset (p, 0, 16);
for (i = 0; i < 128; i++)
{
if (IsBitSet128 (i, b))
xor128 ((unsigned __int64 *)p, (unsigned __int64 *)la);
if (la[0] & 0x80)
{
shl128 (la);
la[15] ^= 0x87;
}
else
{
shl128 (la);
}
}
}
static void xor64 (unsigned __int64 *a, unsigned __int64 *b)
{
*a ^= *b;
}
static void shl64 (unsigned __int8 *a)
{
int i, x = 0, xx;
for (i = 7; i >= 0; i--)
{
xx = (a[i] & 0x80) >> 7;
a[i] = (a[i] << 1) | x;
x = xx;
}
}
static void GfMul64Basic (unsigned __int8 *a, unsigned __int8 *b, unsigned __int8* p)
{
/* Deprecated/legacy */
int i;
unsigned __int8 la[8];
memcpy (la, a, 8);
memset (p, 0, 8);
for (i = 0; i < 64; i++)
{
if (IsBitSet64 (i, b))
xor64 ((unsigned __int64 *)p, (unsigned __int64 *)la);
if (la[0] & 0x80)
{
shl64 (la);
la[7] ^= 0x1b;
}
else
{
shl64 (la);
}
}
}
BOOL GfMulSelfTest ()
{
BOOL result = TRUE;
unsigned __int8 a[16];
unsigned __int8 b[16];
unsigned __int8 p1[16];
unsigned __int8 p2[16];
GfCtx *gfCtx = (GfCtx *) TCalloc (sizeof (GfCtx));
int i, j;
if (!gfCtx)
return FALSE;
/* GF(2^64) - deprecated/legacy */
for (i = 0; i < 0x100; i++)
{
for (j = 0; j < 8; j++)
{
a[j] = (unsigned __int8) i;
b[j] = a[j] ^ 0xff;
}
GfMul64Basic (a, b, p1);
Gf64TabInit (a, gfCtx);
Gf64MulTab (b, p2, gfCtx);
if (memcmp (p1, p2, 8) != 0)
result = FALSE;
}
/* GF(2^128) */
for (i = 0; i < 0x100; i++)
{
for (j = 0; j < 16; j++)
{
a[j] = (unsigned __int8) i;
b[j] = j < 8 ? 0 : a[j] ^ 0xff;
}
GfMul128Basic (a, b, p1);
Gf128Tab64Init (a, gfCtx);
Gf128MulBy64Tab (b + 8, p2, gfCtx);
if (memcmp (p1, p2, 16) != 0)
result = FALSE;
}
TCfree (gfCtx);
return result;
}
#if defined(__cplusplus)
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -