📄 cwc.c
字号:
v = a[5] * ctx->zval[4]
+ a[4] * ctx->zval[5]; /* add in r[9] term */
f = (v + tp59) - tp59;
p = ctx->hash[3] + tp17 * (v - f);
v = (p + tp76) - tp76;
ctx->hash[3] = p - v;
ctx->hash[4] += tm07 * f + tm24 * v;
f = (ctx->hash[4] + tp76) - tp76;
ctx->hash[4] -= f;
ctx->hash[5] += tm24 * f;
reset_FPU;
}
#else
void do_cwc(uint_32t in[], cwc_ctx ctx[1])
{ uint_32t data[3];
double a[6], v, f;
/* set FPU to operate in 53 bit precision and */
/* in truncate to zero mode */
set_FPU;
data[2] = bswap_32(in[2]);
data[1] = bswap_32(in[1]);
data[0] = bswap_32(in[0]);
/* split input data into 24 bit double values */
a[0] = data[2] & 0x00ffffff;
a[1] = (data[2] >> 24) | ((data[1] & 0x0000ffff) << 8);
a[2] = (data[1] >> 16) | ((data[0] & 0x000000ff) << 16);
a[3] = data[0] >> 8;
/* add into the running hash value */
a[0] += ctx->hash[0]; a[1] += ctx->hash[1];
a[2] += ctx->hash[2]; a[3] += ctx->hash[3];
a[4] = ctx->hash[4]; a[5] = ctx->hash[5];
/* calculate the low five terms of the product */
ctx->hash[0] = a[0] * ctx->zval[0];
ctx->hash[1] = a[1] * ctx->zval[0]
+ a[0] * ctx->zval[1];
ctx->hash[2] = a[2] * ctx->zval[0]
+ a[1] * ctx->zval[1]
+ a[0] * ctx->zval[2];
ctx->hash[3] = a[3] * ctx->zval[0]
+ a[2] * ctx->zval[1]
+ a[1] * ctx->zval[2]
+ a[0] * ctx->zval[3];
ctx->hash[4] = a[4] * ctx->zval[0]
+ a[3] * ctx->zval[1]
+ a[2] * ctx->zval[2]
+ a[1] * ctx->zval[3]
+ a[0] * ctx->zval[4];
ctx->hash[5] = a[5] * ctx->zval[0]
+ a[4] * ctx->zval[1]
+ a[3] * ctx->zval[2]
+ a[2] * ctx->zval[3]
+ a[1] * ctx->zval[4]
+ a[0] * ctx->zval[5];
v = a[5] * ctx->zval[5]; /* add in r[10] term */
f = (v + tp59) - tp59;
ctx->hash[4] += tp17 * (v - f);
ctx->hash[5] += tm07 * f;
/* do a modular reduction step */
f = (ctx->hash[5] + tp59) - tp59;
ctx->hash[5] -= f;
ctx->hash[0] += tm07 * f;
v = a[5] * ctx->zval[1]
+ a[4] * ctx->zval[2]
+ a[3] * ctx->zval[3]
+ a[2] * ctx->zval[4]
+ a[1] * ctx->zval[5]; /* add in r[6] term */
f = (v + tp59) - tp59;
ctx->hash[0] += tp17 * (v - f);
ctx->hash[1] += tm07 * f;
v = a[5] * ctx->zval[2]
+ a[4] * ctx->zval[3]
+ a[3] * ctx->zval[4]
+ a[2] * ctx->zval[5]; /* add in r[7] term */
f = (v + tp59) - tp59;
ctx->hash[1] += tp17 * (v - f);
ctx->hash[2] += tm07 * f;
v = a[5] * ctx->zval[3]
+ a[4] * ctx->zval[4]
+ a[3] * ctx->zval[5]; /* add in r[8] term */
f = (v + tp59) - tp59;
ctx->hash[2] += tp17 * (v - f);
ctx->hash[3] += tm07 * f;
v = a[5] * ctx->zval[4]
+ a[4] * ctx->zval[5]; /* add in r[9] term */
f = (v + tp59) - tp59;
ctx->hash[3] += tp17 * (v - f);
ctx->hash[4] += tm07 * f;
/* ripple the carries */
f = (ctx->hash[0] + tp76) - tp76;
ctx->hash[0] -= f;
ctx->hash[1] += tm24 * f;
f = (ctx->hash[1] + tp76) - tp76;
ctx->hash[1] -= f;
ctx->hash[2] += tm24 * f;
f = (ctx->hash[2] + tp76) - tp76;
ctx->hash[2] -= f;
ctx->hash[3] += tm24 * f;
f = (ctx->hash[3] + tp76) - tp76;
ctx->hash[3] -= f;
ctx->hash[4] += tm24 * f;
f = (ctx->hash[4] + tp76) - tp76;
ctx->hash[4] -= f;
ctx->hash[5] += tm24 * f;
/* do a modular reduction step */
f = (ctx->hash[5] + tp59) - tp59;
ctx->hash[5] -= f;
ctx->hash[0] += tm07 * f;
reset_FPU;
}
#endif
#else
/* add multiple length unsigned values in big endian form */
/* little endian long words in big endian word order */
void add_4(uint_32t l[], uint_32t r[])
{ uint_32t ss, cc;
ss = l[3] + r[3];
cc = (ss < l[3] ? 1 : 0);
l[3] = ss;
ss = l[2] + r[2] + cc;
cc = (ss < l[2] ? 1 : ss > l[2] ? 0 : cc);
l[2] = ss;
ss = l[1] + r[1] + cc;
cc = (ss < l[1] ? 1 : ss > l[1] ? 0 : cc);
l[1] = ss;
l[0] += r[0] + cc;
}
/* multiply multiple length unsigned values in big endian form */
/* little endian long words in big endian word order */
void mlt_4(uint_32t r[], const uint_32t a[], const uint_32t b[])
{ uint_64t ch, cl, sm;
int i, j, k;
for(i = 0, cl = 0; i < 8; ++i)
{
/* number of terms in sum */
k = (i < 3 ? 0 : i - 3);
for(j = k, ch = 0; j <= i - k; ++j)
{
sm = (uint_64t)a[3 - j] * b[3 - i + j];
cl += (uint_32t)sm;
ch += (sm >> 32);
}
r[7 - i] = (uint_32t)cl;
cl = (cl >> 32) + ch;
}
}
/* Carter-Wegman hash iteration on 12 bytes of data */
void do_cwc(uint_32t in[], cwc_ctx ctx[1])
{ uint_32t *pt = ctx->hash + (CWC_CBLK_SIZE >> 2), data[4];
/* put big endian 32-bit items into little endian order */
data[3] = bswap_32(in[2]);
data[2] = bswap_32(in[1]);
data[1] = bswap_32(in[0]);
data[0] = 0;
/* add current hash value into the current data block */
add_4(data, ctx->hash);
/* multiply by the hash key in Z */
mlt_4(ctx->hash, data, ctx->zval);
/* we now want to find the remainder when divided by */
/* (2^127 - 1). If hash = 2^128 * hi + lo, we can see */
/* that hash = (2^127 - 1) * 2 * hi + 2 * hi + lo, so */
/* we can set the 128 bit remainder as 2 * hi + lo */
add_4(ctx->hash, ctx->hash);/* 2 * hi - if top bit = 1 */
if(*pt & 0x80000000) /* another 2^127-1 has to be */
{ /* subtracted from the result */
*pt &= 0x7fffffff;
*(pt - 1) += 1;
}
add_4(ctx->hash, pt); /* 2 * hi + lo - adjust the */
if(*ctx->hash & 0x80000000) /* result again (as above) */
{
*ctx->hash &= 0x7fffffff;
be_inc((uint_32t*)ctx->hash, 0);
}
}
#endif
ret_type cwc_init_and_key( /* initialise mode and set key */
const unsigned char key[], /* the key value */
unsigned long key_len, /* and its length in bytes */
cwc_ctx ctx[1]) /* the mode context */
{
uint_32t zv[CWC_CBLK_SIZE >> 2];
if(key_len != 16 && key_len != 24 && key_len != 32)
return RETURN_ERROR;
/* set all bytes in the context to zero */
memset(ctx, 0, sizeof(cwc_ctx));
/* set up encryption context */
aes_encrypt_key(key, key_len, ctx->enc_ctx);
/* initialise cwc z value */
memset(zv, 0, (CWC_CBLK_SIZE >> 2) * sizeof(uint_32t));
((unsigned char*)zv)[0] = 0xc0;
aes_encrypt((unsigned char*)zv, (unsigned char*)zv, ctx->enc_ctx);
((unsigned char*)zv)[0] &= 0x7f;
#if PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN
bswap32_block(zv, zv, 4);
#endif
#if defined( USE_FLOATS )
/* set up the z value in 24 bit doubles */
ctx->zval[0] = zv[3] & 0x00ffffff;
ctx->zval[1] = (zv[3] >> 24) | ((zv[2] & 0x0000ffff) << 8);
ctx->zval[2] = (zv[2] >> 16) | ((zv[1] & 0x000000ff) << 16);
ctx->zval[3] = zv[1] >> 8;
ctx->zval[4] = zv[0] & 0x00ffffff;
ctx->zval[5] = zv[0] >> 24;
#endif
#if defined(USE_LONGS )
memcpy(ctx->zval, zv, CWC_CBLK_SIZE);
#endif
return RETURN_OK;
}
ret_type cwc_init_message( /* initialise a new message */
const unsigned char iv[], /* the initialisation vector */
unsigned long iv_len, /* and its length in bytes */
cwc_ctx ctx[1]) /* the mode context */
{ uint_32t i;
/* set up the initial iv in the context */
ui8_ptr(ctx->ctr_val)[0] = 0x80;
for(i = 0; i < 11; ++i)
ui8_ptr(ctx->ctr_val)[i + 1] = iv[i];
ui8_ptr(ctx->ctr_val)[12] = 0; ui8_ptr(ctx->ctr_val)[13] = 0;
ui8_ptr(ctx->ctr_val)[14] = 0; ui8_ptr(ctx->ctr_val)[15] = 1;
memset(ctx->cwc_buf, 0, sizeof(ctx->cwc_buf));
ctx->hdr_cnt = 0;
ctx->txt_acnt = 0;
ctx->txt_ccnt = 0;
#if defined( USE_FLOATS )
ctx->hash[0] = 0; ctx->hash[1] = 0;
ctx->hash[2] = 0; ctx->hash[3] = 0;
ctx->hash[4] = 0; ctx->hash[5] = 0;
#endif
#if defined( USE_LONGS )
memset(ctx->hash, 0, sizeof(ctx->hash));
#endif
return RETURN_OK;
}
ret_type cwc_auth_header( /* authenticate the header */
const unsigned char hdr[], /* the header buffer */
unsigned long hdr_len, /* and its length in bytes */
cwc_ctx ctx[1]) /* the mode context */
{ uint_32t cnt = 0, b_pos = ctx->hdr_cnt;
if(!hdr_len)
return RETURN_OK;
b_pos -= (b_pos / ABLK_LEN) * ABLK_LEN;
while(cnt < hdr_len && (b_pos & BUF_ADRMASK))
ui8_ptr(ctx->cwc_buf)[b_pos++] = hdr[cnt++];
if(!(b_pos & BUF_ADRMASK) && !((hdr + cnt - ui8_ptr(ctx->cwc_buf)) & BUF_ADRMASK))
{
while(cnt + BUF_INC <= hdr_len && b_pos <= ABLK_LEN - BUF_INC)
{
*unit_ptr(ui8_ptr(ctx->cwc_buf) + b_pos) = *unit_ptr(hdr + cnt);
cnt += BUF_INC; b_pos += BUF_INC;
}
while(cnt + ABLK_LEN <= hdr_len)
{
do_cwc(ui32_ptr(ctx->cwc_buf), ctx);
memcpy(ctx->cwc_buf, hdr + cnt, ABLK_LEN);
cnt += ABLK_LEN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -