I found a lot of implementations of AES, Twofish and Serpent in C. But I don\'t really understand the examples. I only understand that some where provided with examples to i
Trying to answer the -still unanswered- question of killercode, here is my attempt of achieving the same thing:
Download this TwoFish code (thanks go to Schneier et al.): https://www.schneier.com/code/twofish-reference-c.zip
Use this code (at your own risk of course):
int mode = MODE_CBC;
int keySize = 256;
int result = 0;
keyInstance ki; /* key information, including tables */
cipherInstance ci; /* keeps mode (ECB, CBC) and IV */
BYTE plainText[MAX_BLK_CNT*(BLOCK_SIZE / 8)]; // 64 in size!
BYTE cipherText[MAX_BLK_CNT*(BLOCK_SIZE / 8)];
BYTE decryptOut[MAX_BLK_CNT*(BLOCK_SIZE / 8)];
BYTE iv[BLOCK_SIZE / 8];
int i;
/* select number of bytes to encrypt (multiple of block) */
/* e.g., byteCnt = 16, 32, 48, 64 */
//byteCnt = (BLOCK_SIZE / 8) * (1 + (rand() % MAX_BLK_CNT));
/* generate test data */;
int plainTextLength = 65;
for (i = 0; i < min(plainTextLength, MAX_BLK_CNT*(BLOCK_SIZE / 8)); i++)
plainText[i] = (BYTE)rand();
if (plainTextLength > MAX_BLK_CNT * BLOCK_SIZE / 8) {
::MessageBox(NULL, _T("You need to increase your MAX_BLK_CNT for the plain-text to fit in one call."), _T("Error"), MB_OK);
return;
}
int byteCnt = ceil((double)plainTextLength / (BLOCK_SIZE / 8.0)) * (BLOCK_SIZE / 8);
/* ----------------------- */
/* 'dummy' setup for a 128-bit key */
if (makeKey(&ki, DIR_ENCRYPT, keySize, NULL) != TRUE)
result = 1;
/* ----------------------- */
/* 'dummy' setup for cipher */
if (cipherInit(&ci, mode, NULL) != TRUE)
result = 1;
/* select key bits */
for (i = 0; i < keySize / 32; i++)
ki.key32[i] = 0x10003 * rand();
/* run the key schedule */
reKey(&ki);
/* set up random iv (if needed)*/
if (mode != MODE_ECB)
{
for (i = 0; i < sizeof(iv); i++)
iv[i] = (BYTE)rand();
/* copy the IV to ci */
memcpy(ci.iv32, iv, sizeof(ci.iv32));
}
/* encrypt the bytes */
if (blockEncrypt(&ci, &ki, plainText, byteCnt * 8, cipherText) != byteCnt * 8)
result = 1;
/* ----------------------- */
/* decrypt the bytes */
if (mode != MODE_ECB) /* first re-init the IV (if needed) */
memcpy(ci.iv32, iv, sizeof(ci.iv32));
if (blockDecrypt(&ci, &ki, cipherText, byteCnt * 8, decryptOut) != byteCnt * 8)
result = 1;
/* make sure the decrypt output matches original plaintext */
if (memcmp(plainText, decryptOut, byteCnt))
result = 1;
if (result == 0) ::MessageBox(NULL, _T("Success"), _T("SUCCESS"), MB_OK);
That was my attempt and it seems working quite good.
It is using CBC mode.
I am open to suggestions, if anyone has any.
Of course you might like to make MAX_BLK_CNT a variable and increase it accordingly, to be able to encrypt a variety of data lengths. Although I am not 100% sure if that is its normal usage.
Cheer! :)