From 101a1e0fd64eaf003981c1e6c0d67793d36d59ee Mon Sep 17 00:00:00 2001 From: Leonetienne Date: Thu, 26 May 2022 02:44:22 +0200 Subject: [PATCH] Add additional jumbling-up in feistel rounds --- GCryptLib/include/GCrypt/Feistel.h | 2 +- GCryptLib/src/Feistel.cpp | 48 ++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/GCryptLib/include/GCrypt/Feistel.h b/GCryptLib/include/GCrypt/Feistel.h index 60f3d10..5d30334 100644 --- a/GCryptLib/include/GCrypt/Feistel.h +++ b/GCryptLib/include/GCrypt/Feistel.h @@ -32,7 +32,7 @@ namespace Leonetienne::GCrypt { private: //! Will run the feistel rounds, with either regular key //! order or reversed key order - Block Run(const Block& data, bool reverseKeys); + Block Run(const Block& data, bool modeEncrypt); //! Arbitrary cipher function static Halfblock F(Halfblock m, const Key& key); diff --git a/GCryptLib/src/Feistel.cpp b/GCryptLib/src/Feistel.cpp index 7fb731e..1c54a7f 100644 --- a/GCryptLib/src/Feistel.cpp +++ b/GCryptLib/src/Feistel.cpp @@ -30,7 +30,7 @@ namespace Leonetienne::GCrypt { return Run(data, true); } - Block Feistel::Run(const Block& data, bool reverseKeys) { + Block Feistel::Run(const Block& data, bool modeEncrypt) { const auto splitData = FeistelSplit(data); Halfblock l = splitData.first; Halfblock r = splitData.second; @@ -38,19 +38,43 @@ namespace Leonetienne::GCrypt { Halfblock tmp; for (std::size_t i = 0; i < N_ROUNDS; i++) { - // Calculate key index - std::size_t keyIndex; - if (reverseKeys) { - keyIndex = N_ROUNDS - i - 1; - } - else { - keyIndex = i; + + // Encryption + if (modeEncrypt) { + const std::size_t keyIndex = i; + + // Do a feistel round + tmp = r; + r = l ^ F(r, roundKeys[keyIndex]); + l = tmp; + + // Jumble it up a bit more + l.ShiftRowsUpInplace(); + l.ShiftCellsRightInplace(); + l.ShiftBitsLeftInplace(); + l.ShiftColumnsLeftInplace(); + // Seal all these operations with a key + l += ReductionFunction(roundKeys[keyIndex]); + } + + // Decryption + else { + // Decryption needs keys in reverse order + const std::size_t keyIndex = N_ROUNDS - i - 1; + + // Unjumble the jumble + r -= ReductionFunction(roundKeys[keyIndex]); + r.ShiftColumnsRightInplace(); + r.ShiftBitsRightInplace(); + r.ShiftCellsLeftInplace(); + r.ShiftRowsDownInplace(); + + // Do a feistel round + tmp = r; + r = l ^ F(r, roundKeys[keyIndex]); + l = tmp; } - // Do a feistel round - tmp = r; - r = l ^ F(r, roundKeys[keyIndex]); - l = tmp; } // Block has finished de*ciphering.