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

📄 aes_gav.c

📁 文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2, MD4, MD5, RIPEMD-128, RIPEMD-160, SHA-1, SHA-224, SHA-256,
💻 C
📖 第 1 页 / 共 2 页
字号:

// 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                               .   25th January 2000.

// 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 /a:[12345] /t:[kec] [/c] [/h]
// where:
//         /a:[12345] algorithms to be tested
//         /t:[kec]   type of test
//         /c         compare output and reference file(s)
//         /h         use author's byte order (serpent)
// and:
//         1:mars, 2:rc6, 3:rijndael, 4:serpent, 5:twofish
//         k: generate ECB Known Answer Test files
//         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).

#ifdef  __cplusplus
#   include <iostream>
#   include <fstream>
#else
#   include <stdio.h>
#endif

#include "aes_config.h"
#include "aes_defs.h"
#include "aes_aux.h"
#include "mars.h"
#include "rc6.h"
#include "rijndael.h"
#include "serpent.h"
#include "twofish.h"

#if KEEP_USER_HAPPY
#   define  OUT_DOTS(x)     \
    {                       \
        if(!(x % 40))       \
            con_char('\n'); \
        con_char('.');      \
    }
#else
#   define  OUT_DOTS(x)
#endif

// Serpent hack to get test agreement because the test vectors for this
// algorithm assemble the key vectors in the reverse direction in memory

bool    serpent_hack = false;

// Outputs a test vector file header

void header(OFREF outf, int type, char alg_name[])
{
    put_string(outf, "=======================================================");
    put_string(outf, "\nAuthor:    Dr B R Gladman (                           )");
    put_string(outf, "\nTest:      "); put_string(outf, type < 4 ? "ECB " : "CBC ");
    switch(type)
    {
        case  0:    put_string(outf, "Variable Key Known Answer Tests"); break;
        case  1:    put_string(outf, "Variable Text Known Answer Tests"); break;
        case  2:
        case  4:    put_string(outf, "Monte Carlo (Encryption) Tests"); break;
        case  3:
        case  5:    put_string(outf, "Monte Carlo (Decryption) Tests"); break;
    }

    put_string(outf, "\nAlgorithm: "); put_string(outf, alg_name);
    put_string(outf, "\nFilename:  "); put_string(outf, type < 4 ? "ecb_" : "cbc_");
    switch(type)
    {
        case  0:    put_string(outf, "vk.txt\n"); break;
        case  1:    put_string(outf, "vt.txt\n"); break;
        case  2:
        case  4:    put_string(outf, "e_m.txt\n"); break;
        case  3:
        case  5:    put_string(outf, "d_m.txt\n"); break;
    }
    put_string(outf, "=======================================================");
}

// Test of Electronic Code Book (ECB) Mode with Fixed Key and Variable Text

void ecb_vt(OFREF outf, AESREF alg)
{   u4byte      i, j;
    u1byte      pt[16], ct[16], key[32], dummy;

    block_clear(key, 32);   // all zero key

    for(i = 0; i < 3; ++i)  // key lengthes 128, 192 and 256
    {
        block_out(0, &dummy, outf, 128 + 64 * i);   // output key length;

        put_char(outf, '\n');

        block_out(3, key, outf, 16 + 8 * i);    // output key value

        alg.set_key(key, 128 + 64 * i, both);   // set key value

        for(j = 0; j <= 128; ++j)               // 129 test vectors including
        {                                       // an all zero one
            block_out(1, &dummy, outf, j);      // output test number
            block_clear(pt, 16);                // set all zero plain text

            if(j)                               // set bit (j-1) if j <> 0

                *(pt + (j - 1) / 8) = 0x80 >> (j - 1) % 8;

            block_out(4, pt, outf, 16);         // output plaintext

            if(serpent_hack)                    // reverse plaintext
                                                // block for Serpent
                block_reverse(pt, 16);

            alg.encrypt(pt , ct);               // do encryption

            if(serpent_hack)                    // reverse ciphertext
                                                // block for Serpent
                block_reverse(ct, 16);

            block_out(5, ct, outf, 16);         // output ciphertext
        }
    }
}

