На этом сайте вниманию публики представлен новый метод блочного шифрования от компании Extra Systems. Автором этого изобретения является Юрий Павленко.
Размер блока — 8 на 8 байт, то есть — массив из 8-ми 64-битных чисел. То есть, фактически, этот метод разработан именно под нынешние 64-битные реалии.
В отличие от AES (у которого блок имеет размер 4 на 4 байта) сдвиг строк (процедуры «shift_encode» и «shift_decode») выполняется не по байтам, по битам. Причем, и в этом состоит еще одно важное новшество, эта операция производится и до, и после транспонирования матрицы (процедура «transpose_the_matrix»). Таким образом, перетасовка битов производится и по горизонтали, и по вертикали.
В соответствии с общепринятыми в настоящий момент в современной криптографии канонами (принцип Керкгоффса и максима Шеннона), ниже публикуется полный код Extra Systems Block Cipher (сокращенно - ESBC).
#define MATRIX_SIZE 8
#define STEP_LIMIT 32
#define SUB_STEPS 2
#define RC4_SKIP_TRASH 1587
#define XLAT_RANDOMIZE_STEPS 512
uint64_t the_matrix[MATRIX_SIZE];
uint64_t step_key[STEP_LIMIT][SUB_STEPS][MATRIX_SIZE];
unsigned int shift_key[STEP_LIMIT][SUB_STEPS][MATRIX_SIZE];
unsigned char xlat_encode_table[STEP_LIMIT][SUB_STEPS][256]
unsigned char xlat_decode_table[STEP_LIMIT][SUB_STEPS][256];
unsigned char shuffle_key[STEP_LIMIT][SUB_STEPS];
struct {
unsigned char state[256];
unsigned char x;
unsigned char y;
} rc4_key_table;
void swap_byte(unsigned char *a, unsigned char *b)
{
unsigned char swapByte;
swapByte = *a;
*a = *b;
*b = swapByte;
}
void prepare_rc4_key(unsigned char *key_data_ptr, int key_data_len)
{
unsigned char index1, index2;
unsigned char* state;
int counter;
state = rc4_key_table.state;
for(counter = 0; counter < 256; counter++) state[counter] = counter;
rc4_key_table.x = 0; rc4_key_table.y = 0;
index1 = 0; index2 = 0;
for(counter = 0; counter < 256; counter++)
{
index2 = (key_data_ptr[index1] + state[counter] + index2) & 255;
swap_byte(&state[counter], &state[index2]);
index1 = (index1 + 1) % key_data_len;
}
}
unsigned char get_rc4_data(void)
{
unsigned char x, y;
unsigned char *state;
unsigned char xorIndex;
x = rc4_key_table.x; y = rc4_key_table.y;
state = rc4_key_table.state;
x = (x + 1) & 255;
y = (state[x] + y) & 255;
swap_byte(&state[x], &state[y]);
xorIndex = (state[x] + state[y]) & 255;
rc4_key_table.x = x;
rc4_key_table.y = y;
return state[xorIndex];
}
void reverse_xlat_table(unsigned char *encode_table, unsigned char *decode_table)
{
int i;
unsigned char src;
for(i = 0; i < 256; i++)
{
src = encode_table[i];
decode_table[src] = i;
}
}
void make_key_data(unsigned char *key_data_ptr, int key_data_len)
{
int i, j, k;
unsigned char src, dst, x, y;
unsigned char *step_key_array = (unsigned char *)step_key;
prepare_rc4_key(key_data_ptr, key_data_len);
for (i = 0; i < RC4_SKIP_TRASH; i++) get_rc4_data();
for (i = 0; i < STEP_LIMIT; i++)
{
for (k = 0; k < SUB_STEPS; k++) while((shuffle_key[i][k] = get_rc4_data()) == 0 || shuffle_key[i][k] == 0xFF);
for (k = 0; k < SUB_STEPS; k++)
for (j = 0; j < MATRIX_SIZE; j++) while((shift_key[i][k][j] = get_rc4_data() & 63) == 0);
for (k = 0; k < SUB_STEPS; k++)
for (j = 0; j < 256; j++) xlat_encode_table[i][k][j] = j;
for (k = 0; k < SUB_STEPS; k++)
{
for (j = 0; j < XLAT_RANDOMIZE_STEPS; j++)
{
x = j & 255;
while((y = get_rc4_data()) == x);
src = xlat_encode_table[i][k][x];
dst = xlat_encode_table[i][k][y];
xlat_encode_table[i][k][x] = dst;
xlat_encode_table[i][k][y] = src;
}
}
for (k = 0; k < SUB_STEPS; k++) reverse_xlat_table(xlat_encode_table[i][k], xlat_decode_table[i][k]);
}
for (i = 0; i < sizeof(step_key); i++) step_key_array[i] = get_rc4_data();
}
void shift_encode(uint64_t *the_matrix, unsigned int *key_set)
{
int i;
for (i = 0; i < MATRIX_SIZE; i++) the_matrix[i] = (the_matrix[i] << key_set[i]) | (the_matrix[i] >> (64 - key_set[i]));
}
void shift_decode(uint64_t *the_matrix, unsigned int *key_set)
{
int i;
for (i = 0; i < MATRIX_SIZE; i++) the_matrix[i] = (the_matrix[i] >> key_set[i]) | (the_matrix[i] << (64 - key_set[i]));
}
void add_step_key(uint64_t *the_matrix, uint64_t *the_key)
{
int i;
for (i = 0; i < MATRIX_SIZE; i++) the_matrix[i] = the_matrix[i] + the_key[i];
}
void sub_step_key(uint64_t *the_matrix, uint64_t *the_key)
{
int i;
for (i = 0; i < MATRIX_SIZE; i++) the_matrix[i] = the_matrix[i] - the_key[i];
}
void transpose_the_matrix(uint64_t *the_matrix)
{
int i, j;
uint64_t x[MATRIX_SIZE], y[MATRIX_SIZE];
for (i = 0; i < MATRIX_SIZE; i++) y[i] = the_matrix[i];
for (i = 0; i < MATRIX_SIZE; i++)
{
x[i] = 0;
for (j = 0; j < MATRIX_SIZE; j++)
{
x[i] <<= 8;
x[i] |= y[j] >> 56;
y[j] <<= 8;
}
}
for (i = 0; i < MATRIX_SIZE; i++) the_matrix[i] = x[i];
}
void xlat_the_matrix(unsigned char *the_matrix, unsigned char *the_xlat_table)
{
int i;
for (i = 0; i < MATRIX_SIZE * MATRIX_SIZE; i++) the_matrix[i] = the_xlat_table[the_matrix[i]];
}
void shuffle_the_matrix(unsigned char *the_matrix, unsigned char the_shuffle_key)
{
int i, j;
unsigned char x, y, swap_new;
swap_new = ~the_shuffle_key;
for(i = 0; i < MATRIX_SIZE * MATRIX_SIZE / 2; i++)
{
j = MATRIX_SIZE * MATRIX_SIZE - i - 1;
x = the_matrix[i];
y = the_matrix[j];
the_matrix[i] = (x & the_shuffle_key) | (y & swap_new);
the_matrix[j] = (y & the_shuffle_key) | (x & swap_new);
}
}
void twist_the_matrix(unsigned char *the_matrix)
{
int i, j;
unsigned char x, y;
for(i = 0; i < MATRIX_SIZE * MATRIX_SIZE / 2; i++)
{
j = MATRIX_SIZE * MATRIX_SIZE / 2 + i;
x = the_matrix[i];
y = the_matrix[j];
the_matrix[i] = (x & 0xF0) | (y >> 4);
the_matrix[j] = (y & 0xF) | (x << 4);
}
}
void xor_line_encode(uint64_t *the_matrix)
{
int i;
uint64_t x[MATRIX_SIZE];
for(i = 0; i < MATRIX_SIZE; i++) x[i] = the_matrix[i];
for(i = 0; i < MATRIX_SIZE - 1; i++) x[i] ^= the_matrix[i + 1];
x[MATRIX_SIZE - 1] ^= the_matrix[0];
for(i = 0; i < MATRIX_SIZE; i++) the_matrix[i] = x[i];
}
void xor_line_decode(uint64_t *the_matrix)
{
int i;
uint64_t x[MATRIX_SIZE];
for(i = 0; i < MATRIX_SIZE; i++) x[i] = the_matrix[i];
x[MATRIX_SIZE - 1] ^= the_matrix[0];
for(i = MATRIX_SIZE - 2; i >= 0; i--) x[i] ^= the_matrix[i + 1];
for(i = 0; i < MATRIX_SIZE; i++) the_matrix[i] = x[i];
}
void add_matrix_line(uint64_t *the_matrix)
{
int i;
uint64_t x[MATRIX_SIZE];
for(i = 0; i < MATRIX_SIZE; i++) x[i] = the_matrix[i];
for(i = 0; i < MATRIX_SIZE - 1; i++) x[i] += the_matrix[i + 1];
x[MATRIX_SIZE - 1] += the_matrix[0];
for(i = 0; i < MATRIX_SIZE; i++) the_matrix[i] = x[i];
}
void sub_matrix_line(uint64_t *the_matrix)
{
int i;
uint64_t x[MATRIX_SIZE];
for(i = 0; i < MATRIX_SIZE; i++) x[i] = the_matrix[i];
x[MATRIX_SIZE - 1] -= the_matrix[0];
for(i = MATRIX_SIZE - 2; i >= 0; i--) x[i] -= the_matrix[i + 1];
for(i = 0; i < MATRIX_SIZE; i++) the_matrix[i] = x[i];
}
void add_const(uint64_t *the_matrix, int i, int semi_step)
{
int j;
uint64_t c, d;
c = (uint64_t)(i + semi_step + 1);
c = c * c * c;
for(j = 0; j < MATRIX_SIZE; j++)
{
d = (uint64_t)(j + semi_step + 1);
d = d * d * c;
d *= d;
d ^= (~d << 32);
the_matrix[j] += d;
}
}
void sub_const(uint64_t *the_matrix, int i, int semi_step)
{
int j;
uint64_t c, d;
c = (uint64_t)(i + semi_step + 1);
c = c * c * c;
for(j = 0; j < MATRIX_SIZE; j++)
{
d = (uint64_t)(j + semi_step + 1);
d = d * d * c;
d *= d;
d ^= (~d << 32);
the_matrix[j] -= d;
}
}
void encode_matrix(void)
{
int i;
for (i = 0; i < STEP_LIMIT; i++)
{
add_const(the_matrix, i, 1);
add_step_key(the_matrix, step_key[i][0]);
twist_the_matrix((unsigned char *)the_matrix);
xlat_the_matrix((unsigned char *)the_matrix, xlat_encode_table[i][0]);
xor_line_encode(the_matrix);
shift_encode(the_matrix, shift_key[i][0]);
add_matrix_line(the_matrix);
twist_the_matrix((unsigned char *)the_matrix);
shuffle_the_matrix((unsigned char *)the_matrix, shuffle_key[i][0]);
transpose_the_matrix(the_matrix);
add_const(the_matrix, i, 2);
add_step_key(the_matrix, step_key[i][1]);
twist_the_matrix((unsigned char *)the_matrix);
xlat_the_matrix((unsigned char *)the_matrix, xlat_encode_table[i][1]);
xor_line_encode(the_matrix);
shift_encode(the_matrix, shift_key[i][1]);
add_matrix_line(the_matrix);
shuffle_the_matrix((unsigned char *)the_matrix, shuffle_key[i][1]);
}
}
void decode_matrix(void)
{
int i;
for (i = STEP_LIMIT - 1; i >= 0; i--)
{
shuffle_the_matrix((unsigned char *)the_matrix, shuffle_key[i][1]);
sub_matrix_line(the_matrix);
shift_decode(the_matrix, shift_key[i][1]);
xor_line_decode(the_matrix);
xlat_the_matrix((unsigned char *)the_matrix, xlat_decode_table[i][1]);
twist_the_matrix((unsigned char *)the_matrix);
sub_step_key(the_matrix, step_key[i][1]);
sub_const(the_matrix, i, 2);
transpose_the_matrix(the_matrix);
shuffle_the_matrix((unsigned char *)the_matrix, shuffle_key[i][0]);
twist_the_matrix((unsigned char *)the_matrix);
sub_matrix_line(the_matrix);
shift_decode(the_matrix, shift_key[i][0]);
xor_line_decode(the_matrix);
xlat_the_matrix((unsigned char *)the_matrix, xlat_decode_table[i][0]);
twist_the_matrix((unsigned char *)the_matrix);
sub_step_key(the_matrix, step_key[i][0]);
sub_const(the_matrix, i, 1);
}
}
| © Extra Systems, 2026 |