2021-12-05 15:47:31 +01:00
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <array>
|
2021-12-05 15:58:56 +01:00
|
|
|
#include <bitset>
|
2021-12-05 15:47:31 +01:00
|
|
|
|
2021-12-05 15:58:56 +01:00
|
|
|
#define BLOCK_SIZE 16
|
|
|
|
#define FEISTELBLOCK_SIZE (BLOCK_SIZE / 2)
|
2021-12-05 15:47:31 +01:00
|
|
|
#define N_ROUNDS 8
|
|
|
|
|
2021-12-05 15:58:56 +01:00
|
|
|
typedef std::bitset<BLOCK_SIZE> Block;
|
|
|
|
typedef std::bitset<FEISTELBLOCK_SIZE> Feistelblock;
|
|
|
|
|
|
|
|
Feistelblock F(Feistelblock m, const Feistelblock& key);
|
|
|
|
std::pair<Feistelblock, Feistelblock> Feistel(Feistelblock l, Feistelblock r, const std::array<Feistelblock, 8>& keys, bool reverseKeyOrder = false);
|
2021-12-05 15:47:31 +01:00
|
|
|
|
|
|
|
int Mod(int numerator, int denominator)
|
|
|
|
{
|
|
|
|
return (denominator + (numerator % denominator)) % denominator;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
2021-12-05 15:58:56 +01:00
|
|
|
Feistelblock l = 0b10101010;
|
|
|
|
Feistelblock r = 0b10101010;
|
|
|
|
const std::array<Feistelblock, N_ROUNDS> keys = {
|
|
|
|
0b11101101,
|
|
|
|
0b01110101,
|
|
|
|
0b10111101,
|
|
|
|
0b00010110,
|
|
|
|
0b00000011,
|
|
|
|
0b10110011,
|
|
|
|
0b11011101,
|
|
|
|
0b00111101
|
2021-12-05 15:47:31 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
std::cout << "Input: " << l << r << std::endl;
|
|
|
|
|
|
|
|
auto c = Feistel(l, r, keys);
|
|
|
|
l = c.first;
|
|
|
|
r = c.second;
|
|
|
|
|
|
|
|
std::cout << "Ciphertext: " << l << r << std::endl;
|
|
|
|
|
|
|
|
c = Feistel(l, r, keys, true);
|
|
|
|
l = c.first;
|
|
|
|
r = c.second;
|
|
|
|
|
|
|
|
std::cout << "Decrypted: " << l << r << std::endl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-12-05 15:58:56 +01:00
|
|
|
std::pair<Feistelblock, Feistelblock> Feistel(Feistelblock l, Feistelblock r, const std::array<Feistelblock, 8>& keys, bool reverseKeyOrder)
|
2021-12-05 15:47:31 +01:00
|
|
|
{
|
2021-12-05 15:58:56 +01:00
|
|
|
Feistelblock tmp;
|
2021-12-05 15:47:31 +01:00
|
|
|
|
|
|
|
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;
|
2021-12-05 15:58:56 +01:00
|
|
|
r = l ^ F(r, keys[keyIndex]);
|
2021-12-05 15:47:31 +01:00
|
|
|
l = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_pair(r, l);
|
|
|
|
}
|
|
|
|
|
2021-12-05 15:58:56 +01:00
|
|
|
Feistelblock F(Feistelblock m, const Feistelblock& key)
|
2021-12-05 15:47:31 +01:00
|
|
|
{
|
|
|
|
// Made-up F function
|
|
|
|
|
|
|
|
// Shift 5 to the left
|
2021-12-05 15:58:56 +01:00
|
|
|
m <<= 5;
|
2021-12-05 15:47:31 +01:00
|
|
|
|
|
|
|
// Xor with key
|
2021-12-05 15:58:56 +01:00
|
|
|
return m ^ key;
|
2021-12-05 15:47:31 +01:00
|
|
|
}
|