Попытка создания более быстрого алгоритма хеширования на основе SHA-256
Ожидает приглашения
Собственно на написание сподвигло неторопливость работы криптографически-православного SHA-256.
Алгоритм перемешивания взят из реализации SHA-256 BSD, с небольшим усовершенствованием.
При запуске программы выводятся хеши строк, различающихся одним битом.
Выношу на суд сообщества, комментарии приветствуются:
Компилируем GCC.
Алгоритм перемешивания взят из реализации SHA-256 BSD, с небольшим усовершенствованием.
При запуске программы выводятся хеши строк, различающихся одним битом.
Выношу на суд сообщества, комментарии приветствуются:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
// cyclic diletantic check
struct cdc256_data {
uint64_t a, b, c, d, e, f, g, h;
uint64_t position;
};
struct cdc256 {
union {
uint8_t data[32];
uint32_t d32[8];
uint64_t d64[4];
};
};
static const struct cdc256_data prime = {
UINT64_C(0x992E367BE6F0EA1E),
UINT64_C(0x71DCF41FFACC283F),
UINT64_C(0xC9581F48D85ABD75),
UINT64_C(0xE4B93335FF1CE990),
UINT64_C(0xE51D6424EFEC1E01),
UINT64_C(0x353867A0E66C2A39),
UINT64_C(0xA8DBF7B782226B67),
UINT64_C(0x9F8B7F0DC254488E),
0
};
static void shuffle(struct cdc256_data * v)
{
v->a -= v->e; v->f ^= v->h >> 9; v->h += v->a;
v->b -= v->f; v->g ^= v->a << 9; v->a += v->b;
v->c -= v->g; v->h ^= v->b >> 23; v->b += v->c;
v->d -= v->h; v->a ^= v->c << 15; v->c += v->d;
v->e -= v->a; v->b ^= v->d >> 14; v->d += v->e;
v->f -= v->b; v->c ^= v->e << 20; v->e += v->f;
v->g -= v->c; v->d ^= v->f >> 17; v->f += v->g;
v->h -= v->d; v->e ^= v->g << 14; v->g += v->h;
}
static void update(struct cdc256_data * a,const struct cdc256_data * v)
{
a->a -= v->e; a->f ^= v->h >> 9; a->h += v->a;
a->b -= v->f; a->g ^= v->a << 9; a->a += v->b;
a->c -= v->g; a->h ^= v->b >> 23; a->b += v->c;
a->d -= v->h; a->a ^= v->c << 15; a->c += v->d;
a->e -= v->a; a->b ^= v->d >> 14; a->d += v->e;
a->f -= v->b; a->c ^= v->e << 20; a->e += v->f;
a->g -= v->c; a->d ^= v->f >> 17; a->f += v->g;
a->h -= v->d; a->e ^= v->g << 14; a->g += v->h;
}
void cdc256_init(struct cdc256_data * code)
{
static const struct cdc256_data init_value = {
UINT64_C(0xA640524A5B44F1FC),
UINT64_C(0xC535059705F0BB7E),
UINT64_C(0xC8ED76CF6B6EA626),
UINT64_C(0x531D1E8E254EA59E),
UINT64_C(0x8C0FE7F3E46E2A80),
UINT64_C(0x1C53F41FD1E3A7F8),
UINT64_C(0x08D4DEAAA1C33335),
UINT64_C(0x4C592980FBE9B011),
0
};
*code = init_value;
}
void cdc256_update(struct cdc256_data * code,const void * data,uintptr_t size)
{
struct cdc256_data pad;
code->position += size;
while( size > 0 ){
if( size < 64 ){
memcpy(&pad,data,size);
memset((uint8_t *) &pad + size,0,64 - size);
data = &pad;
}
update(code,(const struct cdc256_data *) data);
shuffle(code);
if( size < 64 ) break;
data = (const uint8_t *) data + 64;
size -= 64;
}
pad.a = pad.b = pad.c = pad.d = pad.e = pad.f = pad.g = pad.h = code->position;
shuffle(&pad);
shuffle(&pad);
update(code,&pad);
shuffle(code);
}
void cdc256_final(struct cdc256_data * code,struct cdc256 * cdc256)
{
uintptr_t c;
const uint8_t * p = (const uint8_t *) code;
for( c = 0; c < 4; c++, p += 16 ){
uint64_t h = 5381;
h = (h << 5) + h + p[0];
h = (h << 5) + h + p[1];
h = (h << 5) + h + p[2];
h = (h << 5) + h + p[3];
h = (h << 5) + h + p[4];
h = (h << 5) + h + p[5];
h = (h << 5) + h + p[6];
h = (h << 5) + h + p[7];
h = (h << 5) + h + p[8];
h = (h << 5) + h + p[9];
h = (h << 5) + h + p[10];
h = (h << 5) + h + p[11];
h = (h << 5) + h + p[12];
h = (h << 5) + h + p[13];
h = (h << 5) + h + p[14];
h = (h << 5) + h + p[15];
cdc256->d64[c] = h;
}
}
void cdc256_print(FILE * stream,const struct cdc256 * code)
{
fprintf(stream,
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
code->data[0],
code->data[1],
code->data[2],
code->data[3],
code->data[4],
code->data[5],
code->data[6],
code->data[7],
code->data[8],
code->data[9],
code->data[10],
code->data[11],
code->data[12],
code->data[13],
code->data[14],
code->data[15],
code->data[16],
code->data[17],
code->data[18],
code->data[19],
code->data[20],
code->data[21],
code->data[22],
code->data[23],
code->data[24],
code->data[25],
code->data[26],
code->data[27],
code->data[28],
code->data[29],
code->data[30],
code->data[31]
);
}
void main(void)
{
struct cdc256_data ctx;
struct cdc256 b;
char t[] = "0123456789ABCDEF";
cdc256_init(&ctx);
cdc256_update(&ctx,t,strlen(t));
cdc256_final(&ctx,&b);
fprintf(stderr,"%s\n",t);
cdc256_print(stdout,&b);
t[3] |= 0x40;
cdc256_init(&ctx);
cdc256_update(&ctx,t,strlen(t));
cdc256_final(&ctx,&b);
fprintf(stderr,"%s\n",t);
cdc256_print(stdout,&b);
}
Компилируем GCC.