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

📄 aestmr.cpp

📁 escription: The Rijndael Encryption algorithm has been recently recognized as an AES (Advanced Encry
💻 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.
//
// Measure the Encryption, Decryption and Key Setup Times for AES using
// the Pentium Time Stamp Counter

#include <iostream>
#include <fstream>

#include "aes.h"
#include "aesaux.h"
#include "aestst.h"

// Use this define if testing aespp.c

//#define AESX

#if defined(AES_DLL)
fn_ptrs fn;
#endif

#define  PROCESSOR   "PIII"  // Processor

void cycles(unsigned __int64 *rtn)    
{                           // read the Pentium Time Stamp Counter
    __asm
    {
    _emit   0x0f            // complete pending operations
    _emit   0xa2
    _emit   0x0f            // read time stamp counter
    _emit   0x31
    mov     ebx,rtn
    mov     [ebx],eax
    mov     [ebx+4],edx
    _emit   0x0f            // complete pending operations
    _emit   0xa2
    }
}

const unsigned int loops = 100; // number of timing loops

word rand32(void)
{   static word   r4,r_cnt = -1,w = 521288629,z = 362436069;

    z = 36969 * (z & 65535) + (z >> 16);
    w = 18000 * (w & 65535) + (w >> 16);

    r_cnt = 0; r4 = (z << 16) + w; return r4;
}

byte rand8(void)
{   static word   r4,r_cnt = 4;

    if(r_cnt == 4)
    {
        r4 = byte_swap(rand32()); r_cnt = 0;
    }

    return (char)(r4 >> (8 * r_cnt++));
}

// fill a block with random charactrers

void block_rndfill(byte l[], word len)
{   word  i;

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

        l[i] = rand8();
}

// measure cycles for an encryption call

word e_cycles(const word klen, aes* alg)
{   byte  pt[16], ct[16], key[32];
    word  i, c1, c2;
    unsigned __int64 cy0, cy1, cy2;

    // set up a random key of 256 bits

    block_rndfill(key, 32);

    // set up a random plain text

    block_rndfill(pt, 16);

    // do a set_key in case it is necessary

    f_set_key(alg, key, klen, both); c1 = c2 = 0xffffffff;

    // do an encrypt to remove any 'first time through' effects

    f_encrypt(alg, pt, ct);

    for(i = 0; i < loops; ++i)
    {
        block_rndfill(pt, 16);

        // time one and two encryptions

        cycles(&cy0);
        f_encrypt(alg, pt, ct);
        cycles(&cy1);
        f_encrypt(alg, pt, ct);
        f_encrypt(alg, pt, ct);
        cycles(&cy2);

        cy2 -= cy1; cy1 -= cy0;     // time for one and two calls

        c1 = (c1 > cy1 ? cy1 : c1); // find minimum values over the loops

        c2 = (c2 > cy2 ? cy2 : c2);
    }

    return c2 - c1; // return one call timing
}

// measure cycles for a decryption call

word d_cycles(const word klen, aes* alg)
{   byte  pt[16], ct[16], key[32];
    word  i, c1, c2;
    unsigned __int64 cy0, cy1, cy2;

    // set up a random key of 256 bits

    block_rndfill(key, 32);

    // set up a random plain text

    block_rndfill(pt, 16);

    // do a set_key in case it is necessary

    f_set_key(alg, key, klen, both); c1 = c2 = 0xffffffff;

    // do an decrypt to remove any 'first time through' effects

    f_decrypt(alg, pt, ct);

    for(i = 0; i < loops; ++i)
    {
        block_rndfill(pt, 16);

        // time one and two encryptions

        cycles(&cy0);
        f_decrypt(alg, pt, ct);
        cycles(&cy1);
        f_decrypt(alg, pt, ct);
        f_decrypt(alg, pt, ct);
        cycles(&cy2);

        cy2 -= cy1; cy1 -= cy0;     // time for one and two calls

        c1 = (c1 > cy1 ? cy1 : c1); // find minimum values over the loops

        c2 = (c2 > cy2 ? cy2 : c2);
    }

    return c2 - c1; // return one call timing
}

// measure cycles for a key setup

word k_cycles(const word klen, aes* alg, const enum aes_key f)
{   byte  key[32];
    word  i, c1, c2;
    unsigned __int64 cy0, cy1, cy2;

    // set up a random key of 256 bits

    block_rndfill(key, 32);

    // do an set_key to remove any 'first time through' effects

    f_set_key(alg, key, klen, f); c1 = c2 = 0xffffffff;

    for(i = 0; i < loops; ++i)
    {
        block_rndfill(key, 32);

        // time one and two encryptions

        cycles(&cy0);
        f_set_key(alg, key, klen, f);
        cycles(&cy1);
        f_set_key(alg, key, klen, f);
        f_set_key(alg, key, klen, f);
        cycles(&cy2);

        cy2 -= cy1; cy1 -= cy0;     // time for one and two calls

        c1 = (c1 > cy1 ? cy1 : c1); // find minimum values over the loops

        c2 = (c2 > cy2 ? cy2 : c2);
    }

    return c2 - c1; // return one call timing
}

static word kl[5] = { 16, 20, 24, 28, 32 };
static word ekt[5], dkt[5], et[5], dt[5];

void output(std::ofstream& outf, const inx, const word bits)
{   word  t;
    byte  c0, c1, c2;

    outf << "\n// " << 8 * kl[inx] << " Bit:";
    outf << "   Key Setup: " << ekt[inx] << '/' << dkt[inx] << " cycles";
    t = (1000 * bits + et[inx] / 2) / et[inx]; 
    c0 = '0' + t / 100; c1 = '0' + (t / 10) % 10; c2 = '0' + t % 10;
    outf << "\n// Encrypt:   " << et[inx] << " cycles = 0."
         << c0 << c1 << c2 << " bits/cycle"; 
    t = (1000 * bits + et[inx] / 2) / dt[inx]; 
    c0 = '0' + t / 100; c1 = '0' + (t / 10) % 10; c2 = '0' + t % 10;
    outf << "\n// Decrypt:   " << dt[inx] << " cycles = 0."
         << c0 << c1 << c2 << " bits/cycle"; 
}

#if defined(AESX)
#define INC 1
#else
#define INC 2
#endif

#if BLOCK_SIZE == 16
#define STR 0
#define CNT 1
#elif BLOCK_SIZE == 20
#define STR 1
#define CNT 2
#elif BLOCK_SIZE == 24
#define STR 2
#define CNT 3
#elif BLOCK_SIZE == 28
#define STR 3
#define CNT 4
#elif BLOCK_SIZE == 32
#define STR 4
#define CNT 5
#elif !defined(BLOCK_SIZE)
#define STR 0
#define CNT 5
#else
#error Illegal block size
#endif

#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[])
{   std::ofstream   outf;
    aes             alg;
#if defined(REPORT_SPACE)
    word            lc, lt;
    char            fn[16];

    length(&lc, &lt, fn);
#endif


#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 defined(REPORT_SPACE)
    outf.open(fn, std::ios_base::out);
#else
    outf.open(argc == 2 ? argv[1] : "CON", std::ios_base::out);
#endif

    outf << "\n// AES"
#if defined(AES_DLL)
        " (DLL)"
#endif
    " on " << PROCESSOR << " processor";

#if defined(REPORT_SPACE)
    outf << "\n// " << fn << " (code " << lc << ", tables " << lt << ')';
#endif
    for(int i = STR; i < CNT; i += INC)
    {
#if !defined(BLOCK_SIZE)
        f_set_blk(&alg, 16 + 4 * i);
#elif defined(AES_DLL)
        if(fn.fn_set_blk) f_set_blk(&alg, BLOCK_SIZE);
#endif
        for(word j = 0; j < 5; j += INC)
        {
            ekt[j] = k_cycles(kl[j], &alg, enc);
            dkt[j] = k_cycles(kl[j], &alg, dec);
            et[j] = e_cycles(kl[j], &alg);
            dt[j] = d_cycles(kl[j], &alg);
        }
    
        outf << "\n// Block Length: " << 128 + 32 * i;
        for(word k = 0; k < 5; k += INC)
            output(outf, k, 128 + 32 * i); 
    }
#if defined(AES_DLL)
    if(h_dll) FreeLibrary(h_dll);
#endif

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

⌨️ 快捷键说明

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