⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aes_rav.cpp

📁 关于AES加密算法的VC源代码
💻 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.
//
// usage: aes_rav /t:[knec] /b:[45678] /k:[45678]
//
// 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)
// 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
//
// 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 "aes_aux.h"
#include "aes_tst.h"

#if defined(AES_DLL)
fn_ptrs fn;
#endif

using   std::cout;
using   std::ifstream;
using   std::ofstream;

enum test_type { ecb_vk, ecb_vt, ecb_nvk, ecb_nvt, ecb_me, ecb_md, cbc_me, cbc_md };

void ref_test(const char *in_file, const unsigned int it_cnt, enum test_type t_type, 
								aes *alg, const word blen, const word klen)
{   word        i, test_cnt, cnt, e_cnt, fe_cnt;
    byte        key[32], pt[32], iv[32], ect[32], act[64];
    char        str[128];
    line_type   ty;
    ifstream    inf;

    cout << "Test file " << in_file << ": ";

    inf.open(in_file);				// reference test vector file

    if(!inf)
    {
        cout << " file not found \n"; return;
    }

    cnt = 0; e_cnt = test_cnt = 0;

    for(;;)                         // while there are tests
    {
        ty = find_line(inf, str);   // input a line

        if(ty == bad_line)          // until end of file

            break;

        if(ty == block_len)
        {
              if((get_dec(str) >> 3) == blen) continue;
              
              return;
        }
        else if(ty == key_len)
        {
              if((get_dec(str) >> 3) == klen) continue;
              
              return;
        }
        else if(ty == test_no)
        {
            test_cnt = get_dec(str); continue;
        }
        else if(ty == iv_val)
        {
            block_in(iv, str); continue;
        }
        else if(ty == key_val)
        {
            block_in(key, str); continue;
        }
        else if(ty == pt_val)
        {
            block_in(pt, str);
            if(t_type != ecb_md && t_type != cbc_md) continue;
        }
        else if(ty == ct_val)
        {
            block_in(ect, str);
            if(t_type == ecb_md || t_type == cbc_md) continue;
        }

        f_set_key(alg, key, klen, both);            // set the key

        if(t_type == ecb_md || t_type == cbc_md)
        {
            block_copy(act, ect, blen);             // encrypted text to low block

            if(t_type == cbc_md)                    // CBC Monte Carlo decryption
            {
                block_copy(act + blen, iv, blen);   // IV to high block

                for(i = 0; i < it_cnt; i += 2)      // do decryptions two at a time
                {
                    f_decrypt(alg, act, ect);       // decrypt low block

                    block_xor(act + blen, ect, blen);   // xor into high block

                    f_decrypt(alg, act + blen, ect);    // decrypt high block

                    block_xor(act, ect, blen);      // xor into low block
                }
            }
            else    // ECB Monte Carlo decryption
            {
                for(i = 0; i < it_cnt; ++i)

                    f_decrypt(alg, act, act);
            }

            if(!block_cmp(pt, act, blen)) if(!e_cnt++) fe_cnt = test_cnt;

            if(t_type == ecb_md)    // test encryption if ECB mode
            {
                for(i = 0; i < it_cnt; ++i)

                    f_encrypt(alg, act, act);

                if(!block_cmp(ect, act, blen)) 
                    
                    if(!e_cnt++) fe_cnt = test_cnt;
            }
        }
        else    // if(t_type == ecb_me || t_type == cbc_me || ecb_vk || ecb_vt)
        {
            if(t_type == cbc_me)                        // CBC Monte Carlo encryption
            {
                block_copy(act, iv, blen);
                block_copy(act + blen, pt, blen);       // copy IV and plaintext

                for(i = 0; i < it_cnt; i += 2)
                {
                    block_xor(act + blen, act, blen);   // xor low block into high block

                    f_encrypt(alg, act + blen, act + blen); // encrypt high block

                    block_xor(act, act + blen, blen);   // xor high block into low block

                    f_encrypt(alg, act, act);           // encrypt low block
                }
            }
            else    // ECB Monte Carlo encryption
            {
                block_copy(act, pt, blen);

                for(i = 0; i < it_cnt; ++i)

                    f_encrypt(alg, act, act);
            }

            if(!block_cmp(ect, act, blen)) if(!e_cnt++) fe_cnt = test_cnt;

            if(t_type != cbc_me)    // if ECB mode test decrytpion
            {
                for(i = 0; i < it_cnt; ++i)

                    f_decrypt(alg, act, act);

                if(!block_cmp(pt, act, blen)) if(!e_cnt++) fe_cnt = test_cnt;
            }
        }
    }

    inf.close();

    if(e_cnt > 0)   // report any errors
    {
        cout << e_cnt << " ERRORS during test (first on test " << fe_cnt << ")\n";
    }
    else            // else report all is well

        cout << "all tests correct\n";
}

void do_tests(const bool vkt, const bool vktn, const bool ecb, const bool cbc, aes *alg,
                const word blen, const word klen)
{   char    path[128], *sp;

    sp = copy_str(path, ref_path);

    if(vkt)
    {
        file_name(sp, 0, blen, klen); 
        ref_test(path, 1, ecb_vk, alg, blen, klen);
        file_name(sp, 1, blen, klen); 
        ref_test(path, 1, ecb_vt, alg, blen, klen);
    }

    if(vktn)
    {
        file_name(sp, 2, blen, klen); 
        ref_test(path, 1, ecb_nvk, alg, blen, klen);
        file_name(sp, 3, blen, klen); 
        ref_test(path, 1, ecb_nvt, alg, blen, klen);
    }

    if(ecb)
    {
        file_name(sp, 4, blen, klen); 
        ref_test(path, 10000, ecb_me, alg, blen, klen);
        file_name(sp, 5, blen, klen); 
        ref_test(path, 10000, ecb_md, alg, blen, klen);
    }

    if(cbc)
    {
        file_name(sp, 6, blen, klen); 
        ref_test(path, 10000, cbc_me, alg, blen, klen);
        file_name(sp, 7, blen, klen); 
        ref_test(path, 10000, cbc_md, alg, blen, klen);
    }
}