// Test of Electronic Code Book (ECB) Mode with Fixed Text and Variable Key

void ecb_vk(OFREF outf, AESREF alg)
{   u4byte      i, j;
    u1byte      pt[16], ct[16], key[32], dummy;

    block_clear(pt, 16);    // all zero plaintext

    for(i = 0; i < 3; ++i)  // key lengths of 128, 192 and 256 bits
    {
        block_out(0, &dummy, outf, 128 + 64 * i);   // output key length;

        put_char(outf, '\n');

        block_out(4, pt, outf, 16);         // output plaintext

        for(j = 0; j <= 128 + 64 * i; ++j)  // 129, 193 or 257 tests
        {
            block_out(1, &dummy, outf, j);  // output test number
            block_clear(key, 32);

            if(j)                           // set bit (j-1) if j <> 0

                *(key + (j - 1) / 8) = 0x80 >> (j - 1) % 8;

            block_out(3, key, outf, 16 + 8 * i);    // output key value

            if(serpent_hack)                // reverse key block for Serpent

                block_reverse(key, 16 + 8 * i);

            alg.set_key(key, 128 + 64 * i, enc);    // set key value
            alg.encrypt(pt , ct);                   // alg.encrypt

            if(serpent_hack)                // reverse ciphertext for Serpent

                block_reverse(ct, 16);

            block_out(5, ct, outf, 16);     // output ciphertext
        }
    }
}

// Monte Carlo Encryption Test of Electronic Code Book (ECB) Mode

void ecb_me(OFREF outf, AESREF alg)
{   u4byte  i, j, k;
    u1byte  pt[16], ct[32], key[32], dummy;

    for(i = 0; i < 3; ++i)  // key lengths of 128, 192 and 256 bits
    {
        block_out(0, &dummy, outf, 128 + 64 * i);   // output key length;

        block_clear(pt, 16); block_clear(key, 32);  // clear initial plaintext
                                                    // and key blocks
        block_copy(ct + 16, pt, 16);                // put plaintext in upper half
                                                    // of double length buffer
        for(j = 0; j < 400; j++)                    // 400 Monte Carlo tests
        {
            OUT_DOTS(j);

            block_out(1, &dummy, outf, j);      // output test number
            block_out(3, key, outf, 16 + 8 * i);// output key
            block_out(4, pt, outf, 16);         // output plaintext

            if(serpent_hack)    // reverse both input blocks for Serpent
            {
                block_reverse(key, 16 + 8 * i); block_reverse(ct + 16, 16);
            }

            alg.set_key(key, 128 + 64 * i, enc);    // set the key

            for(k = 0; k < 5000; ++k)       // 10000 encryptions alternating
            {                               // upper and lower blocks in ct
                alg.encrypt(ct + 16, ct); alg.encrypt(ct, ct + 16);
            }

            // compile next key as defined by NIST

            block_xor(key, ct + 16 - 8 * i, 16 + 8 * i);

            if(serpent_hack)    // put blocks in normal mode for Serpent
            {
                block_reverse(key, 16 + 8 * i); block_reverse(ct + 16, 16);
            }

            block_out(5, ct + 16, outf, 16);    // output ciphertext
            block_copy(pt, ct + 16, 16);        // copy cipertext as next plaintext
        }
    }
}

// Monte Carlo Decryption Test of Electronic Code Book (ECB) Mode

