From 51528ecf3d90d09351322e172d91eed0cb45b2e7 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Sun, 8 Nov 2020 20:34:13 +0200 Subject: Add more test vectors --- blowfish.hpp | 50 +++++----- blowfish_init.hpp | 3 +- main.cpp | 46 +-------- makefile | 13 +-- test_set_keys.cpp | 42 ++++++++ test_variable_keys.cpp | 36 +++++++ vectors.h | 253 +++++++++++++++++++++++++++---------------------- 7 files changed, 255 insertions(+), 188 deletions(-) create mode 100644 test_set_keys.cpp create mode 100644 test_variable_keys.cpp diff --git a/blowfish.hpp b/blowfish.hpp index 3637335..88d865a 100644 --- a/blowfish.hpp +++ b/blowfish.hpp @@ -4,9 +4,12 @@ #include "blowfish_init.hpp" #include +#include namespace Blowfish { -template concept is_valid_key_length = (sz < KEYLEN); + +template +concept is_valid_key_length = (KEYLEN_MIN <= sz && sz <= KEYLEN_MAX); struct Block { constexpr Block(uint64_t x) { @@ -28,23 +31,21 @@ struct Block { template requires is_valid_key_length class Context { public: - constexpr Context(const std::array &key) { + constexpr Context(const std::span &key) { for (std::size_t i = 0; i < BOXES; ++i) { std::copy(S_INIT[i].begin(), S_INIT[i].end(), S[i].begin()); } - // - std::size_t k = 0; for (std::size_t i = 0; i < SUBKEYS; ++i) { - uint32_t qk = 0; - for (std::size_t j = 0; j < 4; ++j) { - qk = (qk << 8) | key[k]; - ++k; - if (k >= keylen) { - k = 0; - } - } - P[i] = P_INIT[i] ^ qk; + const auto idx0 = (i * 4 + 0) % keylen; + const auto idx1 = (i * 4 + 1) % keylen; + const auto idx2 = (i * 4 + 2) % keylen; + const auto idx3 = (i * 4 + 3) % keylen; + const uint32_t qk = (static_cast(key[idx0]) << 24) + + (static_cast(key[idx1]) << 16) + + (static_cast(key[idx2]) << 8) + + static_cast(key[idx3]); + P[i] = P_INIT[i] ^ qk; } Block x(0, 0); @@ -54,6 +55,7 @@ public: P[i] = x.L; P[i + 1] = x.R; } + for (std::size_t i = 0; i < BOXES; ++i) { for (std::size_t j = 0; j < ENTRIES; j += 2) { x = encrypt(x); @@ -65,11 +67,12 @@ public: constexpr Block encrypt(const Block &x) const { Block y(x); - for (std::size_t i = 0; i < ROUNDS; ++i) { - y.L = y.L ^ P[i]; - y.R = F(y.L) ^ y.R; - std::swap(y.L, y.R); - } + for (std::size_t i = 0; i < ROUNDS; ++i) + [[likely]] { + y.L = y.L ^ P[i]; + y.R = F(y.L) ^ y.R; + std::swap(y.L, y.R); + } std::swap(y.L, y.R); y.R = y.R ^ P[16]; y.L = y.L ^ P[17]; @@ -79,11 +82,12 @@ public: constexpr Block decrypt(const Block &x) const { Block y(x); - for (std::size_t i = ROUNDS + 1; i > 1; --i) { - y.L = y.L ^ P[i]; - y.R = F(y.L) ^ y.R; - std::swap(y.L, y.R); - } + for (std::size_t i = ROUNDS + 1; i > 1; --i) + [[likely]] { + y.L = y.L ^ P[i]; + y.R = F(y.L) ^ y.R; + std::swap(y.L, y.R); + } std::swap(y.L, y.R); y.R = y.R ^ P[1]; y.L = y.L ^ P[0]; diff --git a/blowfish_init.hpp b/blowfish_init.hpp index 2d7bf6c..7e9a0d9 100644 --- a/blowfish_init.hpp +++ b/blowfish_init.hpp @@ -4,7 +4,8 @@ namespace Blowfish { -constexpr std::size_t KEYLEN = 448 / sizeof(uint8_t); +constexpr std::size_t KEYLEN_MIN = 32 / 8; +constexpr std::size_t KEYLEN_MAX = 448 / 8; constexpr std::size_t ROUNDS = 16; constexpr std::size_t SUBKEYS = ROUNDS + 2; constexpr std::size_t BOXES = 4; diff --git a/main.cpp b/main.cpp index 2a46d8c..d11aba1 100644 --- a/main.cpp +++ b/main.cpp @@ -2,49 +2,11 @@ #include "vectors.h" #include -constexpr uint64_t k(const uint8_t key[8]) { - uint64_t r = 0; - for (int i = 0; i < 8; ++i) { - r += static_cast(key[i]) << (64 - 8 * (i + 1)); - } - return r; -} - -template struct wrapper { - constexpr void operator()() const { - constexpr Blowfish::Context<8> b(std::to_array(variable_key[i])); - constexpr Blowfish::Block x(plaintext_l[i], plaintext_r[i]); - - constexpr auto y = b.encrypt(x); - static_assert(y.L == ciphertext_l[i]); - static_assert(y.R == ciphertext_r[i]); - - constexpr auto z = b.decrypt(y); - static_assert(x.L == z.L); - static_assert(x.R == z.R); - - printf("0x%016lx\t", k(variable_key[i])); - printf("0x%016lx\t", static_cast(x)); - printf("0x%016lx\t", static_cast(y)); - printf("0x%016lx\n", static_cast(z)); - } -}; - -template