AES, Serpent or Twofish in C example?

后端 未结 3 1971
野趣味
野趣味 2020-12-31 17:20

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

3条回答
  •  再見小時候
    2020-12-31 17:54

    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! :)

提交回复
热议问题