Пример #1
0
static void rijndaelVKKAT (FILE *fp, int keyLength, int blockLength)
{
	int i, j, r;
	BYTE block[4*MAXBC];
	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, blockLength/8);
	blockPrint (fp, block, blockLength, "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 */
		keyInst.blockLen = blockLength;
		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, blockLength/8);
		cipherInst.blockLen = blockLength;
		r = cipherInit (&cipherInst, MODE_ECB, NULL);
		if (TRUE != r) {
			fprintf(stderr,"cipherInit error %d\n",r);
			exit(-1);
		}
		r = blockEncrypt(&cipherInst, &keyInst, block, blockLength, block);
		if (blockLength != r) {
			fprintf(stderr,"blockEncrypt error %d\n",r);
			exit(-1);
		}
		blockPrint (fp, block, blockLength, "CT");
		/* now check decryption: */
		keyInst.blockLen = blockLength;
		makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
		blockDecrypt(&cipherInst, &keyInst, block, blockLength, block);
		for (j = 0; j < blockLength/8; 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 */
Пример #2
0
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 */
}
Пример #3
0
static void rijndaelCBC_MCT (FILE *fp, const char *initKey, int keyLength,
	const char *initIV, const char *initBlock, int blockLength, BYTE direction)
{
	int i, j, r, t;
	BYTE inBlock[256/8], outBlock[256/8], binKey[256/8], cv[256/8];
	BYTE keyMaterial[320];
	BYTE iv[64+1];
	keyInstance keyInst;
	cipherInstance cipherInst;

#ifdef TRACE_KAT_MCT
	int width = 0;
	clock_t elapsed = -clock();
	printf ("Executing CBC 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);
	HexToBin (inBlock, initBlock, blockLength); /* this is either PT0 or CT0 */
	HexToBin (cv, initIV, blockLength);
	HexToBin (binKey, initKey, keyLength);
	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);
		keyInst.blockLen = blockLength;
		r = makeKey(&keyInst, direction, keyLength, keyMaterial);
		if (TRUE != r) {
			fprintf(stderr,"makeKey error %d\n",r);
			exit(-1);
		}
		/* do encryption/decryption: */
		blockPrint (fp, cv, blockLength, "IV");
		blockPrint (fp, inBlock, blockLength, direction == DIR_ENCRYPT ? "PT" : "CT");
		if (direction == DIR_ENCRYPT) {
			for (j = 0; j < 10000; j++) {
				for(t = 0; t < blockLength/8; t++) {
					sprintf(iv+2*t,"%02x",cv[t]);					
				}
				cipherInst.blockLen = blockLength;
				r = cipherInit (&cipherInst, MODE_CBC, iv);
				if (TRUE != r) {
					fprintf(stderr,"cipherInit error %d\n",r);
					exit(-1);
				}
				r = blockEncrypt(&cipherInst, &keyInst, inBlock, blockLength, outBlock);
				if (blockLength != r) {
					fprintf(stderr,"blockEncrypt error %d\n",r);
					exit(-1);
				}
				memcpy (inBlock, cv, blockLength/8);
				memcpy (cv, outBlock, blockLength/8);
			}
		} else {
			for (j = 0; j < 10000; j++) {
				for(t = 0; t < blockLength/8; t++) {
					sprintf(iv+2*t,"%02x",cv[t]);					
				}
				cipherInst.blockLen = blockLength;
				cipherInit (&cipherInst, MODE_CBC, iv);
				blockDecrypt(&cipherInst, &keyInst, inBlock, blockLength, outBlock);
				memcpy (cv, inBlock, blockLength/8);
				memcpy (inBlock, outBlock, blockLength/8);
			}
		}
		blockPrint (fp, outBlock, blockLength, 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++) {
				if (direction == DIR_ENCRYPT)
					binKey[j] ^= inBlock[j + 64/8];
				else
					binKey[j] ^= cv[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++) {
				if (direction == DIR_ENCRYPT)
					binKey[j] ^= inBlock[j];
				else
					binKey[j] ^= cv[j];
			}
			for (j = 0; j < 128/8; j++) {
				binKey[j + 128/8] ^= outBlock[j];
			}
			break;
		}
	}
