📄 rijndael-test-fst.c
字号:
/** * rijndael-test-fst.c * * @version 3.0 (December 2000) * * Optimised ANSI C code for the Rijndael cipher (now AES) * * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> * @author Paulo Barreto <paulo.barreto@terra.com.br> * * This code is hereby placed in the public domain. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#ifndef INTERMEDIATE_VALUE_KAT#error "Must #define INTERMEDIATE_VALUE_KAT to generate the Intermediate Value Known Answer Test."#endif /* INTERMEDIATE_VALUE_KAT */#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include "rijndael-api-fst.h"#define SUBMITTER "Joan Daemen"static void blockPrint(FILE *fp, const BYTE *block, const char *tag) { int i; fprintf (fp, "%s=", tag); for (i = 0; i < 16; i++) { fprintf (fp, "%02X", block[i]); } fprintf (fp, "\n"); fflush (fp);} /* blockPrint */static void rijndaelVKKAT(FILE *fp, int keyLength) { int i, j, r; BYTE block[4*4]; BYTE keyMaterial[320]; BYTE byteVal = (BYTE)'8'; keyInstance keyInst; cipherInstance cipherInst;#ifdef TRACE_KAT_MCT printf("Executing Variable-Key KAT (key %d): ", keyLength); fflush(stdout);#endif /* ?TRACE_KAT_MCT */ fprintf(fp, "\n" "==========\n" "\n" "KEYSIZE=%d\n" "\n", keyLength); fflush(fp); memset(block, 0, 16); blockPrint(fp, block, "PT"); memset(keyMaterial, 0, sizeof (keyMaterial)); memset(keyMaterial, '0', keyLength/4); for (i = 0; i < keyLength; i++) { keyMaterial[i/4] = byteVal; /* set only the i-th bit of the i-th test key */ r = makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial); if (TRUE != r) { fprintf(stderr,"makeKey error %d\n",r); exit(-1); } fprintf(fp, "\nI=%d\n", i+1); fprintf(fp, "KEY=%s\n", keyMaterial); memset(block, 0, 16); r = cipherInit(&cipherInst, MODE_ECB, NULL); if (TRUE != r) { fprintf(stderr,"cipherInit error %d\n",r); exit(-1); } r = blockEncrypt(&cipherInst, &keyInst, block, 128, block); if (128 != r) { fprintf(stderr,"blockEncrypt error %d\n",r); exit(-1); } blockPrint(fp, block, "CT"); /* now check decryption: */ makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial); blockDecrypt(&cipherInst, &keyInst, block, 128, block); for (j = 0; j < 16; j++) { assert(block[j] == 0); } /* undo changes for the next iteration: */ keyMaterial[i/4] = (BYTE)'0'; byteVal = (byteVal == '8') ? '4' : (byteVal == '4') ? '2' : (byteVal == '2') ? '1' : /* (byteVal == '1') */ '8'; } assert(byteVal == (BYTE)'8'); #ifdef TRACE_KAT_MCT printf(" done.\n");#endif /* ?TRACE_KAT_MCT */} /* rijndaelVKKAT */static void rijndaelVTKAT(FILE *fp, int keyLength) { int i; BYTE block[4*4]; BYTE keyMaterial[320]; keyInstance keyInst; cipherInstance cipherInst;#ifdef TRACE_KAT_MCT printf("Executing Variable-Text KAT (key %d): ", keyLength); fflush(stdout);#endif /* ?TRACE_KAT_MCT */ fprintf(fp, "\n" "==========\n" "\n" "KEYSIZE=%d\n" "\n", keyLength); fflush(fp); memset(keyMaterial, 0, sizeof (keyMaterial)); memset(keyMaterial, '0', keyLength/4); makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial); fprintf(fp, "KEY=%s\n", keyMaterial); for (i = 0; i < 128; i++) { memset(block, 0, 16); block[i/8] |= 1 << (7 - i%8); /* set only the i-th bit of the i-th test block */ fprintf (fp, "\nI=%d\n", i+1); blockPrint(fp, block, "PT"); cipherInit(&cipherInst, MODE_ECB, NULL); blockEncrypt(&cipherInst, &keyInst, block, 128, block); blockPrint(fp, block, "CT"); }#ifdef TRACE_KAT_MCT printf(" done.\n");#endif /* ?TRACE_KAT_MCT */}static void rijndaelTKAT(FILE *fp, int keyLength, FILE *in) { int i, j; unsigned int s; BYTE block[4*4], block2[4*4]; BYTE keyMaterial[320]; keyInstance keyInst; cipherInstance cipherInst;#ifdef TRACE_KAT_MCT printf("Executing Tables KAT (key %d): ", keyLength); fflush(stdout);#endif /* ?TRACE_KAT_MCT */ fprintf(fp, "\n" "==========\n" "\n" "KEYSIZE=%d\n" "\n", keyLength); fflush(fp); memset(keyMaterial, 0, sizeof (keyMaterial)); for (i = 0; i < 64; i++) { fprintf(fp, "\nI=%d\n", i+1); for(j = 0; j < keyLength/4; j++) { fscanf(in, "%c", &keyMaterial[j]); } makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial); fprintf(fp, "KEY=%s\n", keyMaterial); for (j = 0; j < 16; j++) { fscanf(in, "%02x", &s); block[j] = s; } fscanf(in, "%c", (char *)&s); fscanf(in, "%c", (char *)&s); blockPrint(fp, block, "PT"); cipherInit(&cipherInst, MODE_ECB, NULL); blockEncrypt(&cipherInst, &keyInst, block, 128, block2); blockPrint(fp, block2, "CT"); } for (i = 64; i < 128; i++) { fprintf(fp, "\nI=%d\n", i+1); for(j = 0; j < keyLength/4; j++) { fscanf(in, "%c", &keyMaterial[j]); } makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial); fprintf(fp, "KEY=%s\n", keyMaterial); for (j = 0; j < 16; j++) { fscanf(in, "%02x", &s); block[j] = s; } fscanf(in, "%c", (char *)&s); fscanf(in, "%c", (char *)&s); cipherInit(&cipherInst, MODE_ECB, NULL); blockDecrypt(&cipherInst, &keyInst, block, 128, block2); blockPrint(fp, block2, "PT"); blockPrint(fp, block, "CT"); }#ifdef TRACE_KAT_MCT printf(" done.\n");#endif /* ?TRACE_KAT_MCT */}#ifdef INTERMEDIATE_VALUE_KATstatic void rijndaelIVKAT (FILE *fp, int keyLength) { int i; BYTE pt[4*4], ct[4*4]; BYTE keyMaterial[320]; keyInstance keyInst; cipherInstance cipherInst; char format[10];#ifdef TRACE_KAT_MCT printf ("Executing Intermediate value KAT (key %d): ", keyLength); fflush (stdout);#endif /* ?TRACE_KAT_MCT */ fprintf(fp, "\n" "==========\n" "\n" "KEYSIZE=%d\n", keyLength); fflush(fp); memset(keyMaterial, 0, sizeof (keyMaterial)); for (i = 0; i < keyLength/8; i++) { sprintf(&keyMaterial[2*i], "%02X", i); } fprintf(fp, "KEY=%s\n", keyMaterial); for (i = 0; i < 16; i++) { pt[i] = i; } fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n"); makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial); blockPrint(fp, pt, "PT"); cipherInit(&cipherInst, MODE_ECB, NULL); for(i = 1; i < keyInst.Nr; i++) { cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, i); sprintf(format, "CT%d", i); blockPrint(fp, ct, format); } cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, keyInst.Nr); blockPrint(fp, ct, "CT"); fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n"); makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial); blockPrint(fp, ct, "CT"); cipherInit(&cipherInst, MODE_ECB, NULL); for(i = 1; i < keyInst.Nr; i++) { cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, i); sprintf(format, "PT%d", i); blockPrint(fp, pt, format); } cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, keyInst.Nr); blockPrint(fp, pt, "PT"); #ifdef TRACE_KAT_MCT printf(" done.\n");#endif }#endif /* INTERMEDIATE_VALUE_KAT */static void makeKATs(const char *vkFile, const char *vtFile, const char *tblFile, const char *ivFile) { FILE *fp, *fp2; /* prepare Variable Key Known Answer Tests: */ fp = fopen(vkFile, "w"); fprintf(fp, "\n" "=========================\n" "\n" "FILENAME: \"%s\"\n" "\n" "Electronic Codebook (ECB) Mode\n" "Variable Key Known Answer Tests\n" "\n" "Algorithm Name: Rijndael\n" "Principal Submitter: %s\n", vkFile, SUBMITTER); fflush(fp); rijndaelVKKAT(fp, 128); rijndaelVKKAT(fp, 192); rijndaelVKKAT(fp, 256); fprintf(fp, "\n" "=========="); fclose(fp); /* prepare Variable Text Known Answer Tests: */ fp = fopen(vtFile, "w"); fprintf(fp, "\n" "=========================\n" "\n" "FILENAME: \"%s\"\n" "\n" "Electronic Codebook (ECB) Mode\n" "Variable Text Known Answer Tests\n" "\n" "Algorithm Name: Rijndael\n" "Principal Submitter: %s\n", vtFile, SUBMITTER); fflush(fp); rijndaelVTKAT(fp, 128); rijndaelVTKAT(fp, 192); rijndaelVTKAT(fp, 256); fprintf(fp, "\n" "=========="); fclose(fp); /* prepare Tables Known Answer Tests: */ fp = fopen(tblFile, "w"); fprintf(fp, "/* Description of what tables are tested:\n" " The provided implementations each use a different set of tables\n" " - Java implementation: uses no tables\n" " - reference C implementation: uses Logtable, Alogtable, S, Si, rcon\n" " - fast C implementation: uses rcon and additionally\n" " Te0, Te1, Te2, Te3, Te4, Td0, Td1, Td2, Td3, Td4.\n" " All these tables are tested.\n" "\n" "=========================\n" "\n" "FILENAME: \"%s\"\n" "\n" "Electronic Codebook (ECB) Mode\n" "Tables Known Answer Tests\n" "\n" "Algorithm Name: Rijndael\n" "Principal Submitter: %s\n", tblFile, SUBMITTER); fflush(fp); if (NULL != (fp2 = fopen("table.128", "r"))) { rijndaelTKAT(fp, 128, fp2); fclose(fp2); } else { printf("Table Known Answer test expects file table.128\n"); fclose(fp); exit(EXIT_FAILURE); } if (NULL != (fp2 = fopen("table.192", "r"))) { rijndaelTKAT(fp, 192, fp2); fclose(fp2); } else { printf("Table Known Answer test expects file table.192\n"); fclose(fp); exit(EXIT_FAILURE); } if (NULL != (fp2 = fopen("table.256", "r"))) { rijndaelTKAT(fp, 256, fp2); fclose(fp2); } else { printf("Table Known Answer test expects file table.192\n"); fclose(fp); exit(EXIT_FAILURE); } fprintf(fp, "\n" "=========="); fclose(fp);#ifdef INTERMEDIATE_VALUE_KAT /* prepare Intermediate Values Known Answer Tests: */ fp = fopen(ivFile, "w"); fprintf(fp, "\n" "=========================\n" "\n" "FILENAME: \"%s\"\n" "\n" "Electronic Codebook (ECB) Mode\n" "Intermediate Value Known Answer Tests\n" "\n" "Algorithm Name: Rijndael\n" "Principal Submitter: %s\n", ivFile, SUBMITTER); fflush(fp); rijndaelIVKAT(fp, 128); rijndaelIVKAT(fp, 192); rijndaelIVKAT(fp, 256); fprintf(fp, "\n" "=========="); fclose(fp);#endif /* INTERMEDIATE_VALUE_KAT */}static void rijndaelECB_MCT(FILE *fp, int keyLength, BYTE direction) { int i, j; BYTE inBlock[4*4], outBlock[4*4], binKey[4*MAXKC]; BYTE keyMaterial[320]; keyInstance keyInst; cipherInstance cipherInst;#ifdef TRACE_KAT_MCT int width = 0; clock_t elapsed = -clock(); printf("Executing ECB MCT (%s, key %d): ", direction == DIR_ENCRYPT ? "ENCRYPT" : "DECRYPT", keyLength); fflush(stdout);#endif /* ?TRACE_KAT_MCT */ fprintf(fp, "\n" "=========================\n" "\n" "KEYSIZE=%d\n", keyLength); fflush(fp); memset(outBlock, 0, 16); memset(binKey, 0, keyLength/8); for (i = 0; i < 400; i++) {#ifdef TRACE_KAT_MCT while (width-- > 0) { putchar('\b'); } width = printf("%d", i); fflush(stdout); #endif /* ?TRACE_KAT_MCT */ fprintf(fp, "\nI=%d\n", i); /* prepare key: */ for (j = 0; j < keyLength/8; j++) { sprintf(&keyMaterial[2*j], "%02X", binKey[j]); } keyMaterial[keyLength/4] = 0; fprintf(fp, "KEY=%s\n", keyMaterial); makeKey(&keyInst, direction, keyLength, keyMaterial); /* do encryption/decryption: */ blockPrint(fp, outBlock, direction == DIR_ENCRYPT ? "PT" : "CT"); cipherInit(&cipherInst, MODE_ECB, NULL); if (direction == DIR_ENCRYPT) { for (j = 0; j < 10000; j++) { memcpy(inBlock, outBlock, 16); blockEncrypt(&cipherInst, &keyInst, inBlock, 128, outBlock); } } else { for (j = 0; j < 10000; j++) { memcpy(inBlock, outBlock, 16); blockDecrypt(&cipherInst, &keyInst, inBlock, 128, outBlock); } } blockPrint(fp, outBlock, direction == DIR_ENCRYPT ? "CT" : "PT"); /* prepare new key: */ switch (keyLength) { case 128: for (j = 0; j < 128/8; j++) { binKey[j] ^= outBlock[j]; } break; case 192: for (j = 0; j < 64/8; j++) { binKey[j] ^= inBlock[j + 64/8]; } for (j = 0; j < 128/8; j++) { binKey[j + 64/8] ^= outBlock[j]; } break; case 256: for (j = 0; j < 128/8; j++) { binKey[j] ^= inBlock[j]; } for (j = 0; j < 128/8; j++) { binKey[j + 128/8] ^= outBlock[j]; } break; } }#ifdef TRACE_KAT_MCT elapsed += clock(); while (width-- > 0) { putchar('\b'); } printf("%d done (%.1f s).\n", i, (float)elapsed/CLOCKS_PER_SEC);#endif /* ?TRACE_KAT_MCT */} /* rijndaelECB_MCT */static void rijndaelCBC_MCT(FILE *fp, int keyLength, BYTE direction) { int i, j, r, t;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -