diff --git a/all.cpp b/all.cpp deleted file mode 100644 index 0c428ed..0000000 --- a/all.cpp +++ /dev/null @@ -1,325 +0,0 @@ -#include -#include -#include -#include - -#define BLOCK_SIZE 128 -#define HALFBLOCK_SIZE (BLOCK_SIZE / 2) -#define N_ROUNDS 64 - -typedef std::bitset Block; -typedef std::bitset Halfblock; -typedef std::array Keyset; - -// Will convert a string to a data block -Block StringToBits(const std::string& s); - -// Will convert a data block to a string -std::string BitsToString(const Block& bits); - -// Split a data block into two half blocks (into L and R) -std::pair FeistelSplit(const Block& block); - -// Combine two half blocks (L and R) into a regular data block -Block FeistelCombine(const Halfblock& l, const Halfblock& r); - -// Creates a key of size key-size from a password of arbitrary length. -Block PasswordToKey(const std::string& in); - -// Will generate a keyset from a seed-key -Keyset GenerateRoundkeys(const Block& seedKey); - -// Feistel-cipher -Block Feistel(const Block& data, const Keyset& keys, bool reverseKeyOrder = false); - -// Will expand a halfblock to a fullblock -Block ExpansionFunction(const Halfblock& block); - -// Will compress a fullblock to a halfblock -Halfblock CompressionFunction(const Block& block); - -// Substitutes four bits by static random others -std::string SBox(const std::string& in); - -// Arbitrary cipher function -Halfblock F(Halfblock m, const Block& key); - -template -std::bitset Shiftl(const std::bitset& bits, std::size_t amount); - -template -std::bitset Shiftr(const std::bitset& bits, std::size_t amount); - -std::string DiffusionCheck(const std::string& asciiMessage); - -int Mod(int numerator, int denominator) -{ - return (denominator + (numerator % denominator)) % denominator; -} - - -int main() -{ - const std::string cipher1 = DiffusionCheck("Hello, World :3"); - - std::cout << std::endl; - - const std::string cipher2 = DiffusionCheck("Hello, world :3"); - - std::size_t numDiff = 0; - for (std::size_t i = 0; i < cipher1.size(); i++) - if (cipher1[i] != cipher2[i]) - numDiff++; - std::cout << std::endl; - std::cout << "Total difference between C1 and C2: " << numDiff << std::endl; - - return 0; -} - -std::string DiffusionCheck(const std::string& asciiMessage) -{ - Block message = StringToBits(asciiMessage); - - const Block seedKey = PasswordToKey("Ich bin ein PASSWORT-SCHLÜSSEL!"); - Keyset roundkeys = GenerateRoundkeys(seedKey); - - //std::cout << "Keys: " << std::endl; - //for (std::size_t i = 0; i < roundkeys.size(); i++) - // std::cout << roundkeys[i] << std::endl; - //std::cout << "---" << std::endl; - //exit(0); - - - std::cout << "Message ascii: " << asciiMessage << std::endl; - - std::cout << "Message: " << message << std::endl; - - Block ciphertext = Feistel(message, roundkeys); - std::cout << "Ciphertext: " << ciphertext << std::endl; - - Block decrypted = Feistel(ciphertext, roundkeys, true); - std::cout << "Decrypted: " << decrypted << std::endl; - - const std::string asciiDecrypted = BitsToString(decrypted); - std::cout << "Decrypted ascii: " << asciiDecrypted << std::endl; - - return ciphertext.to_string(); -} - -Block Feistel(const Block& data, const Keyset& keys, bool reverseKeyOrder) -{ - const auto splitData = FeistelSplit(data); - Halfblock l = splitData.first; - Halfblock r = splitData.second; - - Halfblock tmp; - - for (std::size_t i = 0; i < N_ROUNDS; i++) - { - // Calculate key index - std::size_t keyIndex; - if (reverseKeyOrder) - keyIndex = N_ROUNDS - i - 1; - else - keyIndex = i; - - // Do a feistel round - tmp = r; - r = l ^ F(r, keys[keyIndex]); - l = tmp; - } - - return FeistelCombine(r, l); -} - -Halfblock F(Halfblock m, const Block& key) -{ - // Made-up F function - - // Expand to full bitwidht - Block m_expanded = ExpansionFunction(m); - - // Shift to left by 1 - m_expanded = Shiftl(m_expanded, 1); - - // Xor with key - m_expanded ^= key; - - // Non-linearly apply subsitution boxes - std::stringstream ss; - const std::string m_str = m_expanded.to_string(); - - for (std::size_t i = 0; i < m_str.size(); i += 4) - { - ss << SBox(m_str.substr(i, 4)); - } - - m_expanded = Block(ss.str()); - - // Return the compressed version - return CompressionFunction(m_expanded); -} - -Block ExpansionFunction(const Halfblock& block) -{ - std::stringstream ss; - const std::string bits = block.to_string(); - - // We have to double the bits! - for (std::size_t i = 0; i < bits.size(); i += 2) - { - const std::string sub = bits.substr(i, 2); - - if (sub == "00") ss << "1101"; - else if (sub == "01") ss << "1000"; - else if (sub == "10") ss << "0010"; - else /*if (sub == "11")*/ ss << "0111"; - - } - - return Block(ss.str()); -} - -Halfblock CompressionFunction(const Block& block) -{ - std::stringstream ss; - const std::string bits = block.to_string(); - - // We have to double the bits! - for (std::size_t i = 0; i < bits.size(); i += 4) - { - const std::string sub = bits.substr(i, 4); - - if (sub == "0000") ss << "10"; - else if (sub == "0001") ss << "01"; - else if (sub == "0010") ss << "10"; - else if (sub == "0011") ss << "10"; - else if (sub == "0100") ss << "11"; - else if (sub == "0101") ss << "01"; - else if (sub == "0110") ss << "00"; - else if (sub == "0111") ss << "11"; - else if (sub == "1000") ss << "01"; - else if (sub == "1001") ss << "00"; - else if (sub == "1010") ss << "11"; - else if (sub == "1011") ss << "00"; - else if (sub == "1100") ss << "11"; - else if (sub == "1101") ss << "10"; - else if (sub == "1110") ss << "00"; - else /*if (sub == "1111")*/ ss << "01"; - } - - return Halfblock(ss.str()); -} - -std::string SBox(const std::string& in) -{ - if (in == "0000") return "1100"; - else if (in == "0001") return "1000"; - else if (in == "0010") return "0001"; - else if (in == "0011") return "0111"; - else if (in == "0100") return "1011"; - else if (in == "0101") return "0011"; - else if (in == "0110") return "1101"; - else if (in == "0111") return "1111"; - else if (in == "1000") return "0000"; - else if (in == "1001") return "1010"; - else if (in == "1010") return "0100"; - else if (in == "1011") return "1001"; - else if (in == "1100") return "0010"; - else if (in == "1101") return "1110"; - else if (in == "1110") return "0101"; - else /*if (in == "1111")*/ return "0110"; -} - -Block StringToBits(const std::string& s) -{ - std::stringstream ss; - - for (std::size_t i = 0; i < s.size(); i++) - ss << std::bitset<8>(s[i]); - - // Pad rest with zeores - for (std::size_t i = s.size() * 8; i < BLOCK_SIZE; i++) - ss << '0'; - - return Block(ss.str()); -} - -std::string BitsToString(const Block& bits) -{ - std::stringstream ss; - - const std::string bitstring = bits.to_string(); - - for (std::size_t i = 0; i < BLOCK_SIZE; i += 8) - { - ss << (char)std::bitset<8>(bitstring.substr(i, 8)).to_ulong(); - } - - return ss.str(); -} - -std::pair FeistelSplit(const Block& block) -{ - const std::string bits = block.to_string(); - - Halfblock l(bits.substr(0, bits.size() / 2)); - Halfblock r(bits.substr(bits.size() / 2)); - - return std::make_pair(l, r); -} - -Block FeistelCombine(const Halfblock& l, const Halfblock& r) -{ - return Block(l.to_string() + r.to_string()); -} - -Keyset GenerateRoundkeys(const Block& seedKey) -{ - Keyset keys; - - keys[0] = seedKey; - keys[1] = (Shiftl(seedKey, 32) ^ keys[0]); - - for (std::size_t i = 2; i < keys.size(); i++) - { - keys[i] = Shiftl(keys[i-1], i + 32) ^ keys[i-2]; - } - - return keys; -} - -template -std::bitset Shiftl(const std::bitset& bits, std::size_t amount) -{ - std::stringstream ss; - const std::string bitss = bits.to_string(); - - for (std::size_t i = 0; i < bitss.size(); i++) - ss << bitss[Mod((i + amount), bitss.size())]; - - return std::bitset(ss.str()); -} - -template -std::bitset Shiftr(const std::bitset& bits, std::size_t amount) -{ - std::stringstream ss; - const std::string bitss = bits.to_string(); - - for (std::size_t i = 0; i < bitss.size(); i++) - ss << bitss[Mod((i - amount), bitss.size())]; - - return std::bitset(ss.str()); -} - -Block PasswordToKey(const std::string& in) -{ - Block b; - - // Segment the password in segments of key-size, and xor them together. - for (std::size_t i = 0; i < in.size(); i += BLOCK_SIZE / 8) - b ^= StringToBits(in.substr(i, BLOCK_SIZE / 8)); - - return b; -}