#ifdef TRACE_KAT_MCT
	elapsed += clock();
	printf (" done (%.1f s).\n", (float)elapsed/CLOCKS_PER_SEC);
#endif /* ?TRACE_KAT_MCT */
} /* rijndaelCBC_MCT */
Пример #4
0
static void rijndaelECB_MCT (FILE *fp, const char *initKey, int keyLength,
	const char *initBlock, int blockLength, BYTE direction)
{
	int i, j;
	BYTE inBlock[4*MAXBC], outBlock[4*MAXBC], 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);
	HexToBin (outBlock, initBlock, blockLength);
	HexToBin (binKey, initKey, keyLength);
	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);
		keyInst.blockLen = blockLength;
		makeKey(&keyInst, direction, keyLength, keyMaterial);
		/* do encryption/decryption: */
		blockPrint (fp, outBlock, blockLength, direction == DIR_ENCRYPT ? "PT" : "CT");
		cipherInst.blockLen = blockLength;
		cipherInit (&cipherInst, MODE_ECB, NULL);
		if (direction == DIR_ENCRYPT) {
			for (j = 0; j < 10000; j++) {
				memcpy (inBlock, outBlock, blockLength/8);
				blockEncrypt(&cipherInst, &keyInst, inBlock, blockLength, outBlock);
			}
		} else {
			for (j = 0; j < 10000; j++) {
				memcpy (inBlock, outBlock, blockLength/8);
				blockDecrypt(&cipherInst, &keyInst, inBlock, blockLength, outBlock);
			}
		}
		blockPrint (fp, outBlock, blockLength, 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();
	printf (" done (%.1f s).\n", (float)elapsed/CLOCKS_PER_SEC);
#endif /* ?TRACE_KAT_MCT */
} /* rijndaelECB_MCT */
Пример #5
0
static void rijndaelIVKAT (FILE *fp, int keyLength, int blockLength)
{
	int i, ROUNDS;
	BYTE block[4*MAXBC], block2[4*MAXBC];
	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 */

	switch (keyLength >= blockLength ? keyLength : blockLength) {
	case 128: ROUNDS = 10; break;
	case 192: ROUNDS = 12; break;
	case 256: ROUNDS = 14; break;
	default : return; /* this cannot happen */
	}
	
	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);
	}
	keyInst.blockLen = blockLength;
	makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
	fprintf (fp, "KEY=%s\n", keyMaterial);
	fprintf (fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
	for (i = 0; i < blockLength/8; i++) {
		block[i] = i;
	}
	blockPrint (fp, block, blockLength, "PT");
	cipherInst.blockLen = blockLength;
	cipherInit (&cipherInst, MODE_ECB, NULL);
	for(i = 1; i < ROUNDS; i++) {
		cipherUpdateRounds (&cipherInst, &keyInst, block, blockLength/8, block2, i);
		sprintf(format,"CT%d",i);
		blockPrint (fp, block2, blockLength, format);
	}
	cipherUpdateRounds (&cipherInst, &keyInst, block, blockLength, block2, ROUNDS);
	blockPrint (fp, block2, blockLength, "CT");
	
	keyInst.blockLen = blockLength;
	makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
	fprintf (fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
	blockPrint (fp, block2, blockLength, "CT");
	cipherInst.blockLen = blockLength;
	cipherInit (&cipherInst, MODE_ECB, NULL);
	for(i = 1; i < ROUNDS; i++) {
		cipherUpdateRounds (&cipherInst, &keyInst, block2, blockLength,block, ROUNDS-i);
		sprintf(format,"PT%d",i);
		blockPrint (fp, block, blockLength, format);
	}
	cipherUpdateRounds (&cipherInst, &keyInst, block2, blockLength, block, 0);
	blockPrint (fp, block, blockLength, "PT");
	
#ifdef TRACE_KAT_MCT
	printf (" done.\n");
#endif 
}
Пример #6
0
static void rijndaelCBC_MCT(FILE * fp, int keyLength, BYTE direction)
{
        int i, j, r, t;
        BYTE inBlock[256 / 8], outBlock[256 / 8], binKey[256 / 8], cv[256 / 8];
        BYTE keyMaterial[320];
        keyInstance keyInst;
        cipherInstance cipherInst;

        printf(".");
        fflush(stdout);
#ifdef TRACE_KAT_MCT
        int width = 0;
        clock_t elapsed = -clock();
        printf("Executing CBC 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(cv, 0, 16);
        memset(inBlock, 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);
                r = makeKey(&keyInst, direction, keyLength, keyMaterial);
                if (TRUE != r) {
                        fprintf(stderr, "makeKey error %d\n", r);
                        exit(-1);
                }
                r = cipherInit(&cipherInst, MODE_ECB, NULL);
                if (TRUE != r) {
                        fprintf(stderr, "cipherInit error %d\n", r);
                        exit(-1);
                }
                /* do encryption/decryption: */
                blockPrint(fp, cv, "IV");
                blockPrint(fp, inBlock, direction == DIR_ENCRYPT ? "PT" : "CT");
                if (direction == DIR_ENCRYPT) {
                        for (j = 0; j < 10000; j++) {
                                for (t = 0; t < 16; t++) {
                                        inBlock[t] ^= cv[t];
                                }
                                r = blockEncrypt(&cipherInst, &keyInst, inBlock,
                                                 128, outBlock);
                                if (128 != r) {
                                        fprintf(stderr,
                                                "blockEncrypt error %d\n", r);
                                        exit(-1);
                                }
                                memcpy(inBlock, cv, 16);
                                memcpy(cv, outBlock, 16);
                        }
                } else {
                        for (j = 0; j < 10000; j++) {
                                blockDecrypt(&cipherInst, &keyInst, inBlock,
                                             128, outBlock);
                                for (t = 0; t < 16; t++) {
                                        outBlock[t] ^= cv[t];
                                }
                                memcpy(cv, inBlock, 16);
                                memcpy(inBlock, outBlock, 16);
                        }
                }
                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++) {
                                if (direction == DIR_ENCRYPT) {
                                        binKey[j] ^= inBlock[j + 64 / 8];
                                } else {
                                        binKey[j] ^= cv[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++) {
                                if (direction == DIR_ENCRYPT) {
                                        binKey[j] ^= inBlock[j];
                                } else {
                                        binKey[j] ^= cv[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 */
}                               /* rijndaelCBC_MCT */
Пример #7
0
static void makeFIPSTestVectors(const char *fipsFile) {
	int i, keyLength, r;
	keyInstance keyInst;
	cipherInstance cipherInst;
	BYTE keyMaterial[320];
	u8 pt[16], ct[16];
	char format[64];
	FILE *fp;

#ifdef TRACE_KAT_MCT
	printf("Generating FIPS test vectors...");
#endif /* ?TRACE_KAT_MCT */
	
	fp = fopen(fipsFile, "w");
	fprintf(fp,
		"\n"
		"================================\n\n"
		"FILENAME:  \"%s\"\n\n"
		"FIPS Test Vectors\n",
		fipsFile);

	/* 128-bit key: 00010103...0e0f: */
	keyLength = 128;
	memset(keyMaterial, 0, sizeof (keyMaterial));
	for (i = 0; i < keyLength/8; i++) {
		sprintf(&keyMaterial[2*i], "%02X", i);
	}
	
	fprintf(fp, "\n================================\n\n");
	fprintf(fp, "KEYSIZE=128\n\n");
    fprintf(fp, "KEY=%s\n\n", keyMaterial);

	/* plaintext is always 00112233...eeff: */
	for (i = 0; i < 16; i++) {
		pt[i] = (i << 4) | i;
	}

    /* encryption: */	
	makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
	cipherInit(&cipherInst, MODE_ECB, NULL);
	fprintf(fp, "Round Subkey Values (Encryption)\n\n");
    for (r = 0; r <= keyInst.Nr; r++) {
        fprintf(fp, "RK%d=", r);
        for (i = 0; i < 4; i++) {
            u32 w = keyInst.rke[4*r + i];
            fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
        }
        fprintf(fp, "\n");
    }
	fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
	blockPrint(fp, pt, "PT");
	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");
	
    /* decryption: */	
	makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
	cipherInit(&cipherInst, MODE_ECB, NULL);
	fprintf(fp, "\nRound Subkey Values (Decryption)\n\n");
    for (r = 0; r <= keyInst.Nr; r++) {
        fprintf(fp, "RK%d=", r);
        for (i = 0; i < 4; i++) {
            u32 w = keyInst.rkd[4*r + i];
            fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
        }
        fprintf(fp, "\n");
    }
	fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
	blockPrint(fp, ct, "CT");
	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");

	/* 192-bit key: 00010103...1617: */
	keyLength = 192;
	memset(keyMaterial, 0, sizeof (keyMaterial));
	for (i = 0; i < keyLength/8; i++) {
		sprintf(&keyMaterial[2*i], "%02X", i);
	}
	
	fprintf(fp, "\n================================\n\n");
	fprintf(fp, "KEYSIZE=192\n\n");
    fprintf(fp, "KEY=%s\n\n", keyMaterial);

	/* plaintext is always 00112233...eeff: */
	for (i = 0; i < 16; i++) {
		pt[i] = (i << 4) | i;
	}

    /* encryption: */	
	makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
	cipherInit(&cipherInst, MODE_ECB, NULL);
	fprintf(fp, "\nRound Subkey Values (Encryption)\n\n");
    for (r = 0; r <= keyInst.Nr; r++) {
        fprintf(fp, "RK%d=", r);
        for (i = 0; i < 4; i++) {
            u32 w = keyInst.rke[4*r + i];
            fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
        }
        fprintf(fp, "\n");
    }
	fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
	blockPrint(fp, pt, "PT");
	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");
	
    /* decryption: */	
	makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
	cipherInit(&cipherInst, MODE_ECB, NULL);
	fprintf(fp, "\nRound Subkey Values (Decryption)\n\n");
    for (r = 0; r <= keyInst.Nr; r++) {
        fprintf(fp, "RK%d=", r);
        for (i = 0; i < 4; i++) {
            u32 w = keyInst.rkd[4*r + i];
            fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
        }
        fprintf(fp, "\n");
    }
	fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
	blockPrint(fp, ct, "CT");
	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");

	/* 256-bit key: 00010103...1e1f: */
	keyLength = 256;
	memset(keyMaterial, 0, sizeof (keyMaterial));
	for (i = 0; i < keyLength/8; i++) {
		sprintf(&keyMaterial[2*i], "%02X", i);
	}
	
	fprintf(fp, "\n================================\n\n");
	fprintf(fp, "KEYSIZE=256\n\n");
    fprintf(fp, "KEY=%s\n\n", keyMaterial);

	/* plaintext is always 00112233...eeff: */
	for (i = 0; i < 16; i++) {
		pt[i] = (i << 4) | i;
	}

    /* encryption: */	
	makeKey(&keyInst, DIR_ENCRYPT, keyLength, keyMaterial);
	cipherInit(&cipherInst, MODE_ECB, NULL);
	fprintf(fp, "\nRound Subkey Values (Encryption)\n\n");
    for (r = 0; r <= keyInst.Nr; r++) {
        fprintf(fp, "RK%d=", r);
        for (i = 0; i < 4; i++) {
            u32 w = keyInst.rke[4*r + i];
            fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
        }
        fprintf(fp, "\n");
    }
	fprintf(fp, "\nIntermediate Ciphertext Values (Encryption)\n\n");
	blockPrint(fp, pt, "PT");
	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");
	
    /* decryption: */	
	makeKey(&keyInst, DIR_DECRYPT, keyLength, keyMaterial);
	cipherInit(&cipherInst, MODE_ECB, NULL);
	fprintf(fp, "\nRound Subkey Values (Decryption)\n\n");
    for (r = 0; r <= keyInst.Nr; r++) {
        fprintf(fp, "RK%d=", r);
        for (i = 0; i < 4; i++) {
            u32 w = keyInst.rkd[4*r + i];
            fprintf(fp, "%02X%02X%02X%02X", w >> 24, (w >> 16) & 0xff, (w >> 8) & 0xff, w & 0xff);
        }
        fprintf(fp, "\n");
    }
	fprintf(fp, "\nIntermediate Ciphertext Values (Decryption)\n\n");
	blockPrint(fp, ct, "CT");
	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");

    fprintf(fp, "\n");
	fclose(fp);
#ifdef TRACE_KAT_MCT
	printf(" done.\n");
#endif /* ?TRACE_KAT_MCT */
}