📄 twofish.c
字号:
// 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 + -