From 6d89ab37754462928b28ad85714af316c83f43cb Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Sun, 8 Nov 2020 12:13:01 +0200 Subject: Add compile-time key length check --- blowfish.hpp | 57 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 24 deletions(-) (limited to 'blowfish.hpp') diff --git a/blowfish.hpp b/blowfish.hpp index 9a6e0fe..3637335 100644 --- a/blowfish.hpp +++ b/blowfish.hpp @@ -5,32 +5,39 @@ #include "blowfish_init.hpp" #include -class Blowfish { -public: - struct Block { - constexpr Block(uint64_t x) { - L = x >> 32; - R = x & 0xffffffff; - } - constexpr Block(uint32_t l, uint32_t r) : L(l), R(r) {} +namespace Blowfish { +template concept is_valid_key_length = (sz < KEYLEN); - constexpr operator uint64_t() const { - return (static_cast(L) << 32) + R; - } - uint32_t L; - uint32_t R; - }; +struct Block { + constexpr Block(uint64_t x) { + static_assert(sizeof(Block) == sizeof(uint64_t)); + L = x >> 32; + R = x & 0xffffffff; + } + constexpr Block(uint32_t l, uint32_t r) : L(l), R(r) { + static_assert(sizeof(Block) == sizeof(uint64_t)); + } - constexpr Blowfish(const uint8_t key[], size_t keylen) { - for (size_t i = 0; i < BOXES; ++i) { + constexpr operator uint64_t() const { + return (static_cast(L) << 32) + R; + } + uint32_t L; + uint32_t R; +}; + +template +requires is_valid_key_length class Context { +public: + constexpr Context(const std::array &key) { + for (std::size_t i = 0; i < BOXES; ++i) { std::copy(S_INIT[i].begin(), S_INIT[i].end(), S[i].begin()); } // - size_t k = 0; - for (size_t i = 0; i < SUBKEYS; ++i) { + std::size_t k = 0; + for (std::size_t i = 0; i < SUBKEYS; ++i) { uint32_t qk = 0; - for (size_t j = 0; j < 4; ++j) { + for (std::size_t j = 0; j < 4; ++j) { qk = (qk << 8) | key[k]; ++k; if (k >= keylen) { @@ -42,13 +49,13 @@ public: Block x(0, 0); - for (size_t i = 0; i < SUBKEYS; i += 2) { + for (std::size_t i = 0; i < SUBKEYS; i += 2) { x = encrypt(x); P[i] = x.L; P[i + 1] = x.R; } - for (size_t i = 0; i < BOXES; ++i) { - for (size_t j = 0; j < ENTRIES; j += 2) { + for (std::size_t i = 0; i < BOXES; ++i) { + for (std::size_t j = 0; j < ENTRIES; j += 2) { x = encrypt(x); S[i][j] = x.L; S[i][j + 1] = x.R; @@ -58,7 +65,7 @@ public: constexpr Block encrypt(const Block &x) const { Block y(x); - for (size_t i = 0; i < ROUNDS; ++i) { + 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); @@ -72,7 +79,7 @@ public: constexpr Block decrypt(const Block &x) const { Block y(x); - for (size_t i = ROUNDS + 1; i > 1; --i) { + 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); @@ -99,3 +106,5 @@ private: std::array P; std::array, BOXES> S; }; + +} // namespace Blowfish -- cgit v1.2.1