?? twofish.c
字號:
#elseint twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)#endif{#ifndef TWOFISH_SMALL unsigned char S[4*4], tmpx0, tmpx1;#endif int k, x, y; unsigned char tmp[4], tmp2[4], M[8*4]; ulong32 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] & 255; } /* 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] = (unsigned char)(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); }#ifndef TWOFISH_SMALL /* make the sboxes (large ram variant) */ if (k == 2) { for (x = 0; x < 256; x++) { tmpx0 = sbox(0, x); tmpx1 = sbox(1, x); skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0); skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1); skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2); skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3); } } else if (k == 3) { for (x = 0; x < 256; x++) { tmpx0 = sbox(0, x); tmpx1 = sbox(1, x); skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0); skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1); skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2); skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3); } } else { for (x = 0; x < 256; x++) { tmpx0 = sbox(0, x); tmpx1 = sbox(1, x); skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, sbox(1, tmpx1 ^ S[0]) ^ S[4]) ^ S[8]) ^ S[12])),0); skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, sbox(1, tmpx0 ^ S[1]) ^ S[5]) ^ S[9]) ^ S[13])),1); skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10]) ^ S[14])),2); skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, sbox(0, tmpx1 ^ S[3]) ^ S[7]) ^ S[11]) ^ S[15])),3); } }#else /* where to start in the sbox layers */ /* small ram variant */ switch (k) { case 4 : skey->twofish.start = 0; break; case 3 : skey->twofish.start = 1; break; default: skey->twofish.start = 2; break; }#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(ulong32) * 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{ ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; int r;#if !defined(TWOFISH_SMALL) && !defined(__GNUC__) ulong32 *S1, *S2, *S3, *S4;#endif _ARGCHK(pt != NULL); _ARGCHK(ct != NULL); _ARGCHK(key != NULL); #if !defined(TWOFISH_SMALL) && !defined(__GNUC__) S1 = key->twofish.S[0]; S2 = key->twofish.S[1]; S3 = key->twofish.S[2]; S4 = key->twofish.S[3];#endif 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]; k = key->twofish.K + 8; for (r = 8; r != 0; --r) { t2 = g1_func(b, key); t1 = g_func(a, key) + t2; c = ROR(c ^ (t1 + k[0]), 1); d = ROL(d, 1) ^ (t2 + t1 + k[1]); t2 = g1_func(d, key); t1 = g_func(c, key) + t2; a = ROR(a ^ (t1 + k[2]), 1); b = ROL(b, 1) ^ (t2 + t1 + k[3]); k += 4; } /* 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(ulong32) * 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{ ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; int r;#if !defined(TWOFISH_SMALL) && !defined(__GNUC__) ulong32 *S1, *S2, *S3, *S4;#endif _ARGCHK(pt != NULL); _ARGCHK(ct != NULL); _ARGCHK(key != NULL); #if !defined(TWOFISH_SMALL) && !defined(__GNUC__) S1 = key->twofish.S[0]; S2 = key->twofish.S[1]; S3 = key->twofish.S[2]; S4 = key->twofish.S[3];#endif /* 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]; k = key->twofish.K + 36; for (r = 8; r != 0; --r) { t2 = g1_func(d, key); t1 = g_func(c, key) + t2; a = ROL(a, 1) ^ (t1 + k[2]); b = ROR(b ^ (t2 + t1 + k[3]), 1); t2 = g1_func(b, key); t1 = g_func(a, key) + t2; c = ROL(c, 1) ^ (t1 + k[0]); d = ROR(d ^ (t2 + t1 + k[1]), 1); k -= 4; } /* 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(ulong32) * 10 + sizeof(int));}#endifint twofish_test(void){ #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { int keylen; unsigned char key[32], pt[16], ct[16]; } tests[] = { { 16, { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }, { 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 }, { 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 } }, { 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 }, { 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 }, { 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 } }, { 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 }, { 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 }, { 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 err, i, y; for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { return err; } twofish_ecb_encrypt(tests[i].pt, tmp[0], &key); twofish_ecb_decrypt(tmp[0], tmp[1], &key); if (memcmp(tmp[0], tests[i].ct, 16) != 0 || memcmp(tmp[1], tests[i].pt, 16) != 0) { return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 16; y++) tmp[0][y] = 0; for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key); for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key); for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK;#endif }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 + -