📄 twofish.c
字号:
#else#ifdef CLEAN_STACKstatic unsigned long _g_func(unsigned long x, symmetric_key *key)#elseunsigned long g_func(unsigned long x, symmetric_key *key)#endif{ unsigned char g, i, y, z; unsigned long res; res = 0; for (y = 0; y < 4; y++) { z = key->twofish.start; /* do unkeyed substitution */ g = sbox(qord[y][z++], (x >> (8*y)) & 255); /* first subkey */ i = 0; /* do key mixing+sbox until z==5 */ while (z != 5) { g = g ^ key->twofish.S[4*i++ + y]; g = sbox(qord[y][z++], g); } /* multiply g by a column of the MDS */ res ^= mds_column_mult(g, y); } return res;}#ifdef CLEAN_STACKstatic unsigned long g_func(unsigned long x, symmetric_key *key){ unsigned long y; y = _g_func(x, key); burn_stack(sizeof(unsigned char) * 4 + sizeof(unsigned long)); return y;}#endif#endif#ifdef CLEAN_STACKstatic int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)#elseint twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)#endif{#ifndef TWOFISH_SMALL int g, z, i; unsigned char S[4*4];#endif int k, x, y, start; unsigned char tmp[4], tmp2[4], M[8*4]; unsigned long A, B; _ARGCHK(key != NULL); _ARGCHK(skey != NULL); /* invalid arguments? */ if (num_rounds != 16 && num_rounds != 0) { return CRYPT_INVALID_ROUNDS; } if (keylen != 16 && keylen != 24 && keylen != 32) { return CRYPT_INVALID_KEYSIZE; } /* k = keysize/64 [but since our keysize is in bytes...] */ k = keylen / 8; /* copy the key into M */ for (x = 0; x < keylen; x++) M[x] = key[x]; /* create the S[..] words */#ifndef TWOFISH_SMALL for (x = 0; x < k; x++) rs_mult(M+(x*8), S+(x*4));#else for (x = 0; x < k; x++) rs_mult(M+(x*8), skey->twofish.S+(x*4));#endif /* make subkeys */ for (x = 0; x < 20; x++) { /* A = h(p * 2x, Me) */ for (y = 0; y < 4; y++) tmp[y] = x+x; h_func(tmp, tmp2, M, k, 0); LOAD32L(A, tmp2); /* B = ROL(h(p * (2x + 1), Mo), 8) */ for (y = 0; y < 4; y++) tmp[y] = x+x+1; h_func(tmp, tmp2, M, k, 1); LOAD32L(B, tmp2); B = ROL(B, 8); /* K[2i] = A + B */ skey->twofish.K[x+x] = (A + B) & 0xFFFFFFFFUL; /* K[2i+1] = (A + 2B) <<< 9 */ skey->twofish.K[x+x+1] = ROL(B + B + A, 9); } /* where to start in the sbox layers */ switch (k) { case 4 : start = 0; break; case 3 : start = 1; break; default: start = 2; break; }#ifndef TWOFISH_SMALL /* make the sboxes (large ram variant) */ for (y = 0; y < 4; y++) { for (x = 0; x < 256; x++) { z = start; /* do unkeyed substitution */ g = sbox(qord[y][z++], x); /* first subkey */ i = 0; /* do key mixing+sbox until z==5 */ while (z != 5) { g = g ^ S[4*i++ + y]; g = sbox(qord[y][z++], g); } /* multiply g by a column of the MDS */ skey->twofish.S[y][x] = mds_column_mult(g, y); } }#else /* small ram variant */ skey->twofish.start = start;#endif return CRYPT_OK;}#ifdef CLEAN_STACKint twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey){ int x; x = _twofish_setup(key, keylen, num_rounds, skey); burn_stack(sizeof(int) * 7 + sizeof(unsigned char) * 56 + sizeof(unsigned long) * 2); return x;}#endif#ifdef CLEAN_STACKstatic void _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)#elsevoid twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)#endif{ unsigned long a,b,c,d,ta,tb,tc,td,t1,t2; int r; _ARGCHK(pt != NULL); _ARGCHK(ct != NULL); _ARGCHK(key != NULL); LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]); LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]); a ^= key->twofish.K[0]; b ^= key->twofish.K[1]; c ^= key->twofish.K[2]; d ^= key->twofish.K[3]; for (r = 0; r < 16; r += 2) { t1 = g_func(a, key); t2 = g_func(ROL(b, 8), key); t2 += (t1 += t2); t1 += key->twofish.K[r+r+8]; t2 += key->twofish.K[r+r+9]; c ^= t1; c = ROR(c, 1); d = ROL(d, 1) ^ t2; t1 = g_func(c, key); t2 = g_func(ROL(d, 8), key); t2 += (t1 += t2); t1 += key->twofish.K[r+r+10]; t2 += key->twofish.K[r+r+11]; a ^= t1; a = ROR(a, 1); b = ROL(b, 1) ^ t2; } /* output with "undo last swap" */ ta = c ^ key->twofish.K[4]; tb = d ^ key->twofish.K[5]; tc = a ^ key->twofish.K[6]; td = b ^ key->twofish.K[7]; /* store output */ STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]);}#ifdef CLEAN_STACKvoid twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key){ _twofish_ecb_encrypt(pt, ct, key); burn_stack(sizeof(unsigned long) * 10 + sizeof(int));}#endif#ifdef CLEAN_STACKstatic void _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)#elsevoid twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)#endif{ unsigned long a,b,c,d,ta,tb,tc,td,t1,t2; int r; _ARGCHK(pt != NULL); _ARGCHK(ct != NULL); _ARGCHK(key != NULL); /* load input */ LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]); LOAD32L(tc,&ct[8]); LOAD32L(td,&ct[12]); /* undo undo final swap */ a = tc ^ key->twofish.K[6]; b = td ^ key->twofish.K[7]; c = ta ^ key->twofish.K[4]; d = tb ^ key->twofish.K[5]; for (r = 14; r >= 0; r -= 2) { t1 = g_func(c, key); t2 = g_func(ROL(d, 8), key); t2 += (t1 += t2); t1 += key->twofish.K[r+r+10]; t2 += key->twofish.K[r+r+11]; a = ROL(a, 1) ^ t1; b = b ^ t2; b = ROR(b, 1); t1 = g_func(a, key); t2 = g_func(ROL(b, 8), key); t2 += (t1 += t2); t1 += key->twofish.K[r+r+8]; t2 += key->twofish.K[r+r+9]; c = ROL(c, 1) ^ t1; d = d ^ t2; d = ROR(d, 1); } /* pre-white */ a ^= key->twofish.K[0]; b ^= key->twofish.K[1]; c ^= key->twofish.K[2]; d ^= key->twofish.K[3]; /* store */ STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);}#ifdef CLEAN_STACKvoid twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key){ _twofish_ecb_decrypt(ct, pt, key); burn_stack(sizeof(unsigned long) * 10 + sizeof(int));}#endifint twofish_test(void){ static const unsigned char key128[16] = { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }; static const unsigned char pt128[16] = { 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 }; static const unsigned char ct128[16] = { 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 }; static const unsigned char key192[24] = { 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88, 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 }; static const unsigned char pt192[16] = { 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 }; static const unsigned char ct192[16] = { 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 }; static const unsigned char key256[32] = { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F }; static const unsigned char pt256[16] = { 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 }; static const unsigned char ct256[16] = { 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA }; symmetric_key key; unsigned char tmp[2][16]; int errno; if ((errno = twofish_setup(key128, 16, 0, &key)) != CRYPT_OK) { return errno; } twofish_ecb_encrypt(pt128, tmp[0], &key); twofish_ecb_decrypt(tmp[0], tmp[1], &key); if (memcmp(tmp[0], ct128, 16) || memcmp(tmp[1], pt128, 16)) { return CRYPT_FAIL_TESTVECTOR; } if ((errno = twofish_setup(key192, 24, 0, &key)) != CRYPT_OK) { return errno; } twofish_ecb_encrypt(pt192, tmp[0], &key); twofish_ecb_decrypt(tmp[0], tmp[1], &key); if (memcmp(tmp[0], ct192, 16) || memcmp(tmp[1], pt192, 16)) { return CRYPT_FAIL_TESTVECTOR; } if ((errno = twofish_setup(key256, 32, 0, &key)) != CRYPT_OK) { return errno; } twofish_ecb_encrypt(pt256, tmp[0], &key); twofish_ecb_decrypt(tmp[0], tmp[1], &key); if (memcmp(tmp[0], ct256, 16) || memcmp(tmp[1], pt256, 16)) { return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK;}int twofish_keysize(int *desired_keysize){ _ARGCHK(desired_keysize); if (*desired_keysize < 16) return CRYPT_INVALID_KEYSIZE; if (*desired_keysize < 24) { *desired_keysize = 16; return CRYPT_OK; } else if (*desired_keysize < 32) { *desired_keysize = 24; return CRYPT_OK; } else { *desired_keysize = 32; return CRYPT_OK; }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -