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 + -
显示快捷键?