📄 aesgav.cpp
字号:
// Copyright in this code is held by Dr B. R. Gladman but free direct or
// derivative use is permitted subject to acknowledgement of its origin.
// Dr B. R. Gladman <brg@gladman.uk.net> 1st June 2001.
//
// AES Algorithm Test - Generate local test files for KAT and Monte Carlo
// tests and optionally compare these files with a reference set of test
// files
//
// usage: aes_gav /t:[knec] /b:[45678] /k:[45678] [/c]
//
// where:
//
// each of the symbols in square brakets can be used in any combination so
// that:
//
// /t:[knec] selects the tests to be used
// /b:[45678] selects the block lengths to be used (in 32-bit words)
// /k:[45678] selects the key lengths to be used (in 32-bit words)
// /c selects the comparison of output and reference file(s)
// and:
// k: generate ECB Known Answer Test files
// n: generate ECB Known Answer Test files (new)
// e: generate ECB Monte Carlo Test files
// c: generate CBC Monte Carlo Test files
//
// The reference files have a ".txt" extension while those generated use
// ".txt" if in a different directory or ".dat" otherwise. The directory
// paths for files are set below. Note that, when compared with the NIST
// test vector sequences, this code implements one additional (all zero)
// test vector as the first vector in each set (test 0).
#include "aes.h"
#include "aesaux.h"
#include "aestst.h"
using std::cout;
using std::ofstream;
using std::ifstream;
using std::ios_base;
#if defined(AES_DLL)
fn_ptrs fn;
#endif
// Outputs a test vector file header
void header(ofstream& outf, const int type, const word blen, const word klen)
{ char buf[32];
byte dummy;
outf << "==============================================";
outf << "\nAuthor: Dr B R Gladman (brg@gladman.uk.net)";
outf << "\nTest: " << (type < 6 ? "ECB " : "CBC ");
switch(type)
{
case 0: outf << "Variable Key Known Answer Tests"; break;
case 2: outf << "Variable Key Known Answer Tests"; break;
case 1: outf << "Variable Text Known Answer Tests"; break;
case 3: outf << "Variable Text Known Answer Tests"; break;
case 4:
case 6: outf << "Monte Carlo (Encryption) Tests"; break;
case 5:
case 7: outf << "Monte Carlo (Decryption) Tests"; break;
}
outf << "\nAlgorithm: Extended Rijndael (an AES Superset)\nFilename: "
<< file_name(buf, type, blen, klen)
<< "\n==============================================\n";
block_out(block_len, &dummy, outf, 8 * blen);
block_out(key_len, &dummy, outf, 8 * klen);
outf << '\n';
}
// Test of Electronic Code Book (ECB) Mode with Fixed Key and Variable Text
void ecb_vt(ofstream& outf, aes* alg, const word blen, const word klen)
{ word j;
byte pt[32], ct[32], key[32], dummy;
block_clear(key, klen); // all zero key
block_out(key_val, key, outf, klen); // output key value
f_set_key(alg, key, klen, both); // set key value
for(j = 0; j <= 8 * blen; ++j) // test vectors include
{ // an all zero one
block_out(test_no, &dummy, outf, j); // output test number
block_clear(pt, blen); // set all zero plain text
if(j) // set bit (j-1) if j <> 0
*(pt + (j - 1) / 8) = 0x80 >> (j - 1) % 8;
block_out(pt_val, pt, outf, blen); // output plaintext
f_encrypt(alg, pt , ct); // do encryption
block_out(ct_val, ct, outf, blen); // output ciphertext
}
}
// Test of Electronic Code Book (ECB) Mode with Fixed Text and Variable Key
void ecb_vk(ofstream& outf, aes* alg, const word blen, const word klen)
{ word j;
byte pt[32], ct[32], key[32], dummy;
block_clear(pt, blen); // all zero plaintext
block_out(pt_val, pt, outf, blen); // output plaintext
for(j = 0; j <= 8 * klen; ++j) // 129, 193 or 257 tests
{
block_out(test_no, &dummy, outf, j); // output test number
block_clear(key, klen); // set all zero key
if(j) // set bit (j-1) if j <> 0
*(key + (j - 1) / 8) = 0x80 >> (j - 1) % 8;
block_out(key_val, key, outf, klen); // output key value
f_set_key(alg, key, klen, enc); // set key value
f_encrypt(alg, pt , ct); // alg.encrypt
block_out(ct_val, ct, outf, blen); // output ciphertext
}
}
// Test of Electronic Code Book (ECB) Mode with Fixed Key and Variable Text
void ecb_vtn(ofstream& outf, aes* alg, const word blen, const word klen)
{ word j;
byte pt[32], ct[32], key[32], *bp, dummy;
block_clear(key, klen); // all zero key
block_out(key_val, key, outf, klen); // output key value
f_set_key(alg, key, klen, both); // set key value
block_clear(pt, blen); // set all zero plain text
for(j = 0; j < 16 * blen; ++j)
{
block_out(test_no, &dummy, outf, j); // output test number
block_out(pt_val, pt, outf, blen); // output plaintext
f_encrypt(alg, pt , ct); // do encryption
block_out(ct_val, ct, outf, blen); // output ciphertext
bp = pt + blen - 1 - j / 8;
if(j < 8 * blen)
*bp |= (*bp << 1) | 1;
else
*(bp + blen) = *(bp + blen) << 1;
}
}
// Test of Electronic Code Book (ECB) Mode with Fixed Text and Variable Key
void ecb_vkn(ofstream& outf, aes* alg, const word blen, const word klen)
{ word j;
byte pt[32], ct[32], key[32], *bp, dummy;
block_clear(pt, blen); // all zero plaintext
block_out(pt_val, pt, outf, blen); // output plaintext
block_clear(key, klen);
for(j = 0; j < 16 * klen; ++j)
{
block_out(test_no, &dummy, outf, j); // output test number
block_out(key_val, key, outf, klen); // output key value
f_set_key(alg, key, klen, enc); // set key value
f_encrypt(alg, pt , ct); // alg.encrypt
block_out(ct_val, ct, outf, blen); // output ciphertext
bp = key + klen - 1 - j / 8;
if(j < 8 * klen)
*bp |= (*bp << 1) | 1;
else
*(bp + klen) = *(bp + klen) << 1;
}
}
// Monte Carlo Encryption Test of Electronic Code Book (ECB) Mode
void ecb_me(ofstream& outf, aes* alg, const word blen, const word klen)
{ word j, k;
byte pt[32], ct[64], key[32], dummy;
block_clear(pt, blen); // clear initial plaintext
block_clear(key, klen); // and key blocks
block_copy(ct + blen, pt, blen); // put plaintext in upper half
// of double length buffer
for(j = 0; j < 400; j++) // 400 Monte Carlo tests
{
block_out(test_no, &dummy, outf, j); // output test number
block_out(key_val, key, outf, klen); // output key
block_out(pt_val, pt, outf, blen); // output plaintext
f_set_key(alg, key, klen, enc); // set the key
for(k = 0; k < 5000; ++k) // 10000 encryptions alternating
{ // upper and lower blocks in ct
f_encrypt(alg, ct + blen, ct);
f_encrypt(alg, ct, ct + blen);
}
// compile next key as defined by NIST
block_xor(key, ct + 2 * blen - klen, klen);
block_out(ct_val, ct + blen, outf, blen); // output ciphertext
block_copy(pt, ct + blen, blen); // copy cipertext as next plaintext
}
}
// Monte Carlo Decryption Test of Electronic Code Book (ECB) Mode
void ecb_md(ofstream& outf, aes* alg, const word blen, const word klen)
{ word j, k;
byte pt[32], ct[64], key[32], dummy;
block_clear(pt, blen); // clear initial plaintext and key
block_clear(key, klen);
block_copy(ct + blen, pt, blen); // copy plaintext into upper half
// of double length ciphertext block
for(j = 0; j < 400; j++) // 400 Monte Carlo tests
{
block_out(test_no, &dummy, outf, j); // output test number
block_out(key_val, key, outf, klen); // output key
block_out(ct_val, pt, outf, blen); // output plaintext
f_set_key(alg, key, klen, dec); // set key
for(k = 0; k < 5000; ++k) // 10000 decryptions alternating
{ // upper and lower blocks in ct
f_decrypt(alg, ct + blen, ct);
f_decrypt(alg, ct, ct + blen);
}
// compile next key as defined by NIST
block_xor(key, ct + 2 * blen - klen, klen);
block_out(pt_val, ct + blen, outf, blen); // output ciphertext
block_copy(pt, ct + blen, blen); // set ciphertext as next plaintext
}
}
// Monte Carlo Encryption Test of Cipher Block Chaining (CBC) Mode
void cbc_me(ofstream& outf, aes* alg, const word blen, const word klen)
{ word j, k;
byte ct[64], key[32], dummy;
block_clear(key, klen); // clear key: KEY[0]
block_clear(ct, 2 * blen); // clear ct: PT[0], ct + blen: IV[0]
for(j = 0; j < 400; j++) // 400 Monte Carlo tests
{
block_out(test_no, &dummy, outf, j); // output test number
block_out(key_val, key, outf, klen); // output key
block_out(iv_val, ct + blen, outf, blen); // output initialisation vector
block_out(pt_val, ct, outf, blen); // output plaintext
f_set_key(alg, key, klen, enc); // set key
for(k = 0; k < 5000; ++k) // 10000 encryptions, two at a time
{
block_xor(ct, ct + blen, blen); // do CBC chaining
f_encrypt(alg, ct, ct); // do block encryption
block_xor(ct + blen, ct, blen); // do CBC chaining
f_encrypt(alg, ct + blen, ct + blen); // do block encryption
}
block_out(ct_val, ct + blen, outf, blen); // output ciphertext
// compile next key as defined by NIST
block_xor(key, ct + 2 * blen - klen, klen);
}
}
// Monte Carlo Encryption Test of Cipher Block Chaining (CBC) Mode
void cbc_md(ofstream& outf, aes* alg, const word blen, const word klen)
{ word j, k;
byte pt[32], ct[64], key[32], dummy;
block_clear(key, klen); // clear key: KEY[0]
block_clear(ct, 2 * blen); // clear ct: IV[0] ct + blen: CT[0]
for(j = 0; j < 400; j++) // 400 Monte Carlo tests
{
block_out(test_no, &dummy, outf, j); // output test number
block_out(key_val, key, outf, klen); // output key
block_out(iv_val, ct, outf, blen); // output initialisation vector
block_out(ct_val, ct + blen, outf, blen); // output ciphertext
f_set_key(alg, key, klen, dec); // set key
for(k = 0; k < 5000; ++k) // 10000 encryptions, two at a time
{
f_decrypt(alg, ct + blen, pt); // do block decryption
block_xor(ct, pt, blen); // do CBC chaining
f_decrypt(alg, ct, pt); // do block decryption
block_xor(ct + blen, pt, blen); // do CBC chaining
}
block_out(pt_val, ct + blen, outf, blen); // output plaintext
// compile next key as defined by NIST
block_xor(key, ct + 2 * blen - klen, klen);
}
}
// Synchronise two comparison files if they get out of step
int sync(int nbr, ifstream& inf, char str[], bool outp)
{ line_type ty;
int nn;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -