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

📄 twofish.cpp

📁 TWOFISH加密算法
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#define CALC_K_2(a, b, c, d, j) \     mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \   ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \   ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \   ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]#define CALC_K(a, j, k, l, m, n) \   x = CALC_K_2 (k, l, k, l, 0); \   y = CALC_K_2 (m, n, m, n, 4); \   y = (y << 8) + (y >> 24); \   x += y; y += x; ctx->a[j] = x; \   ctx->a[(j) + 1] = (y << 9) + (y >> 23)#define CALC_K256_2(a, b, j) \   CALC_K_2 (q0[q1[b ^ key[(j) + 24]] ^ key[(j) + 16]], \	     q1[q1[a ^ key[(j) + 25]] ^ key[(j) + 17]], \	     q0[q0[a ^ key[(j) + 26]] ^ key[(j) + 18]], \	     q1[q0[b ^ key[(j) + 27]] ^ key[(j) + 19]], j)#define CALC_K256(a, j, k, l, m, n) \   x = CALC_K256_2 (k, l, 0); \   y = CALC_K256_2 (m, n, 4); \   y = (y << 8) + (y >> 24); \   x += y; y += x; ctx->a[j] = x; \   ctx->a[(j) + 1] = (y << 9) + (y >> 23)static voidburn_stack (int bytes){    char buf[64];        wipememory(buf,sizeof buf);    bytes -= sizeof buf;    if (bytes > 0)        burn_stack (bytes);}/* Perform the key setup.  Note that this works only with 128- and 256-bit * keys, despite the API that looks like it might support other sizes. */static intdo_twofish_setkey (TWOFISH_context *ctx, const byte *key, unsigned int keylen){    int i, j, k;    /* Temporaries for CALC_K. */    u32 x, y;    /* The S vector used to key the S-boxes, split up into individual bytes.     * 128-bit keys use only sa through sh; 256-bit use all of them. */    byte sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;    byte si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;    /* Temporary for CALC_S. */    byte tmp;    /* Flags for self-test. */    static int initialized = 0;    static const char *selftest_failed=0;    /* Check key length. */    if( ( ( keylen - 16 ) | 16 ) != 16 )	return G10ERR_WRONG_KEYLEN;    /* Do self-test if necessary. */    if (!initialized) {       initialized = 1;       selftest_failed = selftest ();       if( selftest_failed )	 fprintf(stderr, "%s\n", selftest_failed );    }    if( selftest_failed )       return G10ERR_SELFTEST_FAILED;    /* Compute the first two words of the S vector.  The magic numbers are     * the entries of the RS matrix, preprocessed through poly_to_exp.	The     * numbers in the comments are the original (polynomial form) matrix     * entries. */    CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */    CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */    CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */    CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */    CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */    CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */    CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */    CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */    CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */    CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */    CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */    CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */    CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */    CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */    CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */    CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */    if (keylen == 32) { /* 256-bit key */	/* Calculate the remaining two words of the S vector */	CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */	CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */	CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */	CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */	CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */	CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */	CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */	CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */	CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */	CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */	CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */	CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */	CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */	CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */	CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */	CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */	/* Compute the S-boxes. */	for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 ) {	    CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );	}	/* Calculate whitening and round subkeys.  The constants are	 * indices of subkeys, preprocessed through q0 and q1. */	CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);	CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);	CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);	CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);	CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);	CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);	CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);	CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);	CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);	CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);	CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);	CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);	CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);	CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);	CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);	CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);	CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);	CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);	CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);	CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);    }    else {	/* Compute the S-boxes. */	for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 ) {	    CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );	}	/* Calculate whitening and round subkeys.  The constants are	 * indices of subkeys, preprocessed through q0 and q1. */	CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);	CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);	CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);	CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);	CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);	CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);	CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);	CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);	CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);	CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);	CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);	CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);	CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);	CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);	CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);	CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);	CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);	CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);	CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);	CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);    }    return 0;}int twofish_setkey (void *ctx, const byte *key, unsigned int keylen){    int rc = do_twofish_setkey ((TWOFISH_context *)ctx, key, keylen);    burn_stack (23+6*sizeof(void*));    return rc;}        /* Macros to compute the g() function in the encryption and decryption * rounds.  G1 is the straight g() function; G2 includes the 8-bit * rotation for the high 32-bit word. */#define G1(a) \     (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \   ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])#define G2(b) \     (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \   ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])/* Encryption and decryption Feistel rounds.  Each one calls the two g() * macros, does the PHT, and performs the XOR and the appropriate bit * rotations.  The parameters are the round number (used to select subkeys), * and the four 32-bit chunks of the text. */#define ENCROUND(n, a, b, c, d) \   x = G1 (a); y = G2 (b); \   x += y; y += x + ctx->k[2 * (n) + 1]; \   (c) ^= x + ctx->k[2 * (n)]; \   (c) = ((c) >> 1) + ((c) << 31); \   (d) = (((d) << 1)+((d) >> 31)) ^ y#define DECROUND(n, a, b, c, d) \   x = G1 (a); y = G2 (b); \   x += y; y += x; \   (d) ^= y + ctx->k[2 * (n) + 1]; \   (d) = ((d) >> 1) + ((d) << 31); \   (c) = (((c) << 1)+((c) >> 31)); \   (c) ^= (x + ctx->k[2 * (n)])/* Encryption and decryption cycles; each one is simply two Feistel rounds * with the 32-bit chunks re-ordered to simulate the "swap" */#define ENCCYCLE(n) \   ENCROUND (2 * (n), a, b, c, d); \   ENCROUND (2 * (n) + 1, c, d, a, b)#define DECCYCLE(n) \   DECROUND (2 * (n) + 1, c, d, a, b); \   DECROUND (2 * (n), a, b, c, d)/* Macros to convert the input and output bytes into 32-bit words, * and simultaneously perform the whitening step.  INPACK packs word * number n into the variable named by x, using whitening subkey number m. * OUTUNPACK unpacks word number n from the variable named by x, using * whitening subkey number m. */#define INPACK(n, x, m) \   x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \     ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]#define OUTUNPACK(n, x, m) \   x ^= ctx->w[m]; \   out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \   out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24/* Encrypt one block.  in and out may be the same. */static voiddo_twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in){   /* The four 32-bit chunks of the text. */   u32 a, b, c, d;   /* Temporaries used by the round function. */   u32 x, y;   /* Input whitening and packing. */   INPACK (0, a, 0);

⌨️ 快捷键说明

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