⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 twofish.c

📁 文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2, MD4, MD5, RIPEMD-128, RIPEMD-160, SHA-1, SHA-224, SHA-256,
💻 C
📖 第 1 页 / 共 2 页
字号:

// Copyright in this code is held by Dr B.R. Gladman but free direct or
// derivative use is permitted subject to acknowledgement of its origin
// and subject to any constraints placed on the use of the algorithm by
// its designers (if such constraints may exist, this will be indicated
// below).
//
// Dr. B. R. Gladman                               . 25th January 2000.
//
// This is an implementation of Twofish, an encryption algorithm designed
// by Bruce Schneier and colleagues and submitted as a candidate for the
// Advanced Encryption Standard programme of the US National Institute of
// Standards and Technology.
//
// The designers of Twofish have not placed any constraints on the use of
// this algorithm.

#include "aes_defs.h"
#include "twofish.h"

#ifdef  __cplusplus
    namespace
    {
#endif

#define M_TABLE
#define MK_TABLE
#define Q_TABLE
#define ONE_STEP

#if defined(Q_TABLE) && !defined(MK_TABLE)
#error Q_TABLE requires MK_TABLE
#endif

// Extract byte from a 32 bit quantity (little endian notation)

#define byte(x,n)   ((u1byte)((x) >> (8 * (n))))

// finite field arithmetic for GF(2**8) with the modular
// polynomial x^8 + x^6 + x^5 + x^3 + 1 (0x169)

#define G_M 0x0169

STATIC u1byte  tab_5b[4] = { 0, G_M >> 2, G_M >> 1, (G_M >> 1) ^ (G_M >> 2) };
STATIC u1byte  tab_ef[4] = { 0, (G_M >> 1) ^ (G_M >> 2), G_M >> 1, G_M >> 2 };

#define ffm_01(x)    (x)
#define ffm_5b(x)   ((x) ^ ((x) >> 2) ^ tab_5b[(x) & 3])
#define ffm_ef(x)   ((x) ^ ((x) >> 1) ^ ((x) >> 2) ^ tab_ef[(x) & 3])

STATIC u1byte qt[2][256] = {
{   0xa9,0x67,0xb3,0xe8,0x04,0xfd,0xa3,0x76,0x9a,0x92,0x80,0x78,0xe4,0xdd,0xd1,0x38,
    0x0d,0xc6,0x35,0x98,0x18,0xf7,0xec,0x6c,0x43,0x75,0x37,0x26,0xfa,0x13,0x94,0x48,
    0xf2,0xd0,0x8b,0x30,0x84,0x54,0xdf,0x23,0x19,0x5b,0x3d,0x59,0xf3,0xae,0xa2,0x82,
    0x63,0x01,0x83,0x2e,0xd9,0x51,0x9b,0x7c,0xa6,0xeb,0xa5,0xbe,0x16,0x0c,0xe3,0x61,
    0xc0,0x8c,0x3a,0xf5,0x73,0x2c,0x25,0x0b,0xbb,0x4e,0x89,0x6b,0x53,0x6a,0xb4,0xf1,
    0xe1,0xe6,0xbd,0x45,0xe2,0xf4,0xb6,0x66,0xcc,0x95,0x03,0x56,0xd4,0x1c,0x1e,0xd7,
    0xfb,0xc3,0x8e,0xb5,0xe9,0xcf,0xbf,0xba,0xea,0x77,0x39,0xaf,0x33,0xc9,0x62,0x71,
    0x81,0x79,0x09,0xad,0x24,0xcd,0xf9,0xd8,0xe5,0xc5,0xb9,0x4d,0x44,0x08,0x86,0xe7,
    0xa1,0x1d,0xaa,0xed,0x06,0x70,0xb2,0xd2,0x41,0x7b,0xa0,0x11,0x31,0xc2,0x27,0x90,
    0x20,0xf6,0x60,0xff,0x96,0x5c,0xb1,0xab,0x9e,0x9c,0x52,0x1b,0x5f,0x93,0x0a,0xef,
    0x91,0x85,0x49,0xee,0x2d,0x4f,0x8f,0x3b,0x47,0x87,0x6d,0x46,0xd6,0x3e,0x69,0x64,
    0x2a,0xce,0xcb,0x2f,0xfc,0x97,0x05,0x7a,0xac,0x7f,0xd5,0x1a,0x4b,0x0e,0xa7,0x5a,
    0x28,0x14,0x3f,0x29,0x88,0x3c,0x4c,0x02,0xb8,0xda,0xb0,0x17,0x55,0x1f,0x8a,0x7d,
    0x57,0xc7,0x8d,0x74,0xb7,0xc4,0x9f,0x72,0x7e,0x15,0x22,0x12,0x58,0x07,0x99,0x34,
    0x6e,0x50,0xde,0x68,0x65,0xbc,0xdb,0xf8,0xc8,0xa8,0x2b,0x40,0xdc,0xfe,0x32,0xa4,
    0xca,0x10,0x21,0xf0,0xd3,0x5d,0x0f,0x00,0x6f,0x9d,0x36,0x42,0x4a,0x5e,0xc1,0xe0 },

{   0x75,0xf3,0xc6,0xf4,0xdb,0x7b,0xfb,0xc8,0x4a,0xd3,0xe6,0x6b,0x45,0x7d,0xe8,0x4b,
    0xd6,0x32,0xd8,0xfd,0x37,0x71,0xf1,0xe1,0x30,0x0f,0xf8,0x1b,0x87,0xfa,0x06,0x3f,
    0x5e,0xba,0xae,0x5b,0x8a,0x00,0xbc,0x9d,0x6d,0xc1,0xb1,0x0e,0x80,0x5d,0xd2,0xd5,
    0xa0,0x84,0x07,0x14,0xb5,0x90,0x2c,0xa3,0xb2,0x73,0x4c,0x54,0x92,0x74,0x36,0x51,
    0x38,0xb0,0xbd,0x5a,0xfc,0x60,0x62,0x96,0x6c,0x42,0xf7,0x10,0x7c,0x28,0x27,0x8c,
    0x13,0x95,0x9c,0xc7,0x24,0x46,0x3b,0x70,0xca,0xe3,0x85,0xcb,0x11,0xd0,0x93,0xb8,
    0xa6,0x83,0x20,0xff,0x9f,0x77,0xc3,0xcc,0x03,0x6f,0x08,0xbf,0x40,0xe7,0x2b,0xe2,
    0x79,0x0c,0xaa,0x82,0x41,0x3a,0xea,0xb9,0xe4,0x9a,0xa4,0x97,0x7e,0xda,0x7a,0x17,
    0x66,0x94,0xa1,0x1d,0x3d,0xf0,0xde,0xb3,0x0b,0x72,0xa7,0x1c,0xef,0xd1,0x53,0x3e,
    0x8f,0x33,0x26,0x5f,0xec,0x76,0x2a,0x49,0x81,0x88,0xee,0x21,0xc4,0x1a,0xeb,0xd9,
    0xc5,0x39,0x99,0xcd,0xad,0x31,0x8b,0x01,0x18,0x23,0xdd,0x1f,0x4e,0x2d,0xf9,0x48,
    0x4f,0xf2,0x65,0x8e,0x78,0x5c,0x58,0x19,0x8d,0xe5,0x98,0x57,0x67,0x7f,0x05,0x64,
    0xaf,0x63,0xb6,0xfe,0xf5,0xb7,0x3c,0xa5,0xce,0xe9,0x68,0x44,0xe0,0x4d,0x43,0x69,
    0x29,0x2e,0xac,0x15,0x59,0xa8,0x0a,0x9e,0x6e,0x47,0xdf,0x34,0x35,0x6a,0xcf,0xdc,
    0x22,0xc9,0xc0,0x9b,0x89,0xd4,0xed,0xab,0x12,0xa2,0x0d,0x52,0xbb,0x02,0x2f,0xa9,
    0xd7,0x61,0x1e,0xb4,0x50,0x04,0xf6,0xc2,0x16,0x25,0x86,0x56,0x55,0x09,0xbe,0x91 }
};

#ifdef  Q_TABLE

STATIC u4byte qt_gen = 0;
static u4byte q2_tab[256];
static u4byte q3_tab[256];
static u4byte q4_tab[256];

#define qs(m,n) ((u4byte)qt[m][i] << 8 * n)

void gen_qtab(void)
{   u4byte i;

    for(i = 0; i < 256; ++i)
    {
        q2_tab[i] = qs(0, 0) | qs(1, 1) | qs(0, 2) | qs(1, 3);
        q3_tab[i] = qs(1, 0) | qs(1, 1) | qs(0, 2) | qs(0, 3);
        q4_tab[i] = qs(1, 0) | qs(0, 1) | qs(0, 2) | qs(1, 3);
    }
}

#endif

// Q_mn is the q_box applied for byte n on round m, where the rounds
// are numbered from k_len down to 0 (4..0), (3..0) or (2..0)

#define Q_00    qt[1]
#define Q_01    qt[0]
#define Q_02    qt[1]
#define Q_03    qt[0]

#define Q_10    qt[0]
#define Q_11    qt[0]
#define Q_12    qt[1]
#define Q_13    qt[1]

#define Q_20    qt[0]
#define Q_21    qt[1]
#define Q_22    qt[0]
#define Q_23    qt[1]

#define Q_30    qt[1]
#define Q_31    qt[1]
#define Q_32    qt[0]
#define Q_33    qt[0]

#define Q_40    qt[1]
#define Q_41    qt[0]
#define Q_42    qt[0]
#define Q_43    qt[1]

#define bval(x,n)   (((u1byte*)(&x))[n])
#define  q8(x,m,n)  Q_##m##n[x] ^ bval(key[m - 1],n)

#ifdef  M_TABLE

STATIC u4byte mt_gen = 0;
STATIC u4byte m_tab[4][256];

STATIC void gen_mtab(void)
{   u4byte  i, f01, f5b, fef;

    for(i = 0; i < 256; ++i)
    {
        f01 = qt[1][i]; f5b = ffm_5b(f01); fef = ffm_ef(f01);
        m_tab[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24);
        m_tab[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24);

        f01 = qt[0][i]; f5b = ffm_5b(f01); fef = ffm_ef(f01);
        m_tab[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24);
        m_tab[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24);
    }
}

#define mds(n,x)    m_tab[n][x]

#else

#define fm_00   ffm_01
#define fm_10   ffm_5b
#define fm_20   ffm_ef
#define fm_30   ffm_ef

#define fm_01   ffm_ef
#define fm_11   ffm_ef
#define fm_21   ffm_5b
#define fm_31   ffm_01

#define fm_02   ffm_5b
#define fm_12   ffm_ef
#define fm_22   ffm_01
#define fm_32   ffm_ef

#define fm_03   ffm_5b
#define fm_13   ffm_01
#define fm_23   ffm_ef
#define fm_33   ffm_5b

#define mds(n,x)    ((u4byte)fm_0##n(Q_0##n[x])) ^ ((u4byte)fm_1##n(Q_0##n[x]) << 8) ^      \
                    ((u4byte)fm_2##n(Q_0##n[x]) << 16) ^ ((u4byte)fm_3##n(Q_0##n[x]) << 24)
#endif

// My thanks to Bill and John Worley of HP Labs for the speed up of this function
// for the key schedule by using large tables for the first qt substitution

STATIC u4byte h_fun(const u4byte x, const u4byte key[], u4byte k_len)
{   u4byte  b0, b1, b2, b3;

#ifdef  Q_TABLE

    switch(k_len)
    {       u4byte  xx;
    case 4: xx = q4_tab[x] ^ key[3];
            b0 = byte(xx, 0); b1 = byte(xx, 1); b2 = byte(xx, 2); b3 = byte(xx, 3);
            b0 = q8(q8(q8(b0, 3, 0), 2, 0), 1, 0); b1 = q8(q8(q8(b1, 3, 1), 2, 1), 1, 1);
            b2 = q8(q8(q8(b2, 3, 2), 2, 2), 1, 2); b3 = q8(q8(q8(b3, 3, 3), 2, 3), 1, 3);
            break;

    case 3: xx = q3_tab[x] ^ key[2];
            b0 = byte(xx, 0); b1 = byte(xx, 1); b2 = byte(xx, 2); b3 = byte(xx, 3);
            b0 = q8(q8(b0, 2, 0), 1, 0); b1 = q8(q8(b1, 2, 1), 1, 1);
            b2 = q8(q8(b2, 2, 2), 1, 2); b3 = q8(q8(b3, 2, 3), 1, 3);
            break;

    case 2: xx = q2_tab[x] ^ key[1];
            b0 = byte(xx, 0); b1 = byte(xx, 1); b2 = byte(xx, 2); b3 = byte(xx, 3);
            b0 = q8(b0, 1, 0); b1 = q8(b1, 1, 1); b2 = q8(b2, 1, 2); b3 = q8(b3, 1, 3);
    }
#else

    b0 = byte(x, 0); b1 = byte(x, 1); b2 = byte(x, 2); b3 = byte(x, 3);
    switch(k_len)
    {
    case 4: b0 = q8(b0, 4, 0); b1 = q8(b1, 4, 1); b2 = q8(b2, 4, 2); b3 = q8(b3, 4, 3);
    case 3: b0 = q8(b0, 3, 0); b1 = q8(b1, 3, 1); b2 = q8(b2, 3, 2); b3 = q8(b3, 3, 3);
    case 2: b0 = q8(q8(b0, 2, 0), 1, 0); b1 = q8(q8(b1, 2, 1), 1, 1);
            b2 = q8(q8(b2, 2, 2), 1, 2); b3 = q8(q8(b3, 2, 3), 1, 3);
    }

#endif

#ifdef  M_TABLE

    return  mds(0, b0) ^ mds(1, b1) ^ mds(2, b2) ^ mds(3, b3);

#else

    {   u4byte  m5b_b0, m5b_b1, m5b_b2, m5b_b3;
        u4byte  mef_b0, mef_b1, mef_b2, mef_b3;

        b0 = qt[1][b0]; b1 = qt[0][b1]; b2 = qt[1][b2]; b3 = qt[0][b3];
        m5b_b0 = ffm_5b(b0); m5b_b1 = ffm_5b(b1); m5b_b2 = ffm_5b(b2); m5b_b3 = ffm_5b(b3);
        mef_b0 = ffm_ef(b0); mef_b1 = ffm_ef(b1); mef_b2 = ffm_ef(b2); mef_b3 = ffm_ef(b3);
        b0 ^= mef_b1 ^ m5b_b2 ^ m5b_b3; b3 ^= m5b_b0 ^ mef_b1 ^ mef_b2;
        b2 ^= mef_b0 ^ m5b_b1 ^ mef_b3; b1 ^= mef_b0 ^ mef_b2 ^ m5b_b3;
    }

    return b0 | (b3 << 8) | (b2 << 16) | (b1 << 24);

#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -