Implement profiler
This commit is contained in:
50
aes.cpp
50
aes.cpp
@@ -3,7 +3,9 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
const FiniteFieldCalculator AES::ffcalc(0x11b);
|
||||
#include "profiler.hpp"
|
||||
|
||||
const uint8_t AES::irreducible_polynomial = 0x1b;
|
||||
|
||||
const uint8_t AES::sbox[256] = {
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
@@ -56,6 +58,7 @@ const uint8_t AES::rc[10] = {
|
||||
|
||||
void AES::print_data(uint8_t data[16])
|
||||
{
|
||||
PROFILER_RECORD;
|
||||
for (int i = 0;i < 16;i++)
|
||||
{
|
||||
std::cout << std::hex << (int) data[i] << " ";
|
||||
@@ -65,6 +68,7 @@ void AES::print_data(uint8_t data[16])
|
||||
|
||||
void AES::encrypt_ecb(uint8_t data[16], const uint8_t key[16])
|
||||
{
|
||||
PROFILER_RECORD;
|
||||
uint8_t round_keys[11][16];
|
||||
construct_round_keys(key, round_keys);
|
||||
add_round_key(data, round_keys[0]);
|
||||
@@ -82,6 +86,7 @@ void AES::encrypt_ecb(uint8_t data[16], const uint8_t key[16])
|
||||
|
||||
void AES::add_round_key(uint8_t data_[16], const uint8_t key_[16])
|
||||
{
|
||||
PROFILER_RECORD;
|
||||
const uint32_t (&key)[4] = *reinterpret_cast<const uint32_t (*)[4]>(key_);
|
||||
uint32_t (&data)[4] = *reinterpret_cast<uint32_t (*)[4]>(data_);
|
||||
for (int i = 0;i < 4;i++)
|
||||
@@ -92,6 +97,7 @@ void AES::add_round_key(uint8_t data_[16], const uint8_t key_[16])
|
||||
|
||||
void AES::sub_bytes(uint8_t data[16])
|
||||
{
|
||||
PROFILER_RECORD;
|
||||
for (int i = 0;i < 16;i++)
|
||||
{
|
||||
data[i] = sbox[data[i]];
|
||||
@@ -102,6 +108,7 @@ void AES::sub_bytes(uint8_t data[16])
|
||||
|
||||
void AES::shift_rows(uint8_t data[16])
|
||||
{
|
||||
PROFILER_RECORD;
|
||||
uint8_t tmp = data[1];
|
||||
data[1] = data[5];
|
||||
data[5] = data[9];
|
||||
@@ -122,19 +129,21 @@ void AES::shift_rows(uint8_t data[16])
|
||||
|
||||
void AES::mix_columns(uint8_t data[16])
|
||||
{
|
||||
PROFILER_RECORD;
|
||||
uint8_t data_new[16];
|
||||
for (int i = 0;i < 4;i++)
|
||||
{
|
||||
data_new[i * 4 + 0] = ffcalc.mult2(data[i * 4 + 0]) ^ ffcalc.mult3(data[i * 4 + 1]) ^ data[i * 4 + 2] ^ data[i * 4 + 3];
|
||||
data_new[i * 4 + 1] = data[i * 4 + 0] ^ ffcalc.mult2(data[i * 4 + 1]) ^ ffcalc.mult3(data[i * 4 + 2]) ^ data[i * 4 + 3];
|
||||
data_new[i * 4 + 2] = data[i * 4 + 0] ^ data[i * 4 + 1] ^ ffcalc.mult2(data[i * 4 + 2]) ^ ffcalc.mult3(data[i * 4 + 3]);
|
||||
data_new[i * 4 + 3] = ffcalc.mult3(data[i * 4 + 0]) ^ data[i * 4 + 1] ^ data[i * 4 + 2] ^ ffcalc.mult2(data[i * 4 + 3]);
|
||||
data_new[i * 4 + 0] = gf_mult2(data[i * 4 + 0]) ^ gf_mult3(data[i * 4 + 1]) ^ data[i * 4 + 2] ^ data[i * 4 + 3];
|
||||
data_new[i * 4 + 1] = data[i * 4 + 0] ^ gf_mult2(data[i * 4 + 1]) ^ gf_mult3(data[i * 4 + 2]) ^ data[i * 4 + 3];
|
||||
data_new[i * 4 + 2] = data[i * 4 + 0] ^ data[i * 4 + 1] ^ gf_mult2(data[i * 4 + 2]) ^ gf_mult3(data[i * 4 + 3]);
|
||||
data_new[i * 4 + 3] = gf_mult3(data[i * 4 + 0]) ^ data[i * 4 + 1] ^ data[i * 4 + 2] ^ gf_mult2(data[i * 4 + 3]);
|
||||
}
|
||||
memcpy(data, data_new, 16);
|
||||
}
|
||||
|
||||
void AES::construct_round_keys(const uint8_t initial_key_[16], uint8_t round_keys_[11][16])
|
||||
{
|
||||
PROFILER_RECORD;
|
||||
const uint32_t (&initial_key)[4] = *reinterpret_cast<const uint32_t (*)[4]>(initial_key_);
|
||||
uint32_t (&round_keys)[11][4] = *reinterpret_cast<uint32_t (*)[11][4]>(round_keys_);
|
||||
for (int k = 0;k < 4;k++)
|
||||
@@ -152,6 +161,7 @@ void AES::construct_round_keys(const uint8_t initial_key_[16], uint8_t round_key
|
||||
|
||||
uint32_t AES::roundkey_g(uint32_t last_roundkey, uint8_t round)
|
||||
{
|
||||
PROFILER_RECORD;
|
||||
uint32_t result;
|
||||
uint8_t *last = (uint8_t*) &last_roundkey;
|
||||
uint8_t *next = (uint8_t*) &result;
|
||||
@@ -162,24 +172,15 @@ uint32_t AES::roundkey_g(uint32_t last_roundkey, uint8_t round)
|
||||
return result;
|
||||
}
|
||||
|
||||
FiniteFieldCalculator::FiniteFieldCalculator(uint16_t irreducible_polynomial)
|
||||
: irreducible_polynomial(irreducible_polynomial)
|
||||
uint8_t AES::gf_reduce(uint8_t value)
|
||||
{
|
||||
// Nothing to do
|
||||
PROFILER_RECORD;
|
||||
return value ^ irreducible_polynomial;
|
||||
}
|
||||
|
||||
uint16_t FiniteFieldCalculator::get_irreducible_polynomial() const
|
||||
{
|
||||
return irreducible_polynomial;
|
||||
}
|
||||
|
||||
uint8_t FiniteFieldCalculator::reduce(uint16_t value) const
|
||||
{
|
||||
return (uint8_t) add(value, get_irreducible_polynomial());
|
||||
}
|
||||
|
||||
uint8_t FiniteFieldCalculator::mult2(uint8_t value) const
|
||||
uint8_t AES::gf_mult2(uint8_t value)
|
||||
{
|
||||
PROFILER_RECORD;
|
||||
uint16_t result = ((uint16_t) value) << 1;
|
||||
if ((result & 0x100) == 0)
|
||||
{
|
||||
@@ -187,14 +188,13 @@ uint8_t FiniteFieldCalculator::mult2(uint8_t value) const
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0;i < 50;i++)
|
||||
;
|
||||
return reduce(result);
|
||||
return gf_reduce(result);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t FiniteFieldCalculator::mult3(uint8_t value) const
|
||||
uint8_t AES::gf_mult3(uint8_t value)
|
||||
{
|
||||
uint8_t result = mult2(value);
|
||||
return add(result, value);
|
||||
PROFILER_RECORD;
|
||||
uint8_t result = gf_mult2(value);
|
||||
return result ^ value;
|
||||
}
|
||||
|
||||
21
aes.hpp
21
aes.hpp
@@ -3,29 +3,13 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class FiniteFieldCalculator
|
||||
{
|
||||
private:
|
||||
uint16_t irreducible_polynomial;
|
||||
public:
|
||||
FiniteFieldCalculator(uint16_t irreducible_polynomial);
|
||||
template <typename T>
|
||||
T add(T a, T b) const {
|
||||
return a ^ b;
|
||||
}
|
||||
uint8_t mult2(uint8_t value) const;
|
||||
uint8_t mult3(uint8_t value) const;
|
||||
uint8_t reduce(uint16_t value) const;
|
||||
uint16_t get_irreducible_polynomial() const;
|
||||
};
|
||||
|
||||
class AES
|
||||
{
|
||||
private:
|
||||
static const uint8_t sbox[256];
|
||||
static const uint8_t rsbox[256];
|
||||
static const uint8_t rc[10];
|
||||
static const FiniteFieldCalculator ffcalc;
|
||||
static const uint8_t irreducible_polynomial;
|
||||
public:
|
||||
AES();
|
||||
static void encrypt_ecb(uint8_t data[16], const uint8_t key[16]);
|
||||
@@ -36,6 +20,9 @@ public:
|
||||
static void sub_bytes(uint8_t data[16]);
|
||||
static void mix_columns(uint8_t data[16]);
|
||||
static void print_data(uint8_t data[16]);
|
||||
static uint8_t gf_mult2(uint8_t value);
|
||||
static uint8_t gf_mult3(uint8_t value);
|
||||
static uint8_t gf_reduce(uint8_t value);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
10
main.cpp
10
main.cpp
@@ -6,6 +6,8 @@
|
||||
#include <thread>
|
||||
#include <cstring>
|
||||
|
||||
#include "profiler.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
|
||||
@@ -13,18 +15,16 @@ int main(int argc, char **argv) {
|
||||
uint8_t data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
const uint8_t key[16] = {0xA0,0x7C,0x3D,0x99,0xFA,0x00,0x02,0x46,0x97,0x33,0x73,0x50,0x31,0x7C,0xD3,0xDC};
|
||||
ifstream input("/dev/urandom", ios::binary);
|
||||
for (int i = 0;i < 50000;i++)
|
||||
for (int i = 0;i < 5000;i++)
|
||||
{
|
||||
input.read((char*) data, 16);
|
||||
this_thread::sleep_for(nanoseconds(0));
|
||||
for (int d = 0;d < 16;d++)
|
||||
{
|
||||
cout << dec << (int) data[d] << ",";
|
||||
}
|
||||
auto start = high_resolution_clock::now();
|
||||
AES::encrypt_ecb(data, key);
|
||||
auto stop = high_resolution_clock::now();
|
||||
cout << (stop - start).count() << endl;
|
||||
cout << profiler.calls["gf_reduce"] << endl;
|
||||
profiler.clear();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ using std::string;
|
||||
|
||||
Profiler profiler;
|
||||
|
||||
void Profiler::record_function_call(char *function_name)
|
||||
void Profiler::record_function_call(const char *function_name)
|
||||
{
|
||||
calls[function_name]++;
|
||||
}
|
||||
|
||||
@@ -8,12 +8,11 @@ class Profiler
|
||||
{
|
||||
public:
|
||||
std::map<std::string, uint32_t> calls;
|
||||
void record_function_call(char *function_name);
|
||||
void record_function_call(const char *function_name);
|
||||
void clear();
|
||||
};
|
||||
|
||||
//#define PROFILER_RECORD profiler.record_function_call((char*) __func__)
|
||||
#define PROFILER_RECORD
|
||||
#define PROFILER_RECORD profiler.record_function_call(__func__)
|
||||
|
||||
extern Profiler profiler;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user