#if defined(AES_DLL)

#include "windows.h"

HINSTANCE init_dll(fn_ptrs& fn)
{   HINSTANCE   h_dll;

    if(!(h_dll = LoadLibrary(dll_path)))
    {
        std::cout << "\n\nDynamic link Library AES_DLL not found\n\n"; return 0;
    }

    fn.fn_set_key = (f_ky*)GetProcAddress(h_dll, "_set_key@16");
    fn.fn_encrypt = (f_ed*)GetProcAddress(h_dll, "_encrypt@12");
    fn.fn_decrypt = (f_ed*)GetProcAddress(h_dll, "_decrypt@12");
    fn.fn_set_blk = (f_bl*)GetProcAddress(h_dll, "_set_blk@8");

#if !defined(BLOCK_SIZE)
    if(!fn.fn_set_key || !fn.fn_encrypt || !fn.fn_decrypt || !fn.fn_set_blk)
#else
    if(!fn.fn_set_key || !fn.fn_encrypt || !fn.fn_decrypt)
#endif
    {
        std::cout << "\n\nRequired DLL Entry Point(s) not found\n\n"; 
        FreeLibrary(h_dll); 
        return 0;
    }

    return h_dll;
}

#endif  // AES_DLL

int main(int argc, char *argv[])
{   bool        vkt, vktn, ecb, cbc, bf[5], kf[5];
    aes alg;

#if defined(AES_DLL)
    HINSTANCE   h_dll;

    if(!(h_dll = init_dll(fn))) return -1;
#endif

#if !defined(AES_IN_CPP)
    alg.mode = 0;
#endif

    if(argc == 1)
    {
        cout << "\nusage: aes_rav /t:[knec] /b:[45678] /k:[45678]";
        cout << "\n";
        cout << "\nwhere the symbols in square brackets can be used in";
        cout << "\nany combination (without the brackets) and have the";
		cout << "\nfollowing meanings:";
        cout << "\n";
        cout << "\n        /t:[knec]   selects which tests are used";
        cout << "\n        /b:[45678]  selects the block lengths used";
        cout << "\n        /k:[45678]  selects the key lengths used";
        cout << "\nwhere:";
        cout << "\n        k: generate ECB Known Answer Test files";
        cout << "\n        n: generate ECB Known Answer Test files (new)";
        cout << "\n        e: generate ECB Monte Carlo Test files";
        cout << "\n        c: generate CBC Monte Carlo Test files";
        cout << "\n";
        cout << "\nand the characters giving block and key lengths are";
        cout << "\ndigits representing the lengths in 32-bit units.\n\n";
        exit(0);
    }

    cout << "\nRun tests for the AES algorithm"
#if defined(AES_DLL)
     "(DLL Version)\n\n";
#else
    "\n\n";
#endif

    vkt  = test_args(argc, argv, 't', 'k');
    vktn = test_args(argc, argv, 't', 'n');
    ecb  = test_args(argc, argv, 't', 'e');
    cbc  = test_args(argc, argv, 't', 'c');

	kf[0] = test_args(argc, argv, 'k', '4');
	kf[1] = test_args(argc, argv, 'k', '5');
	kf[2] = test_args(argc, argv, 'k', '6');
	kf[3] = test_args(argc, argv, 'k', '7');
	kf[4] = test_args(argc, argv, 'k', '8');

	if(!(kf[0] || kf[1] || kf[2] || kf[3] || kf[4]))
	{
		kf[0] = kf[2] = kf[4] = true; 		// AES key sizes if not specified
		kf[1] = kf[3] = false;
	}

#if !defined(BLOCK_SIZE)
	bf[0] = test_args(argc, argv, 'b', '4');
	bf[1] = test_args(argc, argv, 'b', '5');
	bf[2] = test_args(argc, argv, 'b', '6');
	bf[3] = test_args(argc, argv, 'b', '7');
	bf[4] = test_args(argc, argv, 'b', '8');

	if(!(bf[0] || bf[1] || bf[2] || bf[3] || bf[4]))
	{
		bf[0] = true;					// AES block size if not specified
		bf[1] = bf[2] = bf[3] = bf[4] = false;
	}
#else
	bf[0] = bf[1] = bf[2] = bf[3] = bf[4] = false;
	bf[(BLOCK_SIZE - 16) / 4] = true;
#endif

	for(int bi = 0; bi < 5; ++bi) if(bf[bi])
	{

#if !defined(BLOCK_SIZE)
			f_set_blk(&alg, 16 + 4 * bi);
#elif defined(AES_DLL)
			if(fn.fn_set_blk) f_set_blk(&alg, BLOCK_SIZE);
#endif

		for(int ki = 0; ki < 5; ++ki) if(kf[ki])
		{
            do_tests(vkt, vktn, ecb, cbc, &alg, 16 + 4 * bi, 16 + 4 * ki);
		}
	}

#if defined(AES_DLL)
    if(h_dll) FreeLibrary(h_dll);
#endif

    cout << "\n\n";
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -