Skip to content

Instantly share code, notes, and snippets.

@ranisalt
Last active September 20, 2020 16:23
Show Gist options
  • Save ranisalt/5fee620769584e3a46f69b7913f83050 to your computer and use it in GitHub Desktop.
Save ranisalt/5fee620769584e3a46f69b7913f83050 to your computer and use it in GitHub Desktop.
SIMD vectorized XTEA
#include "xtea.h"
#include <algorithm>
#include <array>
#include <cassert>
#include <chrono>
#include <iostream>
constexpr auto VECTOR_SIZE = 24584u;
// 48*64bytes + 3*16bytes + 3*4bytes + 3bytes, worst size possible
//constexpr auto VECTOR_SIZE = 25080u;
constexpr auto SAMPLES = 2500u;
using test_array = std::array<uint8_t, VECTOR_SIZE>;
using key = std::array<uint32_t, 4>;
auto curr_time = []() {
return std::chrono::high_resolution_clock::now();
};
void test_encrypt(
const test_array& plain,
const key& key
)
{
auto expected = plain;
xtea::encrypt(expected.data(), expected.size(), key);
uint64_t sum = 0;
for (auto _ = 0u; _ < SAMPLES; ++_) {
test_array cipher = plain;
auto start = curr_time();
xtea::encrypt(cipher.data(), cipher.size(), key);
auto end = curr_time();
sum += std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
assert(cipher == expected);
}
std::cout << "Optimized took " << sum / SAMPLES << "us (" << SAMPLES << " samples)\n";
}
void test_decrypt(
const test_array& cipher,
const key& key
)
{
auto expected = cipher;
xtea::decrypt(expected.data(), expected.size(), key);
uint64_t sum = 0;
for (auto _ = 0u; _ < SAMPLES; ++_) {
test_array plain = cipher;
auto start = curr_time();
xtea::decrypt(plain.data(), plain.size(), key);
auto end = curr_time();
sum += std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
assert(plain == expected);
}
std::cout << "Optimized took " << sum / SAMPLES << "us (" << SAMPLES << " samples)\n";
}
void sanity_check()
{
constexpr key key = {0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF};
constexpr std::array<uint8_t, 8> plain = {0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE};
constexpr std::array<uint8_t, 8> cipher = {0xB5, 0x8C, 0xF2, 0xFA, 0xE0, 0xC0, 0x40, 0x09};
{
std::cout << "Sanity checking xtea::encrypt...\n";
auto data = plain;
xtea::encrypt(data.data(), data.size(), key);
assert(data == cipher);
}
{
std::cout << "Sanity checking xtea::decrypt...\n";
auto data = cipher;
xtea::decrypt(data.data(), data.size(), key);
assert(data == plain);
}
}
int main()
{
sanity_check();
key key;
std::generate(key.begin(), key.end(), rand);
std::cout << "\nChecking xtea::encrypt...\n";
test_array plain;
std::generate(plain.begin(), plain.end(), rand);
test_encrypt(plain, key);
std::cout << "\nChecking xtea::decrypt...\n";
test_array cipher;
std::generate(plain.begin(), plain.end(), rand);
test_decrypt(cipher, key);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment