Implement profiler

This commit is contained in:
2019-05-14 15:03:14 +02:00
parent 3887b041f6
commit 702c37656f
5 changed files with 37 additions and 51 deletions

50
aes.cpp
View File

@@ -3,7 +3,9 @@
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
const FiniteFieldCalculator AES::ffcalc(0x11b); #include "profiler.hpp"
const uint8_t AES::irreducible_polynomial = 0x1b;
const uint8_t AES::sbox[256] = { const uint8_t AES::sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 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]) void AES::print_data(uint8_t data[16])
{ {
PROFILER_RECORD;
for (int i = 0;i < 16;i++) for (int i = 0;i < 16;i++)
{ {
std::cout << std::hex << (int) data[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]) void AES::encrypt_ecb(uint8_t data[16], const uint8_t key[16])
{ {
PROFILER_RECORD;
uint8_t round_keys[11][16]; uint8_t round_keys[11][16];
construct_round_keys(key, round_keys); construct_round_keys(key, round_keys);
add_round_key(data, round_keys[0]); 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]) 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_); const uint32_t (&key)[4] = *reinterpret_cast<const uint32_t (*)[4]>(key_);
uint32_t (&data)[4] = *reinterpret_cast<uint32_t (*)[4]>(data_); uint32_t (&data)[4] = *reinterpret_cast<uint32_t (*)[4]>(data_);
for (int i = 0;i < 4;i++) 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]) void AES::sub_bytes(uint8_t data[16])
{ {
PROFILER_RECORD;
for (int i = 0;i < 16;i++) for (int i = 0;i < 16;i++)
{ {
data[i] = sbox[data[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]) void AES::shift_rows(uint8_t data[16])
{ {
PROFILER_RECORD;
uint8_t tmp = data[1]; uint8_t tmp = data[1];
data[1] = data[5]; data[1] = data[5];
data[5] = data[9]; data[5] = data[9];
@@ -122,19 +129,21 @@ void AES::shift_rows(uint8_t data[16])
void AES::mix_columns(uint8_t data[16]) void AES::mix_columns(uint8_t data[16])
{ {
PROFILER_RECORD;
uint8_t data_new[16]; uint8_t data_new[16];
for (int i = 0;i < 4;i++) 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 + 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] ^ ffcalc.mult2(data[i * 4 + 1]) ^ ffcalc.mult3(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] ^ ffcalc.mult2(data[i * 4 + 2]) ^ ffcalc.mult3(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] = ffcalc.mult3(data[i * 4 + 0]) ^ data[i * 4 + 1] ^ data[i * 4 + 2] ^ ffcalc.mult2(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); memcpy(data, data_new, 16);
} }
void AES::construct_round_keys(const uint8_t initial_key_[16], uint8_t round_keys_[11][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_); 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_); uint32_t (&round_keys)[11][4] = *reinterpret_cast<uint32_t (*)[11][4]>(round_keys_);
for (int k = 0;k < 4;k++) 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) uint32_t AES::roundkey_g(uint32_t last_roundkey, uint8_t round)
{ {
PROFILER_RECORD;
uint32_t result; uint32_t result;
uint8_t *last = (uint8_t*) &last_roundkey; uint8_t *last = (uint8_t*) &last_roundkey;
uint8_t *next = (uint8_t*) &result; uint8_t *next = (uint8_t*) &result;
@@ -162,24 +172,15 @@ uint32_t AES::roundkey_g(uint32_t last_roundkey, uint8_t round)
return result; return result;
} }
FiniteFieldCalculator::FiniteFieldCalculator(uint16_t irreducible_polynomial) uint8_t AES::gf_reduce(uint8_t value)
: irreducible_polynomial(irreducible_polynomial)
{ {
// Nothing to do PROFILER_RECORD;
return value ^ irreducible_polynomial;
} }
uint16_t FiniteFieldCalculator::get_irreducible_polynomial() const uint8_t AES::gf_mult2(uint8_t value)
{
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
{ {
PROFILER_RECORD;
uint16_t result = ((uint16_t) value) << 1; uint16_t result = ((uint16_t) value) << 1;
if ((result & 0x100) == 0) if ((result & 0x100) == 0)
{ {
@@ -187,14 +188,13 @@ uint8_t FiniteFieldCalculator::mult2(uint8_t value) const
} }
else else
{ {
for (int i = 0;i < 50;i++) return gf_reduce(result);
;
return reduce(result);
} }
} }
uint8_t FiniteFieldCalculator::mult3(uint8_t value) const uint8_t AES::gf_mult3(uint8_t value)
{ {
uint8_t result = mult2(value); PROFILER_RECORD;
return add(result, value); uint8_t result = gf_mult2(value);
return result ^ value;
} }

21
aes.hpp
View File

@@ -3,29 +3,13 @@
#include <cstdint> #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 class AES
{ {
private: private:
static const uint8_t sbox[256]; static const uint8_t sbox[256];
static const uint8_t rsbox[256]; static const uint8_t rsbox[256];
static const uint8_t rc[10]; static const uint8_t rc[10];
static const FiniteFieldCalculator ffcalc; static const uint8_t irreducible_polynomial;
public: public:
AES(); AES();
static void encrypt_ecb(uint8_t data[16], const uint8_t key[16]); 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 sub_bytes(uint8_t data[16]);
static void mix_columns(uint8_t data[16]); static void mix_columns(uint8_t data[16]);
static void print_data(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 #endif

View File

@@ -6,6 +6,8 @@
#include <thread> #include <thread>
#include <cstring> #include <cstring>
#include "profiler.hpp"
using namespace std; using namespace std;
using namespace std::chrono; 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}; 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}; 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); 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); input.read((char*) data, 16);
this_thread::sleep_for(nanoseconds(0));
for (int d = 0;d < 16;d++) for (int d = 0;d < 16;d++)
{ {
cout << dec << (int) data[d] << ","; cout << dec << (int) data[d] << ",";
} }
auto start = high_resolution_clock::now();
AES::encrypt_ecb(data, key); AES::encrypt_ecb(data, key);
auto stop = high_resolution_clock::now(); cout << profiler.calls["gf_reduce"] << endl;
cout << (stop - start).count() << endl; profiler.clear();
} }
return 0; return 0;
} }

View File

@@ -4,7 +4,7 @@ using std::string;
Profiler profiler; Profiler profiler;
void Profiler::record_function_call(char *function_name) void Profiler::record_function_call(const char *function_name)
{ {
calls[function_name]++; calls[function_name]++;
} }

View File

@@ -8,12 +8,11 @@ class Profiler
{ {
public: public:
std::map<std::string, uint32_t> calls; std::map<std::string, uint32_t> calls;
void record_function_call(char *function_name); void record_function_call(const char *function_name);
void clear(); void clear();
}; };
//#define PROFILER_RECORD profiler.record_function_call((char*) __func__) #define PROFILER_RECORD profiler.record_function_call(__func__)
#define PROFILER_RECORD
extern Profiler profiler; extern Profiler profiler;