Cipher now using new block class
This commit is contained in:
parent
b5369a3c32
commit
edbf36eb6d
@ -8,7 +8,7 @@ namespace Leonetienne::GCrypt {
|
|||||||
constexpr std::size_t BLOCK_SIZE = 512;
|
constexpr std::size_t BLOCK_SIZE = 512;
|
||||||
|
|
||||||
// MUST BE > 2
|
// MUST BE > 2
|
||||||
constexpr std::size_t N_ROUNDS = 10;
|
constexpr std::size_t N_ROUNDS = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +18,17 @@ namespace Leonetienne::GCrypt {
|
|||||||
return (denominator + (numerator % denominator)) % denominator;
|
return (denominator + (numerator % denominator)) % denominator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Block Shiftl(const Block& bits, const std::size_t amount) {
|
||||||
|
std::stringstream ss;
|
||||||
|
const std::string bitss = bits.ToString();
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < bitss.size(); i++) {
|
||||||
|
ss << bitss[Mod((int)(i + amount), (int)bitss.size())];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Block(ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
//! Will perform a wrapping left-bitshift on a bitset
|
//! Will perform a wrapping left-bitshift on a bitset
|
||||||
template <std::size_t T>
|
template <std::size_t T>
|
||||||
inline SecureBitset<T> Shiftl(const SecureBitset<T>& bits, const std::size_t amount) {
|
inline SecureBitset<T> Shiftl(const SecureBitset<T>& bits, const std::size_t amount) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef GCRYPT_VERSION_H
|
#ifndef GCRYPT_VERSION_H
|
||||||
#define GCRYPT_VERSION_H
|
#define GCRYPT_VERSION_H
|
||||||
|
|
||||||
#define GCRYPT_VERSION 0.232
|
#define GCRYPT_VERSION 0.233
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -62,17 +62,19 @@ namespace Leonetienne::GCrypt {
|
|||||||
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);
|
||||||
|
|
||||||
// Shift to left by 1
|
// Mix up the block a bit
|
||||||
//m_expanded = Shiftl(m_expanded, 1);
|
m_expanded.ShiftCellsRightInplace();
|
||||||
m_expanded = (m_expanded);
|
m_expanded.ShiftRowsUpInplace();
|
||||||
|
|
||||||
// Matrix-mult with key
|
// Matrix-mult with key (this is irreversible)
|
||||||
m_expanded *= key;
|
m_expanded *= key;
|
||||||
|
|
||||||
|
// Now do a bitshift
|
||||||
|
m_expanded.ShiftBitsLeftInplace();
|
||||||
|
|
||||||
// Non-linearly apply subsitution boxes
|
// Non-linearly apply subsitution boxes
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
const std::string m_str = m_expanded.ToString();
|
const std::string m_str = m_expanded.ToString();
|
||||||
@ -180,65 +182,32 @@ namespace Leonetienne::GCrypt {
|
|||||||
ZeroKeyMemory();
|
ZeroKeyMemory();
|
||||||
roundKeys = Keyset();
|
roundKeys = Keyset();
|
||||||
|
|
||||||
// Derive the initial two round keys
|
// Derive all round keys with simple matrix operations
|
||||||
|
roundKeys[0] = seedKey;
|
||||||
|
|
||||||
// Compress- substitute, and expand the seed key to form the initial and the second-initial round key
|
for (std::size_t i = 1; i < roundKeys.size(); i++) {
|
||||||
// This action is non-linear and irreversible, and thus strenghtens security.
|
|
||||||
Halfblock compressedSeed1 = CompressionFunction(seedKey);
|
|
||||||
//Halfblock compressedSeed2 = CompressionFunction(Shiftl(seedKey, 1)); // Shifting one key by 1 will result in a completely different compression
|
|
||||||
Halfblock compressedSeed2 = CompressionFunction((seedKey)); // Shifting one key by 1 will result in a completely different compression
|
|
||||||
|
|
||||||
// To add further confusion, let's shift seed1 by 1 aswell (after compression, but before substitution)
|
|
||||||
// but only if the total number of bits set are a multiple of 3
|
|
||||||
// if it is a multiple of 4, we'll shift it by 1 into the opposite direction
|
|
||||||
const std::size_t setBits1 = compressedSeed1.count();
|
|
||||||
|
|
||||||
if (setBits1 % 4 == 0) {
|
|
||||||
//compressedSeed1 = Shiftr(compressedSeed1, 1);
|
|
||||||
compressedSeed1 = (compressedSeed1);
|
|
||||||
}
|
|
||||||
else if (setBits1 % 3 == 0) {
|
|
||||||
compressedSeed1 = (compressedSeed1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now apply substitution
|
|
||||||
std::stringstream ssKey1;
|
|
||||||
std::stringstream ssKey2;
|
|
||||||
const std::string bitsKey1 = compressedSeed1.to_string();
|
|
||||||
const std::string bitsKey2 = compressedSeed2.to_string();
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < HALFBLOCK_SIZE; i += 4) {
|
|
||||||
ssKey1 << SBox(bitsKey1.substr(i, 4));
|
|
||||||
ssKey2 << SBox(bitsKey2.substr(i, 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
compressedSeed1 = Halfblock(ssKey1.str());
|
|
||||||
compressedSeed2 = Halfblock(ssKey2.str());
|
|
||||||
|
|
||||||
// Now extrapolate them to BLOCK_SIZE (key size) again
|
|
||||||
// Xor with the original seed key to get rid of the repititions caused by the expansion
|
|
||||||
roundKeys[0] = ExpansionFunction(compressedSeed1) ^ seedKey;
|
|
||||||
roundKeys[1] = ExpansionFunction(compressedSeed2) ^ seedKey;
|
|
||||||
|
|
||||||
// Now derive all other round keys
|
|
||||||
|
|
||||||
for (std::size_t i = 2; i < roundKeys.size(); i++) {
|
|
||||||
// Initialize new round key with last round key
|
// Initialize new round key with last round key
|
||||||
Block newKey = roundKeys[i - 1];
|
const Key& lastKey = roundKeys[i - 1];
|
||||||
|
roundKeys[i] = lastKey;
|
||||||
|
|
||||||
// Shift to left by how many bits are set, modulo 8
|
// Stir it good
|
||||||
//newKey = Shiftl(newKey, newKey.count() % 8); // This action is irreversible
|
roundKeys[i].ShiftRowsUpInplace();
|
||||||
newKey = (newKey); // This action is irreversible
|
|
||||||
|
|
||||||
// Split into two halfblocks,
|
// Bitshift and matrix-mult 3 times
|
||||||
// apply F() to one halfblock with rk[i-2],
|
// (each time jumbles it up pretty good)
|
||||||
// xor the other one with it
|
// This is irreversible
|
||||||
// and put them back together
|
roundKeys[i].ShiftBitsRightInplace();
|
||||||
auto halfkeys = FeistelSplit(newKey);
|
roundKeys[i] *= lastKey;
|
||||||
Halfblock halfkey1 = F(halfkeys.first, roundKeys[i - 2]);
|
roundKeys[i].ShiftBitsRightInplace();
|
||||||
Halfblock halfkey2 = halfkeys.second ^ halfkey1; // I know this is reversible, but it helps to diffuse future round keys.
|
roundKeys[i] *= lastKey;
|
||||||
|
roundKeys[i].ShiftBitsRightInplace();
|
||||||
|
roundKeys[i] *= lastKey;
|
||||||
|
|
||||||
roundKeys[i] = Key(FeistelCombine(halfkey1, halfkey2));
|
// Lastly, do apply some cell shifting, and other mutations
|
||||||
|
roundKeys[i].ShiftCellsRightInplace();
|
||||||
|
roundKeys[i] += lastKey;
|
||||||
|
roundKeys[i].ShiftColumnsRightInplace();
|
||||||
|
roundKeys[i] ^= lastKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user