Created
June 22, 2020 17:39
-
-
Save JoogsWasTaken/3dbb5254ddb51a5ec6372c65cd700ab2 to your computer and use it in GitHub Desktop.
Implementation of the FEAL-4 round function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <cstdint> | |
#include <array> | |
#include <string> | |
#include <sstream> | |
#include <iomanip> | |
#define UINT8_BITLEN 8 | |
#define UINT32_BITLEN 32 | |
constexpr char hex_alphabet[16] = { '0', '1', '2', '3', '4', '5', '6', | |
'7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; | |
// Converts a uint32 into a string containing its hexadecimal | |
// representation. | |
std::string to_hex(uint32_t val) | |
{ | |
std::stringstream stream; | |
stream << std::setfill('0') << std::setw(8) << std::hex << std::uppercase << val; | |
return stream.str(); | |
} | |
// Performs a cyclic left shift on the given uint8 by the amount | |
// of places specified by count. | |
uint8_t clsh(uint8_t val, int count) | |
{ | |
// No shifting is needed if count is zero. | |
if (count == 0) | |
{ | |
return val; | |
} | |
// Shifts are applied mod 8. | |
count %= UINT8_BITLEN; | |
// CLSH = CRSH + 8. | |
if (count < 0) | |
{ | |
count += UINT8_BITLEN; | |
} | |
int count_inv = UINT8_BITLEN - count; | |
// Mask the bits that would be overflowing if a normal LSH would be performed. | |
uint8_t shift_mask = ((1 << count) - 1) << count_inv; | |
uint8_t overflow_bits = (val & shift_mask) >> count_inv; | |
// Perform the actual shift. | |
val <<= count; | |
// Add the overflow bits back to the original. | |
val |= overflow_bits; | |
return val; | |
} | |
// Implements the G function of the FEAL-4 cipher. | |
// G = (a + b + g) (mod 256). | |
uint8_t g_func(uint8_t a, uint8_t b, uint8_t g) | |
{ | |
return clsh(a + b + g, 2); | |
} | |
// Implements the FEAL-4 round function. | |
uint32_t round_func(uint32_t x) | |
{ | |
// Split up input into four 8 bit bytes. | |
uint8_t x0 = (x >> 24) & 0xff, | |
x1 = (x >> 16) & 0xff, | |
x2 = (x >> 8) & 0xff, | |
x3 = x & 0xff; | |
// Compute the four 8 bit output bytes. | |
uint8_t y1 = g_func(x0 ^ x1, x2 ^ x3, 1); | |
uint8_t y0 = g_func(x0, y1, 0); | |
uint8_t y2 = g_func(y1, x2 ^ x3, 0); | |
uint8_t y3 = g_func(y2, x3, 1); | |
// Merge them all together into one 32 bit output. | |
uint32_t y = 0; | |
// Let y0 be the eight LSBs of the 32 bit output. | |
// Shift to the left so it'll eventually end up at | |
// the MSB positions. | |
y |= y0; | |
y <<= 8; | |
// Same with y1 and y2. | |
y |= y1; | |
y <<= 8; | |
y |= y2; | |
y <<= 8; | |
return y | y3; | |
} | |
// Prompts for a hex string that is then fed into a uint32. | |
uint32_t prompt_uint32_input(std::string prompt) | |
{ | |
uint32_t i; | |
bool done = false; | |
for (std::string line; | |
std::cout << prompt && std::getline(std::cin, line); ) | |
{ | |
std::istringstream iss(line); | |
// Trim leading whitespaces, convert from hex to numbers. | |
// Then check for EOF at end of string. | |
if (iss >> std::ws >> std::hex >> i && iss.get() == EOF) | |
{ | |
done = true; | |
break; | |
} | |
std::cerr << "Invalid input '" << line << "'." << std::endl; | |
} | |
if (done) | |
{ | |
return i; | |
} | |
std::cerr << "Input preemptively aborted." << std::endl; | |
return 0; | |
} | |
int main(int argc, char** argv) | |
{ | |
uint32_t a, b; | |
a = prompt_uint32_input("Input A: "); | |
b = prompt_uint32_input("Input B: "); | |
std::cout << std::endl; | |
std::cout << " A = " << to_hex(a) << std::endl; | |
std::cout << " B = " << to_hex(a) << std::endl; | |
std::cout << " A ^ B = " << to_hex(a ^ b) << std::endl; | |
uint32_t x, y; | |
x = round_func(a); | |
y = round_func(b); | |
std::cout << std::endl; | |
std::cout << " F(A) = " << to_hex(x) << std::endl; | |
std::cout << " F(B) = " << to_hex(y) << std::endl; | |
std::cout << "F(A) ^ F(B) = " << to_hex(x ^ y) << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment