diff --git a/Feistel.cpp b/Feistel.cpp
index 62c220e..ab825ec 100644
--- a/Feistel.cpp
+++ b/Feistel.cpp
@@ -21,17 +21,17 @@ void Feistel::SetKey(const Block& key)
return;
}
-Block Feistel::Encipher(const Block& data)
+Block Feistel::Encipher(const Block& data) const
{
return Run(data, false);
}
-Block Feistel::Decipher(const Block& data)
+Block Feistel::Decipher(const Block& data) const
{
return Run(data, true);
}
-Block Feistel::Run(const Block& data, bool reverseKeys)
+Block Feistel::Run(const Block& data, bool reverseKeys) const
{
const auto splitData = FeistelSplit(data);
Halfblock l = splitData.first;
@@ -173,6 +173,8 @@ std::string Feistel::SBox(const std::string& in)
void Feistel::GenerateRoundKeys(const Block& seedKey)
{
+ // Generate round keys via output feedback modus (OFM) method
+
// Clear initial key memory
ZeroKeyMemory();
roundKeys = Keyset();
@@ -190,7 +192,7 @@ void Feistel::GenerateRoundKeys(const Block& seedKey)
}
// These pragmas only work for MSVC, as far as i know. Beware!!!
-#pragma optimize( "", off )
+#pragma optimize("", off )
void Feistel::ZeroKeyMemory()
{
for (Block& key : roundKeys)
@@ -198,4 +200,4 @@ void Feistel::ZeroKeyMemory()
return;
}
-#pragma optimize( "", on )
+#pragma optimize("", on )
diff --git a/Feistel.h b/Feistel.h
index 7b16689..d133131 100644
--- a/Feistel.h
+++ b/Feistel.h
@@ -8,7 +8,11 @@
class Feistel
{
public:
- Feistel(const Block& key);
+ explicit Feistel(const Block& key);
+
+ Feistel(const Feistel& other) = delete;
+ Feistel(Feistel&& other) noexcept = delete;
+
~Feistel();
//! Will set the seed-key for this feistel network.
@@ -16,14 +20,14 @@ public:
void SetKey(const Block& key);
//! Will encipher a data block via the set seed-key
- Block Encipher(const Block& data);
+ Block Encipher(const Block& data) const;
//! Will decipher a data block via the set seed-key
- Block Decipher(const Block& data);
+ Block Decipher(const Block& data) const;
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 reverseKeys) const;
//! Arbitrary cipher function
static Halfblock F(Halfblock m, const Block& key);
diff --git a/Feistel.vcxproj b/Feistel.vcxproj
index 6876071..ce3f24a 100644
--- a/Feistel.vcxproj
+++ b/Feistel.vcxproj
@@ -146,12 +146,15 @@
true
+
+
+
diff --git a/Feistel.vcxproj.filters b/Feistel.vcxproj.filters
index 7e418d2..dc966f1 100644
--- a/Feistel.vcxproj.filters
+++ b/Feistel.vcxproj.filters
@@ -24,6 +24,9 @@
Quelldateien
+
+ Quelldateien
+
@@ -44,5 +47,11 @@
Headerdateien
+
+ Headerdateien
+
+
+ Headerdateien
+
\ No newline at end of file
diff --git a/FeistelMan.cpp b/FeistelMan.cpp
new file mode 100644
index 0000000..a24631b
--- /dev/null
+++ b/FeistelMan.cpp
@@ -0,0 +1,114 @@
+#include "FeistelMan.h"
+#include "Util.h"
+#include
+
+FeistelMan::FeistelMan(const Block& key)
+ :
+ key { key }
+{
+
+ return;
+}
+
+FeistelMan::FeistelMan(const std::string& password)
+{
+ key = PasswordToKey(password);
+
+ return;
+}
+
+FeistelMan::~FeistelMan()
+{
+ // Clear key memory
+ ZeroKeyMemory();
+
+ return;
+}
+
+void FeistelMan::SetKey(const Block& key)
+{
+ ZeroKeyMemory();
+
+ this->key = key;
+ return;
+}
+
+void FeistelMan::SetPassword(const std::string& password)
+{
+ ZeroKeyMemory();
+
+ key = PasswordToKey(password);
+ return;
+}
+
+Flexblock FeistelMan::Encipher(const Flexblock& data) const
+{
+ // Split cleartext into blocks
+ std::vector blocks;
+
+ for (std::size_t i = 0; i < data.size(); i += BLOCK_SIZE)
+ blocks.push_back(Block(
+ PadStringToLength(data.substr(i, BLOCK_SIZE), BLOCK_SIZE, '0', false))
+ );
+
+ // Encrypt individual blocks using cipher block chaining
+ Feistel feistel(key);
+
+ for (std::size_t i = 0; i < blocks.size(); i++)
+ {
+ const Block& lastBlock = (i>0) ? blocks[i-1] : emptyBlock;
+ blocks[i] = feistel.Encipher(blocks[i] ^ lastBlock);
+ }
+
+ // Concatenate ciphertext blocks back into a flexblock
+ std::stringstream ss;
+ for (Block& b : blocks)
+ ss << b;
+
+ // Return it
+ return ss.str();
+}
+
+Flexblock FeistelMan::Decipher(const Flexblock& data) const
+{
+ // Split ciphertext into blocks
+ std::vector blocks;
+
+ for (std::size_t i = 0; i < data.size(); i += BLOCK_SIZE)
+ blocks.push_back(Block(
+ PadStringToLength(data.substr(i, BLOCK_SIZE), BLOCK_SIZE, '0', false))
+ );
+
+ // Decrypt individual blocks
+ Feistel feistel(key);
+
+ // We can't do this in-loop for decryption, because we are decrypting the blocks in-place.
+ Block lastBlock = emptyBlock;
+
+ for (std::size_t i = 0; i < blocks.size(); i++)
+ {
+ Block tmpCopy = blocks[i];
+
+ blocks[i] = feistel.Decipher(blocks[i]) ^ lastBlock;
+
+ lastBlock = std::move(tmpCopy);
+ }
+
+ // Concatenate ciphertext blocks back into a flexblock
+ std::stringstream ss;
+ for (Block& b : blocks)
+ ss << b;
+
+ // Return it
+ return ss.str();
+}
+
+#pragma optimize("", off )
+void FeistelMan::ZeroKeyMemory()
+{
+ key.reset();
+ return;
+}
+#pragma optimize("", on )
+
+const Block FeistelMan::emptyBlock;
diff --git a/FeistelMan.h b/FeistelMan.h
new file mode 100644
index 0000000..ad242ff
--- /dev/null
+++ b/FeistelMan.h
@@ -0,0 +1,38 @@
+#pragma once
+#include "Feistel.h"
+#include "Flexblock.h"
+
+/** Class to apply a block cipher to messages of arbitrary length in a distributed manner
+*/
+class FeistelMan
+{
+public:
+ explicit FeistelMan(const Block& key);
+ explicit FeistelMan(const std::string& password);
+
+ FeistelMan(const FeistelMan& other) = delete;
+ FeistelMan(FeistelMan&& other) noexcept = delete;
+
+ ~FeistelMan();
+
+ //! Will set the key
+ void SetKey(const Block& key);
+
+ //! Will set the key from a password
+ void SetPassword(const std::string& password);
+
+ //! Will encipher a flexblock of data
+ Flexblock Encipher(const Flexblock& data) const;
+
+ //! Will decipher a flexblock of data
+ Flexblock Decipher(const Flexblock& data) const;
+
+private:
+ Block key;
+
+ //! Will zero the memory used by the key
+ void ZeroKeyMemory();
+
+ // Initial value for cipher block chaining
+ static const Block emptyBlock;
+};
diff --git a/Flexblock.h b/Flexblock.h
new file mode 100644
index 0000000..66c75e0
--- /dev/null
+++ b/Flexblock.h
@@ -0,0 +1,5 @@
+#pragma once
+#include
+
+//! A "bitset" of variable length
+typedef std::string Flexblock;
diff --git a/main.cpp b/main.cpp
index 9daa6a4..f054497 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,10 +1,27 @@
#pragma once
#include
#include "Util.h"
-#include "Feistel.h"
+#include "FeistelMan.h"
int main()
{
+ FeistelMan feistel("Password yo");
+
+ const std::string message = "I am a veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeery long message!";
+
+ std::cout << "Cleartext: " << message << std::endl;
+
+ // Encrypt
+ const Flexblock ciphertext = feistel.Encipher(StringToBits(message));
+ const std::string cipherHex = BitsToHexstring(ciphertext);
+
+ std::cout << "Ciphertext: " << cipherHex << std::endl;
+
+
+ // Decrypt
+ const Flexblock cleartextBits = feistel.Decipher(HexstringToBits(cipherHex));
+ std::cout << "Decrypted: " << BitsToString(cleartextBits) << std::endl;
+
return 0;
}