Implement new sbox, reduction, and expansion function
This commit is contained in:
parent
8ddd9d6bfb
commit
bc3dae96a3
@ -163,8 +163,15 @@ namespace Leonetienne::GCrypt {
|
|||||||
//! Returns 32-bit chunks of data, indexed by a 1d-index (0-16)
|
//! Returns 32-bit chunks of data, indexed by a 1d-index (0-16)
|
||||||
[[nodiscard]] const T& operator[](const std::uint8_t index) const;
|
[[nodiscard]] const T& operator[](const std::uint8_t index) const;
|
||||||
|
|
||||||
|
//! Will return a reference to the data array
|
||||||
|
T* Data() noexcept;
|
||||||
|
|
||||||
|
//! Will return a reference to the data array
|
||||||
|
const T* Data() const noexcept;
|
||||||
|
|
||||||
static constexpr std::size_t CHUNK_SIZE = sizeof(T);
|
static constexpr std::size_t CHUNK_SIZE = sizeof(T);
|
||||||
static constexpr std::size_t CHUNK_SIZE_BITS = CHUNK_SIZE * 8;
|
static constexpr std::size_t CHUNK_SIZE_BITS = CHUNK_SIZE * 8;
|
||||||
|
static constexpr std::size_t BLOCK_SIZE = CHUNK_SIZE * 16;
|
||||||
static constexpr std::size_t BLOCK_SIZE_BITS = CHUNK_SIZE_BITS * 16;
|
static constexpr std::size_t BLOCK_SIZE_BITS = CHUNK_SIZE_BITS * 16;
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const Basic_Block<T>& b) {
|
friend std::ostream& operator<<(std::ostream& os, const Basic_Block<T>& b) {
|
||||||
|
@ -46,11 +46,11 @@ namespace Leonetienne::GCrypt {
|
|||||||
//! Will expand a halfblock to a fullblock
|
//! Will expand a halfblock to a fullblock
|
||||||
static Block ExpansionFunction(const Halfblock& block);
|
static Block ExpansionFunction(const Halfblock& block);
|
||||||
|
|
||||||
//! Will compress a fullblock to a halfblock
|
//! Will reduce a fullblock to a halfblock
|
||||||
static Halfblock CompressionFunction(const Block& block);
|
static Halfblock ReductionFunction(const Block& block);
|
||||||
|
|
||||||
//! Substitutes four bits by static random others
|
//! Substitutes eight bits by static random others, inplace
|
||||||
static std::string SBox(const std::string& in);
|
static void SBox(Block& block);
|
||||||
|
|
||||||
//! Will generate a the round keys
|
//! Will generate a the round keys
|
||||||
void GenerateRoundKeys(const Key& seedKey);
|
void GenerateRoundKeys(const Key& seedKey);
|
||||||
|
46
GCryptLib/include/GCrypt/SBoxLookup.h
Normal file
46
GCryptLib/include/GCrypt/SBoxLookup.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef GCRYPT_SBOX_LOOKUP
|
||||||
|
#define GCRYPT_SBOX_LOOKUP
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace Leonetienne::GCrypt {
|
||||||
|
|
||||||
|
static const std::array<std::uint8_t, 256> sboxLookup {
|
||||||
|
0x23,0xF7,0xA2,0x31,0x5B,0x0C,0x13,0xEE,
|
||||||
|
0xF8,0x1B,0x0B,0xA9,0x37,0x9F,0x55,0xF3,
|
||||||
|
0x7D,0x71,0x9E,0x89,0x38,0x53,0x3D,0xE9,
|
||||||
|
0x47,0xA4,0x30,0xBF,0x82,0xE3,0x69,0x5C,
|
||||||
|
0x3C,0x88,0xDE,0x7F,0x29,0xEB,0x5F,0x02,
|
||||||
|
0x63,0x42,0xDC,0x36,0x20,0x6B,0x9C,0x4A,
|
||||||
|
0xA8,0x11,0x6D,0x67,0x3A,0xF4,0x33,0x61,
|
||||||
|
0x1C,0x4C,0x22,0x07,0x6F,0x80,0xA5,0x96,
|
||||||
|
0x77,0x62,0xDD,0x6A,0x60,0x05,0x08,0x72,
|
||||||
|
0xE5,0x1D,0x39,0xA7,0x58,0x3F,0x57,0xAD,
|
||||||
|
0xFF,0x09,0xC5,0xB2,0xE7,0x94,0xEA,0x34,
|
||||||
|
0x9A,0x5D,0x52,0xE2,0xAE,0x99,0xBB,0x44,
|
||||||
|
0xFD,0x73,0xEC,0x87,0xED,0xBA,0x7C,0xF5,
|
||||||
|
0xDA,0x01,0xC7,0xC1,0xB6,0x81,0x12,0xD5,
|
||||||
|
0x7A,0x16,0x18,0x97,0x74,0x32,0xBD,0x56,
|
||||||
|
0xFE,0x79,0x3E,0x95,0x93,0xAB,0x6C,0xC6,
|
||||||
|
0x2A,0x27,0x19,0x26,0x2E,0x41,0x0F,0x85,
|
||||||
|
0x66,0x59,0xEF,0x98,0x10,0xE8,0xE6,0x49,
|
||||||
|
0xAC,0x0D,0x2D,0xD3,0xF0,0x92,0x8F,0xD9,
|
||||||
|
0xAF,0xC8,0xB5,0xBC,0x6E,0xD6,0x78,0x8E,
|
||||||
|
0x17,0xCB,0x75,0x50,0x51,0x84,0xB7,0x4D,
|
||||||
|
0x70,0x9D,0x8A,0x2B,0x0E,0x35,0xB9,0x40,
|
||||||
|
0x00,0x21,0xC3,0xB3,0x43,0xCD,0x65,0xC0,
|
||||||
|
0x4E,0xCF,0xCA,0x28,0x45,0x46,0x54,0x8B,
|
||||||
|
0x0A,0x5A,0x1F,0x24,0xFA,0xA6,0xB4,0xD7,
|
||||||
|
0x3B,0xFC,0x5E,0xA3,0xB8,0x04,0xCE,0xF2,
|
||||||
|
0xFB,0xD4,0x8C,0xE4,0x90,0xB1,0x06,0x8D,
|
||||||
|
0x86,0xA1,0xE0,0x68,0xD1,0x2C,0x03,0x64,
|
||||||
|
0x9B,0x4F,0x14,0x1E,0x7B,0x76,0x48,0xCC,
|
||||||
|
0xC4,0x15,0xAA,0xC9,0xE1,0x91,0xF6,0xD0,
|
||||||
|
0x25,0xA0,0x7E,0xB0,0x1A,0xBE,0xC2,0x4B,
|
||||||
|
0xF1,0xD2,0xDF,0x2F,0xF9,0xDB,0xD8,0x83
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -694,6 +694,16 @@ namespace Leonetienne::GCrypt {
|
|||||||
return data[index];
|
return data[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T* Basic_Block<T>::Data() noexcept {
|
||||||
|
return data.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
const T* Basic_Block<T>::Data() const noexcept {
|
||||||
|
return data.data();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool Basic_Block<T>::operator==(const Basic_Block<T>& other) const {
|
bool Basic_Block<T>::operator==(const Basic_Block<T>& other) const {
|
||||||
return data == other.data;
|
return data == other.data;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "GCrypt/Feistel.h"
|
#include "GCrypt/Feistel.h"
|
||||||
#include "GCrypt/Util.h"
|
#include "GCrypt/Util.h"
|
||||||
#include "GCrypt/Config.h"
|
#include "GCrypt/Config.h"
|
||||||
|
#include "GCrypt/SBoxLookup.h"
|
||||||
|
|
||||||
namespace Leonetienne::GCrypt {
|
namespace Leonetienne::GCrypt {
|
||||||
|
|
||||||
@ -54,14 +55,14 @@ namespace Leonetienne::GCrypt {
|
|||||||
|
|
||||||
// Block has finished de*ciphering.
|
// Block has finished de*ciphering.
|
||||||
// Let's generate a new set of round keys.
|
// Let's generate a new set of round keys.
|
||||||
GenerateRoundKeys((Key)roundKeys.back());
|
GenerateRoundKeys(roundKeys.back());
|
||||||
|
|
||||||
return FeistelCombine(r, l);
|
return FeistelCombine(r, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
Halfblock Feistel::F(Halfblock m, const Key& key) {
|
Halfblock Feistel::F(Halfblock m, const Key& key) {
|
||||||
|
|
||||||
// Made-up F function
|
// Made-up F function:
|
||||||
// Expand to full bitwidth
|
// Expand to full bitwidth
|
||||||
Block m_expanded = ExpansionFunction(m);
|
Block m_expanded = ExpansionFunction(m);
|
||||||
|
|
||||||
@ -75,82 +76,86 @@ namespace Leonetienne::GCrypt {
|
|||||||
// Now do a bitshift
|
// Now do a bitshift
|
||||||
m_expanded.ShiftBitsLeftInplace();
|
m_expanded.ShiftBitsLeftInplace();
|
||||||
|
|
||||||
// Non-linearly apply subsitution boxes
|
// Apply the sbox
|
||||||
std::stringstream ss;
|
SBox(m_expanded);
|
||||||
const std::string m_str = m_expanded.ToString();
|
|
||||||
for (std::size_t i = 0; i < Block::BLOCK_SIZE_BITS; i += 4) {
|
|
||||||
ss << SBox(m_str.substr(i, 4));
|
|
||||||
}
|
|
||||||
m_expanded = Block(ss.str());
|
|
||||||
|
|
||||||
// Return the compressed version, shifted by 3
|
// Reduce back to a halfblock
|
||||||
//return Shiftl(CompressionFunction(m_expanded), 3);
|
Halfblock hb = ReductionFunction(m_expanded);
|
||||||
return (CompressionFunction(m_expanded));
|
|
||||||
|
// To jumble it up a last time,
|
||||||
|
// matrix-multiply it with the input halfblock
|
||||||
|
hb *= m;
|
||||||
|
|
||||||
|
return hb;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Halfblock, Halfblock> Feistel::FeistelSplit(const Block& block) {
|
std::pair<Halfblock, Halfblock> Feistel::FeistelSplit(const Block& block) {
|
||||||
const std::string bits = block.ToString();
|
Halfblock l;
|
||||||
|
Halfblock r;
|
||||||
|
|
||||||
Halfblock l(bits.substr(0, bits.size() / 2));
|
memcpy(l.Data(), block.Data(), Halfblock::BLOCK_SIZE);
|
||||||
Halfblock r(bits.substr(bits.size() / 2));
|
memcpy(r.Data(), block.Data() + 8, Halfblock::BLOCK_SIZE);
|
||||||
|
// +8, because 8 is HALF the number of elements in the array. We only want to copy HALF a full-sized block.
|
||||||
|
|
||||||
return std::make_pair(l, r);
|
return std::make_pair(l, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
Block Feistel::FeistelCombine(const Halfblock& l, const Halfblock& r) {
|
Block Feistel::FeistelCombine(const Halfblock& l, const Halfblock& r) {
|
||||||
return Block(l.ToString() + r.ToString());
|
Block b;
|
||||||
|
|
||||||
|
memcpy(b.Data(), l.Data(), Halfblock::BLOCK_SIZE);
|
||||||
|
memcpy(b.Data() + 8, r.Data(), Halfblock::BLOCK_SIZE);
|
||||||
|
// +8, because 8 is HALF the number of elements in the array. We only want to copy HALF a full-sized block.
|
||||||
|
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
Block Feistel::ExpansionFunction(const Halfblock& block) {
|
Block Feistel::ExpansionFunction(const Halfblock& hb) {
|
||||||
std::stringstream ss;
|
Block b;
|
||||||
const std::string bits = block.ToString();
|
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> expansionMap;
|
// Copy the bits over
|
||||||
expansionMap["00"] = "1101";
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
expansionMap["01"] = "1000";
|
b[i] = hb[i];
|
||||||
expansionMap["10"] = "0010";
|
|
||||||
expansionMap["11"] = "0111";
|
|
||||||
|
|
||||||
// We have to double the bits!
|
|
||||||
for (std::size_t i = 0; i < Halfblock::BLOCK_SIZE_BITS; i += 2) {
|
|
||||||
const std::string sub = bits.substr(i, 2);
|
|
||||||
ss << expansionMap[sub];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Block(ss.str());
|
// Multiply the block a few tims with a bitshifted version
|
||||||
|
// This is irriversible, too
|
||||||
|
for (std::size_t i = 0; i < 3; i++) {
|
||||||
|
b *= b.ShiftBitsRight();
|
||||||
}
|
}
|
||||||
|
|
||||||
Halfblock Feistel::CompressionFunction(const Block& block) {
|
return b;
|
||||||
std::stringstream ss;
|
|
||||||
const std::string bits = block.ToString();
|
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> compressionMap;
|
|
||||||
compressionMap["0000"] = "10";
|
|
||||||
compressionMap["0001"] = "01";
|
|
||||||
compressionMap["0010"] = "11";
|
|
||||||
compressionMap["0011"] = "10";
|
|
||||||
compressionMap["0100"] = "11";
|
|
||||||
compressionMap["0101"] = "01";
|
|
||||||
compressionMap["0110"] = "00";
|
|
||||||
compressionMap["0111"] = "01";
|
|
||||||
compressionMap["1000"] = "11";
|
|
||||||
compressionMap["1001"] = "00";
|
|
||||||
compressionMap["1010"] = "11";
|
|
||||||
compressionMap["1011"] = "00";
|
|
||||||
compressionMap["1100"] = "11";
|
|
||||||
compressionMap["1101"] = "10";
|
|
||||||
compressionMap["1110"] = "00";
|
|
||||||
compressionMap["1111"] = "01";
|
|
||||||
|
|
||||||
// We have to half the bits!
|
|
||||||
for (std::size_t i = 0; i < Block::BLOCK_SIZE_BITS; i += 4) {
|
|
||||||
const std::string sub = bits.substr(i, 4);
|
|
||||||
ss << compressionMap[sub];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Halfblock(ss.str());
|
Halfblock Feistel::ReductionFunction(const Block& block) {
|
||||||
|
|
||||||
|
// Just apply a modulo operation, remapping a 32bit integer
|
||||||
|
// onto 16bit space (default configuration).
|
||||||
|
// Without saying, modulo is irreversible.
|
||||||
|
Halfblock hb;
|
||||||
|
for (std::size_t i = 0; i < 16; i++) {
|
||||||
|
hb[i] = block[i] % (1 << (Halfblock::CHUNK_SIZE_BITS - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Feistel::SBox(Block& block) {
|
||||||
|
|
||||||
|
std::uint8_t* curByte = (std::uint8_t*)(void*)block.Data();
|
||||||
|
|
||||||
|
// Iterate over all bytes in the block
|
||||||
|
for (std::size_t i = 0; i < Block::BLOCK_SIZE; i++) {
|
||||||
|
curByte++;
|
||||||
|
|
||||||
|
// Subsitute byte
|
||||||
|
*curByte = sboxLookup[*curByte];
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
std::string Feistel::SBox(const std::string& in) {
|
std::string Feistel::SBox(const std::string& in) {
|
||||||
static std::unordered_map<std::string, std::string> subMap;
|
static std::unordered_map<std::string, std::string> subMap;
|
||||||
static bool mapInitialized = false;
|
static bool mapInitialized = false;
|
||||||
@ -176,6 +181,7 @@ namespace Leonetienne::GCrypt {
|
|||||||
|
|
||||||
return subMap[in];
|
return subMap[in];
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void Feistel::GenerateRoundKeys(const Key& seedKey) {
|
void Feistel::GenerateRoundKeys(const Key& seedKey) {
|
||||||
// Clear initial key memory
|
// Clear initial key memory
|
||||||
|
Loading…
x
Reference in New Issue
Block a user