aboutsummaryrefslogtreecommitdiff
path: root/blowfish.hpp
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2020-11-08 20:34:13 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2020-11-08 20:34:13 +0200
commit51528ecf3d90d09351322e172d91eed0cb45b2e7 (patch)
tree270b22937ccf770a70b287730e4113d1b934ac09 /blowfish.hpp
parentAdd compile-time key length check (diff)
downloadblowfish-master.tar.xz
Add more test vectorsHEADmaster
Diffstat (limited to 'blowfish.hpp')
-rw-r--r--blowfish.hpp50
1 files changed, 27 insertions, 23 deletions
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 <algorithm>
+#include <span>
namespace Blowfish {
-template <std::size_t sz> concept is_valid_key_length = (sz < KEYLEN);
+
+template <std::size_t sz>
+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 <std::size_t keylen>
requires is_valid_key_length<keylen> class Context {
public:
- constexpr Context(const std::array<uint8_t, keylen> &key) {
+ constexpr Context(const std::span<const uint8_t> &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<uint32_t>(key[idx0]) << 24) +
+ (static_cast<uint32_t>(key[idx1]) << 16) +
+ (static_cast<uint32_t>(key[idx2]) << 8) +
+ static_cast<uint32_t>(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];