void ecb_md(OFREF outf, AESREF alg)
{   u4byte  i, j, k;
    u1byte  pt[16], ct[32], key[32], dummy;

    for(i = 0; i < 3; ++i)  // key lengths 128, 192 and 256 bits
    {
        block_out(0, &dummy, outf, 128 + 64 * i);   // output key length;

        block_clear(pt, 16);            // clear initial plaintext and key
        block_clear(key, 32);
        block_copy(ct + 16, pt, 16);    // copy plaintext into upper half
                                        // of double length ciphertext block
        for(j = 0; j < 400; j++)        // 400 Monte Carlo tests
        {
            OUT_DOTS(j);

            block_out(1, &dummy, outf, j);          // output test number
            block_out(3, key, outf, 16 + 8 * i);    // output key
            block_out(5, pt, outf, 16);             // output plaintext

            if(serpent_hack)            // reverse input blocks for Serpent
            {
                block_reverse(key, 16 + 8 * i); block_reverse(ct + 16, 16);
            }

            alg.set_key(key, 128 + 64 * i, dec);    // set key

            for(k = 0; k < 5000; ++k)   // 10000 decryptions alternating
            {                           // upper and lower blocks in ct
                alg.decrypt(ct + 16, ct); alg.decrypt(ct, ct + 16);
            }

            // compile next key as defined by NIST

            block_xor(key, ct + 16 - 8 * i, 16 + 8 * i);

            if(serpent_hack)    // put blocks in normal mode for Serpent
            {
                block_reverse(key, 16 + 8 * i); block_reverse(ct + 16, 16);
            }

            block_out(4, ct + 16, outf, 16);    // output ciphertext
            block_copy(pt, ct + 16, 16);        // set ciphertext as next plaintext
        }
    }
}

// Monte Carlo Encryption Test of Cipher Block Chaining (CBC) Mode

void cbc_me(OFREF outf, AESREF alg)
{   u4byte  i, j, k;
    u1byte  ct[32], key[32], dummy;

    for(i = 0; i < 3; ++i)  // key lengths 128, 192 and 256 bits
    {
        block_out(0, &dummy, outf, 128 + 64 * i);   // output key length;

        block_clear(key, 32);   // clear key: KEY[0]
        block_clear(ct, 32);    // clear ct:  PT[0], ct + 16: IV[0]

        for(j = 0; j < 400; j++)            // 400 Monte Carlo tests
        {
            OUT_DOTS(j);

            block_out(1, &dummy, outf, j);      // output test number
            block_out(3, key, outf, 16 + 8 * i);// output key
            block_out(2, ct + 16, outf, 16);    // output initialisation vector
            block_out(4, ct, outf, 16);         // output plaintext

            if(serpent_hack)            // reverse key block if Serpent
            {
                block_reverse(key, 16 + 8 * i);
            }

            alg.set_key(key, 128 + 64 * i, enc);    // set key

            for(k = 0; k < 5000; ++k)       // 10000 encryptions, two at a time
            {
                block_xor(ct, ct + 16, 16); // do CBC chaining

                if(serpent_hack)            // reverse input block for Serpent
                {
                    block_reverse(ct, 16);
                }

                alg.encrypt(ct, ct);        // do block encryption

                if(serpent_hack)            // reverse output block for Serpent
                {
                    block_reverse(ct, 16);
                }

                block_xor(ct + 16, ct, 16); // do CBC chaining

                if(serpent_hack)            // reverse input block for Serpent
                {
                    block_reverse(ct + 16, 16);
                }

                alg.encrypt(ct + 16, ct + 16);  // do block encryption

                if(serpent_hack)        // reverse output block for Serpent
                {
                    block_reverse(ct + 16, 16);
                }
            }

            block_out(5, ct + 16, outf, 16);    // output ciphertext

            if(serpent_hack)                    // reverse blocks for Serpent
            {
                block_reverse(ct, 16); block_reverse(ct + 16, 16);
            }

            // compile next key as defined by NIST

            block_xor(key, ct + 16 - 8 * i, 16 + 8 * i);

            if(serpent_hack)    // put blocks in normal order for Serpent
            {
                block_reverse(key, 16 + 8 * i);
                block_reverse(ct, 16); block_reverse(ct + 16, 16);
            }
        }
    }
}

// Monte Carlo Encryption Test of Cipher Block Chaining (CBC) Mode

void cbc_md(OFREF outf, AESREF alg)
{   u4byte  i, j, k;
    u1byte  pt[16], ct[32], key[32], dummy;

    for(i = 0; i < 3; ++i)  // key lengths 128, 192 and 256 bits
    {

⌨️ 快捷键说明

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