From 702c37656f2c36764af90f6402089fb42f7a8f6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Tue, 14 May 2019 15:03:14 +0200 Subject: [PATCH] Implement profiler --- aes.cpp | 50 +++++++++++++++++++++++++------------------------- aes.hpp | 21 ++++----------------- main.cpp | 10 +++++----- profiler.cpp | 2 +- profiler.hpp | 5 ++--- 5 files changed, 37 insertions(+), 51 deletions(-) diff --git a/aes.cpp b/aes.cpp index 7442c58..d7e327b 100644 --- a/aes.cpp +++ b/aes.cpp @@ -3,7 +3,9 @@ #include #include -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(key_); uint32_t (&data)[4] = *reinterpret_cast(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(initial_key_); uint32_t (&round_keys)[11][4] = *reinterpret_cast(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; } diff --git a/aes.hpp b/aes.hpp index a900f11..b6040ec 100644 --- a/aes.hpp +++ b/aes.hpp @@ -3,29 +3,13 @@ #include -class FiniteFieldCalculator -{ -private: - uint16_t irreducible_polynomial; -public: - FiniteFieldCalculator(uint16_t irreducible_polynomial); - template - 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 diff --git a/main.cpp b/main.cpp index f1a05b9..155c43f 100644 --- a/main.cpp +++ b/main.cpp @@ -6,6 +6,8 @@ #include #include +#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; } diff --git a/profiler.cpp b/profiler.cpp index 8da3ca3..33409e7 100644 --- a/profiler.cpp +++ b/profiler.cpp @@ -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]++; } diff --git a/profiler.hpp b/profiler.hpp index 480b718..20b4c8b 100644 --- a/profiler.hpp +++ b/profiler.hpp @@ -8,12 +8,11 @@ class Profiler { public: std::map 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;