Page principale | Hiérarchie des classes | Liste alphabétique | Liste des classes | Liste des fichiers | Membres de classe | Membres de fichier | Pages associées

rijndael-test-fst.c

00001 /**
00002  * rijndael-test-fst.c
00003  *
00004  * @version 3.0 (December 2000)
00005  *
00006  * Optimised ANSI C code for the Rijndael cipher (now AES)
00007  *
00008  * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
00009  * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
00010  * @author Paulo Barreto <paulo.barreto@terra.com.br>
00011  *
00012  * This code is hereby placed in the public domain.
00013  *
00014  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
00015  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00016  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00017  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
00018  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00019  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00020  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
00021  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00022  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
00023  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00024  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025  */
00026 
00027 #ifndef INTERMEDIATE_VALUE_KAT
00028 #error "Must #define INTERMEDIATE_VALUE_KAT to generate the Intermediate Value Known Answer Test."
00029 #endif /* INTERMEDIATE_VALUE_KAT */
00030 
00031 #include <assert.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <time.h>
00036 
00037 #include "rijndael-api-fst.h"
00038 
00039 #define SUBMITTER "Joan Daemen"
00040 
00041 static void blockPrint(FILE *fp, const BYTE *block, const char *tag) {
00042     int i;
00043     fprintf (fp, "%s=", tag);
00044     for (i = 0; i < 16; i++) {
00045         fprintf (fp, "%02X", block[i]);
00046     }
00047     fprintf (fp, "\n");
00048     fflush (fp);
00049 } /* blockPrint */
00050 
00051 static void rijndaelVKKAT(FILE *fp, int keyLength) {
00052     int i, j, r;
00053     BYTE block[4*4];
00054     BYTE keyMaterial[320];
00055     BYTE byteVal = (BYTE)'8';
00056     keyInstance keyInst;
00057     cipherInstance cipherInst;
00058 
00059 #ifdef TRACE_KAT_MCT
00060     printf("Executing Variable-Key KAT (key %d): ", keyLength);
00061     fflush(stdout);
00062 #endif /* ?TRACE_KAT_MCT */
00063     fprintf(fp,
00064         "\n"
00065         "==========\n"
00066         "\n"
00067         "KEYSIZE=%d\n"
00068         "\n", keyLength);
00069     fflush(fp);
00070     memset(block, 0, 16);
00071     blockPrint(fp, block, "PT");
00072     memset(keyMaterial, 0, sizeof (keyMaterial));
00073     memset(keyMaterial, '0', keyLength/4);
00074     for (i = 0; i < keyLength; i++) {
00075         keyMaterial[i/4] = byteVal; /* set only the i-th bit of the i-th test key */
00076         r = makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00077         if (TRUE != r) {
00078             fprintf(stderr,"makeKey error %d\n",r);
00079             exit(-1);
00080         }
00081         fprintf(fp, "\nI=%d\n", i+1);
00082         fprintf(fp, "KEY=%s\n", keyMaterial);
00083         memset(block, 0, 16);
00084         r = cipherInit(&cipherInst, MODE_ECB, NULL);
00085         if (TRUE != r) {
00086             fprintf(stderr,"cipherInit error %d\n",r);
00087             exit(-1);
00088         }
00089         r = blockEncrypt(&cipherInst, &keyInst, block, 128, block);
00090         if (128 != r) {
00091             fprintf(stderr,"blockEncrypt error %d\n",r);
00092             exit(-1);
00093         }
00094         blockPrint(fp, block, "CT");
00095         /* now check decryption: */
00096         makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
00097         blockDecrypt(&cipherInst, &keyInst, block, 128, block);
00098         for (j = 0; j < 16; j++) {
00099             assert(block[j] == 0);
00100         }
00101         /* undo changes for the next iteration: */
00102         keyMaterial[i/4] = (BYTE)'0';
00103         byteVal =
00104             (byteVal == '8') ?  '4' :
00105             (byteVal == '4') ?  '2' :
00106             (byteVal == '2') ?  '1' :
00107         /*  (byteVal == '1') */ '8';
00108     }
00109     assert(byteVal == (BYTE)'8');
00110     
00111 #ifdef TRACE_KAT_MCT
00112     printf(" done.\n");
00113 #endif /* ?TRACE_KAT_MCT */
00114 } /* rijndaelVKKAT */
00115 
00116 
00117 static void rijndaelVTKAT(FILE *fp, int keyLength) {
00118     int i;
00119     BYTE block[4*4];
00120     BYTE keyMaterial[320];
00121     keyInstance keyInst;
00122     cipherInstance cipherInst;
00123 
00124 #ifdef TRACE_KAT_MCT
00125     printf("Executing Variable-Text KAT (key %d): ", keyLength);
00126     fflush(stdout);
00127 #endif /* ?TRACE_KAT_MCT */
00128     fprintf(fp,
00129         "\n"
00130         "==========\n"
00131         "\n"
00132         "KEYSIZE=%d\n"
00133         "\n", keyLength);
00134     fflush(fp);
00135     memset(keyMaterial, 0, sizeof (keyMaterial));
00136     memset(keyMaterial, '0', keyLength/4);
00137     makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00138     fprintf(fp, "KEY=%s\n", keyMaterial);
00139     for (i = 0; i < 128; i++) {
00140         memset(block, 0, 16);
00141         block[i/8] |= 1 << (7 - i%8); /* set only the i-th bit of the i-th test block */
00142         fprintf (fp, "\nI=%d\n", i+1);
00143         blockPrint(fp, block, "PT");
00144         cipherInit(&cipherInst, MODE_ECB, NULL);
00145         blockEncrypt(&cipherInst, &keyInst, block, 128, block);
00146         blockPrint(fp, block, "CT");
00147     }
00148 #ifdef TRACE_KAT_MCT
00149     printf(" done.\n");
00150 #endif /* ?TRACE_KAT_MCT */
00151 }
00152 
00153 
00154 static void rijndaelTKAT(FILE *fp, int keyLength, FILE *in) {
00155     int i, j;
00156     unsigned int s;
00157     BYTE block[4*4], block2[4*4];
00158     BYTE keyMaterial[320];
00159     keyInstance keyInst;
00160     cipherInstance cipherInst;
00161 
00162 #ifdef TRACE_KAT_MCT
00163     printf("Executing Tables KAT (key %d): ", keyLength);
00164     fflush(stdout);
00165 #endif /* ?TRACE_KAT_MCT */
00166     fprintf(fp,
00167         "\n"
00168         "==========\n"
00169         "\n"
00170         "KEYSIZE=%d\n"
00171         "\n", keyLength);
00172     fflush(fp);
00173 
00174     memset(keyMaterial, 0, sizeof (keyMaterial));
00175     
00176     for (i = 0; i < 64; i++) {
00177         fprintf(fp, "\nI=%d\n", i+1);
00178         for(j = 0; j < keyLength/4; j++) {
00179             fscanf(in, "%c", &keyMaterial[j]);
00180         }
00181         makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00182         
00183         fprintf(fp, "KEY=%s\n", keyMaterial);
00184         
00185         for (j = 0; j < 16; j++) {
00186             fscanf(in, "%02x", &s);
00187             block[j] = s;
00188         }
00189         fscanf(in, "%c", (char *)&s);
00190         fscanf(in, "%c", (char *)&s);
00191         blockPrint(fp, block, "PT");
00192         cipherInit(&cipherInst, MODE_ECB, NULL);
00193         blockEncrypt(&cipherInst, &keyInst, block, 128, block2);
00194         blockPrint(fp, block2, "CT");
00195     }
00196     for (i = 64; i < 128; i++) {
00197         fprintf(fp, "\nI=%d\n", i+1);
00198         for(j = 0; j < keyLength/4; j++) {
00199             fscanf(in, "%c", &keyMaterial[j]);
00200         }
00201         makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
00202         
00203         fprintf(fp, "KEY=%s\n", keyMaterial);
00204         
00205         for (j = 0; j < 16; j++) {
00206             fscanf(in, "%02x", &s);
00207             block[j] = s;
00208         }
00209         fscanf(in, "%c", (char *)&s);
00210         fscanf(in, "%c", (char *)&s);
00211         cipherInit(&cipherInst, MODE_ECB, NULL);
00212         blockDecrypt(&cipherInst, &keyInst, block, 128, block2);
00213         blockPrint(fp, block2, "PT");
00214         blockPrint(fp, block, "CT");
00215     }
00216 
00217 #ifdef TRACE_KAT_MCT
00218     printf(" done.\n");
00219 #endif /* ?TRACE_KAT_MCT */
00220 }
00221 
00222 #ifdef INTERMEDIATE_VALUE_KAT
00223 static void rijndaelIVKAT (FILE *fp, int keyLength) {
00224     int i;
00225     BYTE pt[4*4], ct[4*4];
00226     BYTE keyMaterial[320];
00227     keyInstance keyInst;
00228     cipherInstance cipherInst;
00229     char format[10];
00230 #ifdef TRACE_KAT_MCT
00231     printf ("Executing Intermediate value KAT (key %d): ", keyLength);
00232     fflush (stdout);
00233 #endif /* ?TRACE_KAT_MCT */
00234 
00235     fprintf(fp,
00236         "\n"
00237         "==========\n"
00238         "\n"
00239         "KEYSIZE=%d\n",
00240         keyLength);
00241     fflush(fp);
00242     memset(keyMaterial, 0, sizeof (keyMaterial));
00243     for (i = 0; i < keyLength/8; i++) {
00244         sprintf(&keyMaterial[2*i], "%02X", i);
00245     }
00246     fprintf(fp, "KEY=%s\n", keyMaterial);
00247     
00248     for (i = 0; i < 16; i++) {
00249         pt[i] = i;
00250     }
00251     
00252     fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
00253     makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00254     blockPrint(fp, pt, "PT");
00255     cipherInit(&cipherInst, MODE_ECB, NULL);
00256     for(i = 1; i < keyInst.Nr; i++) {
00257         cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, i);
00258         sprintf(format, "CT%d", i);
00259         blockPrint(fp, ct, format);
00260     }
00261     cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, keyInst.Nr);
00262     blockPrint(fp, ct, "CT");
00263     
00264     fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
00265     makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
00266     blockPrint(fp, ct, "CT");
00267     cipherInit(&cipherInst, MODE_ECB, NULL);
00268     for(i = 1; i < keyInst.Nr; i++) {
00269         cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, i);
00270         sprintf(format, "PT%d", i);
00271         blockPrint(fp, pt, format);
00272     }
00273     cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, keyInst.Nr);
00274     blockPrint(fp, pt, "PT");
00275     
00276 #ifdef TRACE_KAT_MCT
00277     printf(" done.\n");
00278 #endif 
00279 }
00280 #endif /* INTERMEDIATE_VALUE_KAT */
00281 
00282 static void makeKATs(const char *vkFile, const char *vtFile, const char *tblFile, const char *ivFile) {
00283     FILE *fp, *fp2;
00284 
00285     /* prepare Variable Key Known Answer Tests: */
00286     fp = fopen(vkFile, "w");
00287     fprintf(fp,
00288         "\n"
00289         "=========================\n"
00290         "\n"
00291         "FILENAME:  \"%s\"\n"
00292         "\n"
00293         "Electronic Codebook (ECB) Mode\n"
00294         "Variable Key Known Answer Tests\n"
00295         "\n"
00296         "Algorithm Name: Rijndael\n"
00297         "Principal Submitter: %s\n",
00298         vkFile, SUBMITTER);
00299     fflush(fp);
00300 
00301     rijndaelVKKAT(fp, 128);
00302     rijndaelVKKAT(fp, 192);
00303     rijndaelVKKAT(fp, 256);
00304 
00305     fprintf(fp,
00306         "\n"
00307         "==========");
00308     fclose(fp);
00309 
00310     /* prepare Variable Text Known Answer Tests: */
00311     fp = fopen(vtFile, "w");
00312     fprintf(fp,
00313         "\n"
00314         "=========================\n"
00315         "\n"
00316         "FILENAME:  \"%s\"\n"
00317         "\n"
00318         "Electronic Codebook (ECB) Mode\n"
00319         "Variable Text Known Answer Tests\n"
00320         "\n"
00321         "Algorithm Name: Rijndael\n"
00322         "Principal Submitter: %s\n",
00323         vtFile, SUBMITTER);
00324     fflush(fp);
00325 
00326     rijndaelVTKAT(fp, 128);
00327     rijndaelVTKAT(fp, 192);
00328     rijndaelVTKAT(fp, 256);
00329 
00330     fprintf(fp,
00331         "\n"
00332         "==========");
00333     fclose(fp);
00334 
00335     /* prepare Tables Known Answer Tests: */
00336     fp = fopen(tblFile, "w");
00337     fprintf(fp,
00338         "/* Description of what tables are tested:\n"
00339         "   The provided implementations each use a different set of tables\n"
00340         "    - Java implementation: uses no tables\n"
00341         "    - reference C implementation: uses Logtable, Alogtable, S, Si, rcon\n"
00342         "    - fast C implementation: uses rcon and additionally\n"
00343         "        Te0, Te1, Te2, Te3, Te4, Td0, Td1, Td2, Td3, Td4.\n"
00344         "   All these tables are tested.\n"
00345         "\n"
00346         "=========================\n"
00347         "\n"
00348         "FILENAME:  \"%s\"\n"
00349         "\n"
00350         "Electronic Codebook (ECB) Mode\n"
00351         "Tables Known Answer Tests\n"
00352         "\n"
00353         "Algorithm Name: Rijndael\n"
00354         "Principal Submitter: %s\n",
00355         tblFile, SUBMITTER);
00356     fflush(fp);
00357 
00358     if (NULL != (fp2 = fopen("table.128", "r"))) {
00359         rijndaelTKAT(fp, 128, fp2);
00360         fclose(fp2);
00361     } else {
00362         printf("Table Known Answer test expects file table.128\n");
00363         fclose(fp);
00364         exit(EXIT_FAILURE);
00365     }
00366     if (NULL != (fp2 = fopen("table.192", "r"))) {
00367         rijndaelTKAT(fp, 192, fp2);
00368         fclose(fp2);
00369     } else {
00370         printf("Table Known Answer test expects file table.192\n");
00371         fclose(fp);
00372         exit(EXIT_FAILURE);     
00373     }
00374     if (NULL != (fp2 = fopen("table.256", "r"))) {
00375         rijndaelTKAT(fp, 256, fp2);
00376         fclose(fp2);
00377     } else {
00378         printf("Table Known Answer test expects file table.192\n");
00379         fclose(fp);
00380         exit(EXIT_FAILURE);
00381     }
00382     
00383     fprintf(fp,
00384         "\n"
00385         "==========");
00386     fclose(fp);
00387 
00388 #ifdef INTERMEDIATE_VALUE_KAT
00389     /* prepare Intermediate Values Known Answer Tests: */
00390     fp = fopen(ivFile, "w");
00391     fprintf(fp,
00392         "\n"
00393         "=========================\n"
00394         "\n"
00395         "FILENAME:  \"%s\"\n"
00396         "\n"
00397         "Electronic Codebook (ECB) Mode\n"
00398         "Intermediate Value Known Answer Tests\n"
00399         "\n"
00400         "Algorithm Name: Rijndael\n"
00401         "Principal Submitter: %s\n",
00402         ivFile, SUBMITTER);
00403     fflush(fp);
00404 
00405     rijndaelIVKAT(fp, 128);
00406     rijndaelIVKAT(fp, 192);
00407     rijndaelIVKAT(fp, 256);
00408 
00409     fprintf(fp,
00410         "\n"
00411         "==========");
00412     fclose(fp);
00413 #endif /* INTERMEDIATE_VALUE_KAT */
00414 }
00415 
00416 static void rijndaelECB_MCT(FILE *fp, int keyLength, BYTE direction) {
00417     int i, j;
00418     BYTE inBlock[4*4], outBlock[4*4], binKey[4*MAXKC];
00419     BYTE keyMaterial[320];
00420     keyInstance keyInst;
00421     cipherInstance cipherInst;
00422 
00423 #ifdef TRACE_KAT_MCT
00424     int width = 0;
00425     clock_t elapsed = -clock();
00426     printf("Executing ECB MCT (%s, key %d): ",
00427         direction == DIR_ENCRYPT ? "ENCRYPT" : "DECRYPT", keyLength);
00428     fflush(stdout);
00429 #endif /* ?TRACE_KAT_MCT */
00430     fprintf(fp,
00431         "\n"
00432         "=========================\n"
00433         "\n"
00434         "KEYSIZE=%d\n", keyLength);
00435     fflush(fp);
00436     memset(outBlock, 0, 16);
00437     memset(binKey, 0, keyLength/8);
00438     for (i = 0; i < 400; i++) {
00439 #ifdef TRACE_KAT_MCT                 
00440         while (width-- > 0) {
00441             putchar('\b');
00442         }
00443         width = printf("%d", i);
00444         fflush(stdout);    
00445 #endif /* ?TRACE_KAT_MCT */
00446         fprintf(fp, "\nI=%d\n", i);
00447         /* prepare key: */
00448         for (j = 0; j < keyLength/8; j++) {
00449             sprintf(&keyMaterial[2*j], "%02X", binKey[j]);
00450         }
00451         keyMaterial[keyLength/4] = 0;
00452         fprintf(fp, "KEY=%s\n", keyMaterial);
00453         makeKey(&keyInst, direction, keyLength, keyMaterial);
00454         /* do encryption/decryption: */
00455         blockPrint(fp, outBlock, direction == DIR_ENCRYPT ? "PT" : "CT");
00456         cipherInit(&cipherInst, MODE_ECB, NULL);
00457         if (direction == DIR_ENCRYPT) {
00458             for (j = 0; j < 10000; j++) {
00459                 memcpy(inBlock, outBlock, 16);
00460                 blockEncrypt(&cipherInst, &keyInst, inBlock, 128, outBlock);
00461             }
00462         } else {
00463             for (j = 0; j < 10000; j++) {
00464                 memcpy(inBlock, outBlock, 16);
00465                 blockDecrypt(&cipherInst, &keyInst, inBlock, 128, outBlock);
00466             }
00467         }
00468         blockPrint(fp, outBlock, direction == DIR_ENCRYPT ? "CT" : "PT");
00469         /* prepare new key: */
00470         switch (keyLength) {
00471         case 128:
00472             for (j = 0; j < 128/8; j++) {
00473                 binKey[j] ^= outBlock[j];
00474             }
00475             break;
00476         case 192:
00477             for (j = 0; j < 64/8; j++) {
00478                 binKey[j] ^= inBlock[j + 64/8];
00479             }
00480             for (j = 0; j < 128/8; j++) {
00481                 binKey[j + 64/8] ^= outBlock[j];
00482             }
00483             break;
00484         case 256:
00485             for (j = 0; j < 128/8; j++) {
00486                 binKey[j] ^= inBlock[j];
00487             }
00488             for (j = 0; j < 128/8; j++) {
00489                 binKey[j + 128/8] ^= outBlock[j];
00490             }
00491             break;
00492         }
00493     }
00494 #ifdef TRACE_KAT_MCT
00495     elapsed += clock();
00496     while (width-- > 0) {
00497         putchar('\b');
00498     }
00499     printf("%d done (%.1f s).\n", i, (float)elapsed/CLOCKS_PER_SEC);
00500 #endif /* ?TRACE_KAT_MCT */
00501 } /* rijndaelECB_MCT */
00502 
00503 
00504 static void rijndaelCBC_MCT(FILE *fp, int keyLength, BYTE direction) {
00505     int i, j, r, t;
00506     BYTE inBlock[256/8], outBlock[256/8], binKey[256/8], cv[256/8];
00507     BYTE keyMaterial[320];
00508     keyInstance keyInst;
00509     cipherInstance cipherInst;
00510 
00511 #ifdef TRACE_KAT_MCT
00512     int width = 0;
00513     clock_t elapsed = -clock();
00514     printf("Executing CBC MCT (%s, key %d): ",
00515         direction == DIR_ENCRYPT ? "ENCRYPT" : "DECRYPT", keyLength);
00516     fflush (stdout);
00517 #endif /* ?TRACE_KAT_MCT */
00518     fprintf (fp,
00519         "\n"
00520         "==========\n"
00521         "\n"
00522         "KEYSIZE=%d\n", keyLength);
00523     fflush(fp);
00524     memset(cv, 0, 16);
00525     memset(inBlock, 0, 16);
00526     memset(binKey, 0, keyLength/8);
00527     for (i = 0; i < 400; i++) {
00528 #ifdef TRACE_KAT_MCT                 
00529         while (width-- > 0) {
00530             putchar('\b');
00531         }
00532         width = printf("%d", i);
00533         fflush(stdout);    
00534 #endif /* ?TRACE_KAT_MCT */
00535         fprintf (fp, "\nI=%d\n", i);
00536         /* prepare key: */
00537         for (j = 0; j < keyLength/8; j++) {
00538             sprintf (&keyMaterial[2*j], "%02X", binKey[j]);
00539         }
00540         keyMaterial[keyLength/4] = 0;
00541         fprintf(fp, "KEY=%s\n", keyMaterial);
00542         r = makeKey(&keyInst, direction, keyLength, keyMaterial);
00543         if (TRUE != r) {
00544             fprintf(stderr,"makeKey error %d\n",r);
00545             exit(-1);
00546         }
00547         r = cipherInit(&cipherInst, MODE_ECB, NULL);
00548         if (TRUE != r) {
00549             fprintf(stderr,"cipherInit error %d\n",r);
00550             exit(-1);
00551         }
00552         /* do encryption/decryption: */
00553         blockPrint(fp, cv, "IV");
00554         blockPrint(fp, inBlock, direction == DIR_ENCRYPT ? "PT" : "CT");
00555         if (direction == DIR_ENCRYPT) {
00556             for (j = 0; j < 10000; j++) {
00557                 for (t = 0; t < 16; t++) {
00558                     inBlock[t] ^= cv[t];
00559                 }
00560                 r = blockEncrypt(&cipherInst, &keyInst, inBlock, 128, outBlock);
00561                 if (128 != r) {
00562                     fprintf(stderr,"blockEncrypt error %d\n",r);
00563                     exit(-1);
00564                 }
00565                 memcpy(inBlock, cv, 16);
00566                 memcpy(cv, outBlock, 16);
00567             }
00568         } else {
00569             for (j = 0; j < 10000; j++) {
00570                 blockDecrypt(&cipherInst, &keyInst, inBlock, 128, outBlock);
00571                 for (t = 0; t < 16; t++) {
00572                     outBlock[t] ^= cv[t];
00573                 }
00574                 memcpy(cv, inBlock, 16);
00575                 memcpy(inBlock, outBlock, 16);
00576             }
00577         }
00578         blockPrint(fp, outBlock, direction == DIR_ENCRYPT ? "CT" : "PT");
00579         /* prepare new key: */
00580         switch (keyLength) {
00581         case 128:
00582             for (j = 0; j < 128/8; j++) {
00583                 binKey[j] ^= outBlock[j];
00584             }
00585             break;
00586         case 192:
00587             for (j = 0; j < 64/8; j++) {
00588                 if (direction == DIR_ENCRYPT) {
00589                     binKey[j] ^= inBlock[j + 64/8];
00590                 } else {
00591                     binKey[j] ^= cv[j + 64/8];
00592                 }
00593             }
00594             for (j = 0; j < 128/8; j++) {
00595                 binKey[j + 64/8] ^= outBlock[j];
00596             }
00597             break;
00598         case 256:
00599             for (j = 0; j < 128/8; j++) {
00600                 if (direction == DIR_ENCRYPT) {
00601                     binKey[j] ^= inBlock[j];
00602                 } else {
00603                     binKey[j] ^= cv[j];
00604                 }
00605             }
00606             for (j = 0; j < 128/8; j++) {
00607                 binKey[j + 128/8] ^= outBlock[j];
00608             }
00609             break;
00610         }
00611     }
00612 #ifdef TRACE_KAT_MCT
00613     elapsed += clock();
00614     while (width-- > 0) {
00615         putchar('\b');
00616     }
00617     printf("%d done (%.1f s).\n", i, (float)elapsed/CLOCKS_PER_SEC);
00618 #endif /* ?TRACE_KAT_MCT */
00619 } /* rijndaelCBC_MCT */
00620 
00621 
00622 static void makeMCTs(const char *ecbEncryptionFile, const char *ecbDecryptionFile,
00623         const char *cbcEncryptionFile, const char *cbcDecryptionFile) {
00624     FILE *fp;
00625 
00626     /* prepare ECB Encryption Monte Carlo Tests: */
00627     fp = fopen(ecbEncryptionFile, "w");
00628     fprintf(fp,
00629         "\n"
00630         "=========================\n"
00631         "\n"
00632         "FILENAME:  \"%s\"\n"
00633         "\n"
00634         "Electronic Codebook (ECB) Mode - ENCRYPTION\n"
00635         "Monte Carlo Test\n"
00636         "\n"
00637         "Algorithm Name: Rijndael\n"
00638         "Principal Submitter: %s\n",
00639         ecbEncryptionFile, SUBMITTER);
00640     fflush(fp);
00641 
00642     rijndaelECB_MCT(fp, 128, DIR_ENCRYPT);
00643     rijndaelECB_MCT(fp, 192, DIR_ENCRYPT);
00644     rijndaelECB_MCT(fp, 256, DIR_ENCRYPT);
00645 
00646     fprintf(fp,
00647         "\n"
00648         "===========");
00649     fclose(fp);
00650 
00651     /* prepare ECB Decryption Monte Carlo Tests: */
00652     fp = fopen(ecbDecryptionFile, "w");
00653     fprintf(fp,
00654         "\n"
00655         "=========================\n"
00656         "\n"
00657         "FILENAME:  \"%s\"\n"
00658         "\n"
00659         "Electronic Codebook (ECB) Mode - DECRYPTION\n"
00660         "Monte Carlo Test\n"
00661         "\n"
00662         "Algorithm Name: Rijndael\n"
00663         "Principal Submitter: %s\n",
00664         ecbDecryptionFile, SUBMITTER);
00665     fflush(fp);
00666 
00667     rijndaelECB_MCT(fp, 128, DIR_DECRYPT);
00668     rijndaelECB_MCT(fp, 192, DIR_DECRYPT);
00669     rijndaelECB_MCT(fp, 256, DIR_DECRYPT);
00670 
00671     fprintf(fp,
00672         "\n"
00673         "===========");
00674     fclose(fp);
00675 
00676     /* prepare CBC Encryption Monte Carlo Tests: */
00677     fp = fopen (cbcEncryptionFile, "w");
00678     fprintf(fp,
00679         "\n"
00680         "=========================\n"
00681         "\n"
00682         "FILENAME:  \"%s\"\n"
00683         "\n"
00684         "Cipher Block Chaining (CBC) Mode - ENCRYPTION\n"
00685         "Monte Carlo Test\n"
00686         "\n"
00687         "Algorithm Name: Rijndael\n"
00688         "Principal Submitter: %s\n",
00689         cbcEncryptionFile, SUBMITTER);
00690     fflush(fp);
00691 
00692     rijndaelCBC_MCT(fp, 128, DIR_ENCRYPT);
00693     rijndaelCBC_MCT(fp, 192, DIR_ENCRYPT);
00694     rijndaelCBC_MCT(fp, 256, DIR_ENCRYPT);
00695 
00696     fprintf(fp,
00697         "\n"
00698         "===========");
00699     fclose(fp);
00700 
00701     /* prepare CBC Decryption Monte Carlo Tests: */
00702     fp = fopen(cbcDecryptionFile, "w");
00703     fprintf(fp,
00704         "\n"
00705         "=========================\n"
00706         "\n"
00707         "FILENAME:  \"%s\"\n"
00708         "\n"
00709         "Cipher Block Chaining (CBC) Mode - DECRYPTION\n"
00710         "Monte Carlo Test\n"
00711         "\n"
00712         "Algorithm Name: Rijndael\n"
00713         "Principal Submitter: %s\n",
00714         cbcDecryptionFile, SUBMITTER);
00715     fflush(fp);
00716 
00717     rijndaelCBC_MCT(fp, 128, DIR_DECRYPT);
00718     rijndaelCBC_MCT(fp, 192, DIR_DECRYPT);
00719     rijndaelCBC_MCT(fp, 256, DIR_DECRYPT);
00720 
00721     fprintf(fp,
00722         "\n"
00723         "===========");
00724     fclose(fp);
00725 } /* makeMCTs */
00726 
00727 static void makeFIPSTestVectors(const char *fipsFile) {
00728     int i, keyLength, r;
00729     keyInstance keyInst;
00730     cipherInstance cipherInst;
00731     BYTE keyMaterial[320];
00732     u8 pt[16], ct[16];
00733     char format[64];
00734     FILE *fp;
00735 
00736 #ifdef TRACE_KAT_MCT
00737     printf("Generating FIPS test vectors...");
00738 #endif /* ?TRACE_KAT_MCT */
00739     
00740     fp = fopen(fipsFile, "w");
00741     fprintf(fp,
00742         "\n"
00743         "================================\n\n"
00744         "FILENAME:  \"%s\"\n\n"
00745         "FIPS Test Vectors\n",
00746         fipsFile);
00747 
00748     /* 128-bit key: 00010103...0e0f: */
00749     keyLength = 128;
00750     memset(keyMaterial, 0, sizeof (keyMaterial));
00751     for (i = 0; i < keyLength/8; i++) {
00752         sprintf(&keyMaterial[2*i], "%02X", i);
00753     }
00754     
00755     fprintf(fp, "\n================================\n\n");
00756     fprintf(fp, "KEYSIZE=128\n\n");
00757     fprintf(fp, "KEY=%s\n\n", keyMaterial);
00758 
00759     /* plaintext is always 00112233...eeff: */
00760     for (i = 0; i < 16; i++) {
00761         pt[i] = (i << 4) | i;
00762     }
00763 
00764     /* encryption: */   
00765     makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00766     cipherInit(&cipherInst, MODE_ECB, NULL);
00767     fprintf(fp, "Round Subkey Values (Encryption)\n\n");
00768     for (r = 0; r <= keyInst.Nr; r++) {
00769         fprintf(fp, "RK%d=", r);
00770         for (i = 0; i < 4; i++) {
00771             u32 w = keyInst.rk[4*r + i];
00772             fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
00773         }
00774         fprintf(fp, "\n");
00775     }
00776     fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
00777     blockPrint(fp, pt, "PT");
00778     for (i = 1; i < keyInst.Nr; i++) {
00779         cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, i);
00780         sprintf(format, "CT%d", i);
00781         blockPrint(fp, ct, format);
00782     }
00783     cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, keyInst.Nr);
00784     blockPrint(fp, ct, "CT");
00785     
00786     /* decryption: */   
00787     makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
00788     cipherInit(&cipherInst, MODE_ECB, NULL);
00789     fprintf(fp, "\nRound Subkey Values (Decryption)\n\n");
00790     for (r = 0; r <= keyInst.Nr; r++) {
00791         fprintf(fp, "RK%d=", r);
00792         for (i = 0; i < 4; i++) {
00793             u32 w = keyInst.rk[4*r + i];
00794             fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
00795         }
00796         fprintf(fp, "\n");
00797     }
00798     fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
00799     blockPrint(fp, ct, "CT");
00800     for (i = 1; i < keyInst.Nr; i++) {
00801         cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, i);
00802         sprintf(format, "PT%d", i);
00803         blockPrint(fp, pt, format);
00804     }
00805     cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, keyInst.Nr);
00806     blockPrint(fp, pt, "PT");
00807 
00808     /* 192-bit key: 00010103...1617: */
00809     keyLength = 192;
00810     memset(keyMaterial, 0, sizeof (keyMaterial));
00811     for (i = 0; i < keyLength/8; i++) {
00812         sprintf(&keyMaterial[2*i], "%02X", i);
00813     }
00814     
00815     fprintf(fp, "\n================================\n\n");
00816     fprintf(fp, "KEYSIZE=192\n\n");
00817     fprintf(fp, "KEY=%s\n\n", keyMaterial);
00818 
00819     /* plaintext is always 00112233...eeff: */
00820     for (i = 0; i < 16; i++) {
00821         pt[i] = (i << 4) | i;
00822     }
00823 
00824     /* encryption: */   
00825     makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00826     cipherInit(&cipherInst, MODE_ECB, NULL);
00827     fprintf(fp, "\nRound Subkey Values (Encryption)\n\n");
00828     for (r = 0; r <= keyInst.Nr; r++) {
00829         fprintf(fp, "RK%d=", r);
00830         for (i = 0; i < 4; i++) {
00831             u32 w = keyInst.rk[4*r + i];
00832             fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
00833         }
00834         fprintf(fp, "\n");
00835     }
00836     fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
00837     blockPrint(fp, pt, "PT");
00838     for (i = 1; i < keyInst.Nr; i++) {
00839         cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, i);
00840         sprintf(format, "CT%d", i);
00841         blockPrint(fp, ct, format);
00842     }
00843     cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, keyInst.Nr);
00844     blockPrint(fp, ct, "CT");
00845     
00846     /* decryption: */   
00847     makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
00848     cipherInit(&cipherInst, MODE_ECB, NULL);
00849     fprintf(fp, "\nRound Subkey Values (Decryption)\n\n");
00850     for (r = 0; r <= keyInst.Nr; r++) {
00851         fprintf(fp, "RK%d=", r);
00852         for (i = 0; i < 4; i++) {
00853             u32 w = keyInst.rk[4*r + i];
00854             fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
00855         }
00856         fprintf(fp, "\n");
00857     }
00858     fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
00859     blockPrint(fp, ct, "CT");
00860     for(i = 1; i < keyInst.Nr; i++) {
00861         cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, i);
00862         sprintf(format, "PT%d", i);
00863         blockPrint(fp, pt, format);
00864     }
00865     cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, keyInst.Nr);
00866     blockPrint(fp, pt, "PT");
00867 
00868     /* 256-bit key: 00010103...1e1f: */
00869     keyLength = 256;
00870     memset(keyMaterial, 0, sizeof (keyMaterial));
00871     for (i = 0; i < keyLength/8; i++) {
00872         sprintf(&keyMaterial[2*i], "%02X", i);
00873     }
00874     
00875     fprintf(fp, "\n================================\n\n");
00876     fprintf(fp, "KEYSIZE=256\n\n");
00877     fprintf(fp, "KEY=%s\n\n", keyMaterial);
00878 
00879     /* plaintext is always 00112233...eeff: */
00880     for (i = 0; i < 16; i++) {
00881         pt[i] = (i << 4) | i;
00882     }
00883 
00884     /* encryption: */   
00885     makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
00886     cipherInit(&cipherInst, MODE_ECB, NULL);
00887     fprintf(fp, "\nRound Subkey Values (Encryption)\n\n");
00888     for (r = 0; r <= keyInst.Nr; r++) {
00889         fprintf(fp, "RK%d=", r);
00890         for (i = 0; i < 4; i++) {
00891             u32 w = keyInst.rk[4*r + i];
00892             fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
00893         }
00894         fprintf(fp, "\n");
00895     }
00896     fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
00897     blockPrint(fp, pt, "PT");
00898     for(i = 1; i < keyInst.Nr; i++) {
00899         cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, i);
00900         sprintf(format, "CT%d", i);
00901         blockPrint(fp, ct, format);
00902     }
00903     cipherUpdateRounds(&cipherInst, &keyInst, pt, 16, ct, keyInst.Nr);
00904     blockPrint(fp, ct, "CT");
00905     
00906     /* decryption: */   
00907     makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
00908     cipherInit(&cipherInst, MODE_ECB, NULL);
00909     fprintf(fp, "\nRound Subkey Values (Decryption)\n\n");
00910     for (r = 0; r <= keyInst.Nr; r++) {
00911         fprintf(fp, "RK%d=", r);
00912         for (i = 0; i < 4; i++) {
00913             u32 w = keyInst.rk[4*r + i];
00914             fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
00915         }
00916         fprintf(fp, "\n");
00917     }
00918     fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
00919     blockPrint(fp, ct, "CT");
00920     for(i = 1; i < keyInst.Nr; i++) {
00921         cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, i);
00922         sprintf(format, "PT%d", i);
00923         blockPrint(fp, pt, format);
00924     }
00925     cipherUpdateRounds(&cipherInst, &keyInst, ct, 16, pt, keyInst.Nr);
00926     blockPrint(fp, pt, "PT");
00927 
00928     fprintf(fp, "\n");
00929     fclose(fp);
00930 #ifdef TRACE_KAT_MCT
00931     printf(" done.\n");
00932 #endif /* ?TRACE_KAT_MCT */
00933 }
00934 
00935 #define ITERATIONS 10000000
00936 
00937 void rijndaelSpeed(int keyBits) {
00938     int Nr, i;
00939     u32 rk[4*(MAXNR + 1)];
00940     u8 cipherKey[256/8], pt[16], ct[16];
00941     clock_t elapsed;
00942     float sec;
00943 
00944     memset(cipherKey, 0, sizeof(cipherKey));
00945     printf("================================\n");
00946     printf("Speed measurement for %d-bit keys:\n", keyBits);
00947 
00948     /*
00949      * Encryption key setup timing:
00950      */
00951     elapsed = -clock();
00952     for (i = 0; i < ITERATIONS; i++) {
00953         Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits);
00954     }
00955     elapsed += clock();
00956     sec = (float)elapsed/CLOCKS_PER_SEC;
00957     printf("Encryption key schedule: %.1f s, %.0f Mbit/s\n",
00958         sec, (float)ITERATIONS*128/sec/1000000);
00959 
00960     /*
00961      * Encryption timing:
00962      */
00963     elapsed = -clock();
00964     for (i = 0; i < ITERATIONS; i++) {
00965         rijndaelEncrypt(rk, Nr, pt, ct);
00966     }
00967     elapsed += clock();
00968     sec = (float)elapsed/CLOCKS_PER_SEC;
00969     printf("Encryption: %.1f s, %.0f Mbit/s\n",
00970         sec, (float)ITERATIONS*128/sec/1000000);
00971 
00972     /*
00973      * Decryption key setup timing:
00974      */
00975     elapsed = -clock();
00976     for (i = 0; i < ITERATIONS; i++) {
00977         Nr = rijndaelKeySetupDec(rk, cipherKey, keyBits);
00978     }
00979     elapsed += clock();
00980     sec = (float)elapsed/CLOCKS_PER_SEC;
00981     printf("Decryption key schedule: %.1f s, %.0f Mbit/s\n",
00982         sec, (float)ITERATIONS*128/sec/1000000);
00983 
00984     /*
00985      * Decryption timing:
00986      */
00987     elapsed = -clock();
00988     for (i = 0; i < ITERATIONS; i++) {
00989         rijndaelDecrypt(rk, Nr, pt, ct);
00990     }
00991     elapsed += clock();
00992     sec = (float)elapsed/CLOCKS_PER_SEC;
00993     printf("Decryption: %.1f s, %.0f Mbit/s\n",
00994         sec, (float)ITERATIONS*128/sec/1000000);
00995 
00996 }
00997 
00998 int main(void) {
00999     makeFIPSTestVectors("fips-test-vectors.txt");
01000     makeKATs("ecb_vk.txt", "ecb_vt.txt", "ecb_tbl.txt", "ecb_iv.txt");
01001     makeMCTs("ecb_e_m.txt", "ecb_d_m.txt", "cbc_e_m.txt", "cbc_d_m.txt");
01002     /*
01003     rijndaelSpeed(128);
01004     rijndaelSpeed(192);
01005     rijndaelSpeed(256);
01006     */
01007     return 0;
01008 }

Généré le Thu Sep 6 13:57:46 2007 pour A.I.F. par  doxygen 1.3.9.1