magenta.c
来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· C语言 代码 · 共 280 行
C
280 行
/* This is an independent implementation of the encryption algorithm: */
/* */
/* MAGENTA by Deutche Telekom */
/* */
/* which is a candidate algorithm in the Advanced Encryption Standard */
/* programme of the US National Institute of Standards and Technology. */
/* */
/* Copyright in this implementation is held by Dr B R Gladman but I */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
/* that the originators of the algorithm place on its exploitation. */
/* */
/* Dr Brian Gladman 14th January 1999 */
/* Timing data for MAGENTA (magenta.c)
128 bit key:
Key Setup: 30 cycles
Encrypt: 6539 cycles = 3.9 mbits/sec
Decrypt: 6534 cycles = 3.9 mbits/sec
Mean: 6537 cycles = 3.9 mbits/sec
192 bit key:
Key Setup: 25 cycles
Encrypt: 6531 cycles = 3.9 mbits/sec
Decrypt: 6528 cycles = 3.9 mbits/sec
Mean: 6530 cycles = 3.9 mbits/sec
256 bit key:
Key Setup: 37 cycles
Encrypt: 8711 cycles = 2.9 mbits/sec
Decrypt: 8705 cycles = 2.9 mbits/sec
Mean: 8708 cycles = 2.9 mbits/sec
*/
#define LARGE_TABLES
#include "../std_defs.h"
static char *alg_name[] = { "magenta", "magenta.c", "magenta" };
char **cipher_name()
{
return alg_name;
}
#define GF_POLY 0x0165;
u4byte k_len;
u4byte l_key[16]; /* storage for the key schedule */
u1byte f_tab[256];
u4byte tab_init = 0;
#ifdef LARGE_TABLES
u4byte fl_tab[4][256];
#endif
void init_tab(void)
{ u4byte i, f;
f = 1;
for(i = 0; i < 255; ++i)
{
f_tab[i] = (u1byte)f;
#ifdef LARGE_TABLES
fl_tab[0][i] = f;
fl_tab[1][i] = f << 8;
fl_tab[2][i] = f << 16;
fl_tab[3][i] = f << 24;
#endif
f <<= 1;
if(f & 0x100)
f ^= GF_POLY;
}
f_tab[255] = 0;
#ifdef LARGE_TABLES
fl_tab[0][255] = fl_tab[1][255] = 0;
fl_tab[2][255] = fl_tab[3][255] = 0;
#endif
};
#ifdef LARGE_TABLES
void pi_fun(u4byte y[4], const u4byte x[4])
{
y[0] = fl_tab[0][byte(x[0],0) ^ f_tab[byte(x[2],0)]]
| fl_tab[1][byte(x[2],0) ^ f_tab[byte(x[0],0)]]
| fl_tab[2][byte(x[0],1) ^ f_tab[byte(x[2],1)]]
| fl_tab[3][byte(x[2],1) ^ f_tab[byte(x[0],1)]];
y[1] = fl_tab[0][byte(x[0],2) ^ f_tab[byte(x[2],2)]]
| fl_tab[1][byte(x[2],2) ^ f_tab[byte(x[0],2)]]
| fl_tab[2][byte(x[0],3) ^ f_tab[byte(x[2],3)]]
| fl_tab[3][byte(x[2],3) ^ f_tab[byte(x[0],3)]];
y[2] = fl_tab[0][byte(x[1],0) ^ f_tab[byte(x[3],0)]]
| fl_tab[1][byte(x[3],0) ^ f_tab[byte(x[1],0)]]
| fl_tab[2][byte(x[1],1) ^ f_tab[byte(x[3],1)]]
| fl_tab[3][byte(x[3],1) ^ f_tab[byte(x[1],1)]];
y[3] = fl_tab[0][byte(x[1],2) ^ f_tab[byte(x[3],2)]]
| fl_tab[1][byte(x[3],2) ^ f_tab[byte(x[1],2)]]
| fl_tab[2][byte(x[1],3) ^ f_tab[byte(x[3],3)]]
| fl_tab[3][byte(x[3],3) ^ f_tab[byte(x[1],3)]];
};
#else
void pi_fun(u4byte y[4], const u4byte x[4])
{
y[0] = f_tab[byte(x[0],0) ^ f_tab[byte(x[2],0)]]
| (f_tab[byte(x[2],0) ^ f_tab[byte(x[0],0)]] << 8)
| (f_tab[byte(x[0],1) ^ f_tab[byte(x[2],1)]] << 16)
| (f_tab[byte(x[2],1) ^ f_tab[byte(x[0],1)]] << 24);
y[1] = f_tab[byte(x[0],2) ^ f_tab[byte(x[2],2)]]
| (f_tab[byte(x[2],2) ^ f_tab[byte(x[0],2)]] << 8)
| (f_tab[byte(x[0],3) ^ f_tab[byte(x[2],3)]] << 16)
| (f_tab[byte(x[2],3) ^ f_tab[byte(x[0],3)]] << 24);
y[2] = f_tab[byte(x[1],0) ^ f_tab[byte(x[3],0)]]
| (f_tab[byte(x[3],0) ^ f_tab[byte(x[1],0)]] << 8)
| (f_tab[byte(x[1],1) ^ f_tab[byte(x[3],1)]] << 16)
| (f_tab[byte(x[3],1) ^ f_tab[byte(x[1],1)]] << 24);
y[3] = f_tab[byte(x[1],2) ^ f_tab[byte(x[3],2)]]
| (f_tab[byte(x[3],2) ^ f_tab[byte(x[1],2)]] << 8)
| (f_tab[byte(x[1],3) ^ f_tab[byte(x[3],3)]] << 16)
| (f_tab[byte(x[3],3) ^ f_tab[byte(x[1],3)]] << 24);
};
#endif
void e3_fun(u4byte x[4])
{ u4byte u[4],v[4];
u[0] = x[0]; u[1] = x[1]; u[2] = x[2]; u[3] = x[3];
pi_fun(v, u); pi_fun(u, v); pi_fun(v, u); pi_fun(u, v);
v[0] = byte(u[0], 0) | (byte(u[0], 2) << 8) | (byte(u[1], 0) << 16) | (byte(u[1], 2) << 24);
v[1] = byte(u[2], 0) | (byte(u[2], 2) << 8) | (byte(u[3], 0) << 16) | (byte(u[3], 2) << 24);
v[2] = byte(u[0], 1) | (byte(u[0], 3) << 8) | (byte(u[1], 1) << 16) | (byte(u[1], 3) << 24);
v[3] = byte(u[2], 1) | (byte(u[2], 3) << 8) | (byte(u[3], 1) << 16) | (byte(u[3], 3) << 24);
u[0] = x[0] ^ v[0]; u[1] = x[1] ^ v[1]; u[2] = x[2] ^ v[2]; u[3] = x[3] ^ v[3];
pi_fun(v, u); pi_fun(u, v); pi_fun(v, u); pi_fun(u, v);
v[0] = byte(u[0], 0) | (byte(u[0], 2) << 8) | (byte(u[1], 0) << 16) | (byte(u[1], 2) << 24);
v[1] = byte(u[2], 0) | (byte(u[2], 2) << 8) | (byte(u[3], 0) << 16) | (byte(u[3], 2) << 24);
v[2] = byte(u[0], 1) | (byte(u[0], 3) << 8) | (byte(u[1], 1) << 16) | (byte(u[1], 3) << 24);
v[3] = byte(u[2], 1) | (byte(u[2], 3) << 8) | (byte(u[3], 1) << 16) | (byte(u[3], 3) << 24);
u[0] = x[0] ^ v[0]; u[1] = x[1] ^ v[1]; u[2] = x[2] ^ v[2]; u[3] = x[3] ^ v[3];
pi_fun(v, u); pi_fun(u, v); pi_fun(v, u); pi_fun(u, v);
v[0] = byte(u[0], 0) | (byte(u[0], 2) << 8) | (byte(u[1], 0) << 16) | (byte(u[1], 2) << 24);
v[1] = byte(u[2], 0) | (byte(u[2], 2) << 8) | (byte(u[3], 0) << 16) | (byte(u[3], 2) << 24);
v[2] = byte(u[0], 1) | (byte(u[0], 3) << 8) | (byte(u[1], 1) << 16) | (byte(u[1], 3) << 24);
v[3] = byte(u[2], 1) | (byte(u[2], 3) << 8) | (byte(u[3], 1) << 16) | (byte(u[3], 3) << 24);
x[0] = v[0]; x[1] = v[1];
};
/* initialise the key schedule from the user supplied key */
u4byte *set_key(const u4byte in_key[], const u4byte key_len)
{
if(!tab_init)
{
init_tab(); tab_init = 1;
}
k_len = (key_len + 63) / 64;
switch(k_len)
{
case 2:
l_key[ 0] = in_key[0]; l_key[ 1] = in_key[1];
l_key[ 2] = in_key[0]; l_key[ 3] = in_key[1];
l_key[ 4] = in_key[2]; l_key[ 5] = in_key[3];
l_key[ 6] = in_key[2]; l_key[ 7] = in_key[3];
l_key[ 8] = in_key[0]; l_key[ 9] = in_key[1];
l_key[10] = in_key[0]; l_key[11] = in_key[1];
break;
case 3:
l_key[ 0] = in_key[0]; l_key[ 1] = in_key[1];
l_key[ 2] = in_key[2]; l_key[ 3] = in_key[3];
l_key[ 4] = in_key[4]; l_key[ 5] = in_key[5];
l_key[ 6] = in_key[4]; l_key[ 7] = in_key[5];
l_key[ 8] = in_key[2]; l_key[ 9] = in_key[3];
l_key[10] = in_key[0]; l_key[11] = in_key[1];
break;
case 4:
l_key[ 0] = in_key[0]; l_key[ 1] = in_key[1];
l_key[ 2] = in_key[2]; l_key[ 3] = in_key[3];
l_key[ 4] = in_key[4]; l_key[ 5] = in_key[5];
l_key[ 6] = in_key[6]; l_key[ 7] = in_key[7];
l_key[ 8] = in_key[6]; l_key[ 9] = in_key[7];
l_key[10] = in_key[4]; l_key[11] = in_key[5];
l_key[12] = in_key[2]; l_key[13] = in_key[3];
l_key[14] = in_key[0]; l_key[15] = in_key[1];
}
return l_key;
};
#define r_fun(x,y,k) \
tt[0] = (y)[0]; tt[1] = (y)[1]; \
tt[2] = (k)[0]; tt[3] = (k)[1]; \
e3_fun(tt); \
(x)[0] ^= tt[0]; (x)[1] ^= tt[1]
/* encrypt a block of text */
void encrypt(const u4byte in_blk[4], u4byte out_blk[4])
{ u4byte blk[4], tt[4];
blk[0] = in_blk[0]; blk[1] = in_blk[1];
blk[2] = in_blk[2]; blk[3] = in_blk[3];
r_fun(blk, blk + 2, l_key);
r_fun(blk + 2, blk, l_key + 2);
r_fun(blk, blk + 2, l_key + 4);
r_fun(blk + 2, blk, l_key + 6);
r_fun(blk, blk + 2, l_key + 8);
r_fun(blk + 2, blk, l_key + 10);
if(k_len == 4)
{
r_fun(blk, blk + 2, l_key + 12);
r_fun(blk + 2, blk, l_key + 14);
}
out_blk[0] = blk[0]; out_blk[1] = blk[1];
out_blk[2] = blk[2]; out_blk[3] = blk[3];
};
/* decrypt a block of text */
void decrypt(const u4byte in_blk[4], u4byte out_blk[4])
{ u4byte blk[4], tt[4];
blk[2] = in_blk[0]; blk[3] = in_blk[1];
blk[0] = in_blk[2]; blk[1] = in_blk[3];
r_fun(blk, blk + 2, l_key);
r_fun(blk + 2, blk, l_key + 2);
r_fun(blk, blk + 2, l_key + 4);
r_fun(blk + 2, blk, l_key + 6);
r_fun(blk, blk + 2, l_key + 8);
r_fun(blk + 2, blk, l_key + 10);
if(k_len == 4)
{
r_fun(blk, blk + 2, l_key + 12);
r_fun(blk + 2, blk, l_key + 14);
}
out_blk[2] = blk[0]; out_blk[3] = blk[1];
out_blk[0] = blk[2]; out_blk[1] = blk[3];
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?