Improved security
This commit is contained in:
parent
19660fc696
commit
5677d94e6a
@ -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 = 64;
|
constexpr std::size_t N_ROUNDS = 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,6 +25,9 @@ namespace Leonetienne::GCrypt {
|
|||||||
//! Will digest a data block, and return it
|
//! Will digest a data block, and return it
|
||||||
Block Digest(const Block& input);
|
Block Digest(const Block& input);
|
||||||
|
|
||||||
|
//! Will update the base key used
|
||||||
|
void SetKey(const Key& key);
|
||||||
|
|
||||||
void operator=(const GCipher& other);
|
void operator=(const GCipher& other);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -54,12 +54,13 @@ 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((Block)roundKeys.back());
|
GenerateRoundKeys((Key)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
|
||||||
@ -74,15 +75,13 @@ namespace Leonetienne::GCrypt {
|
|||||||
// Non-linearly apply subsitution boxes
|
// Non-linearly apply subsitution boxes
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
const std::string m_str = m_expanded.to_string();
|
const std::string m_str = m_expanded.to_string();
|
||||||
|
|
||||||
for (std::size_t i = 0; i < BLOCK_SIZE; i += 4) {
|
for (std::size_t i = 0; i < BLOCK_SIZE; i += 4) {
|
||||||
ss << SBox(m_str.substr(i, 4));
|
ss << SBox(m_str.substr(i, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_expanded = Block(ss.str());
|
m_expanded = Block(ss.str());
|
||||||
|
|
||||||
// Return the compressed version
|
// Return the compressed version, shifted by 3
|
||||||
return CompressionFunction(m_expanded);
|
return Shiftl(CompressionFunction(m_expanded), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Halfblock, Halfblock> Feistel::FeistelSplit(const Block& block) {
|
std::pair<Halfblock, Halfblock> Feistel::FeistelSplit(const Block& block) {
|
||||||
@ -124,13 +123,13 @@ namespace Leonetienne::GCrypt {
|
|||||||
std::unordered_map<std::string, std::string> compressionMap;
|
std::unordered_map<std::string, std::string> compressionMap;
|
||||||
compressionMap["0000"] = "10";
|
compressionMap["0000"] = "10";
|
||||||
compressionMap["0001"] = "01";
|
compressionMap["0001"] = "01";
|
||||||
compressionMap["0010"] = "10";
|
compressionMap["0010"] = "11";
|
||||||
compressionMap["0011"] = "10";
|
compressionMap["0011"] = "10";
|
||||||
compressionMap["0100"] = "11";
|
compressionMap["0100"] = "11";
|
||||||
compressionMap["0101"] = "01";
|
compressionMap["0101"] = "01";
|
||||||
compressionMap["0110"] = "00";
|
compressionMap["0110"] = "00";
|
||||||
compressionMap["0111"] = "11";
|
compressionMap["0111"] = "01";
|
||||||
compressionMap["1000"] = "01";
|
compressionMap["1000"] = "11";
|
||||||
compressionMap["1001"] = "00";
|
compressionMap["1001"] = "00";
|
||||||
compressionMap["1010"] = "11";
|
compressionMap["1010"] = "11";
|
||||||
compressionMap["1011"] = "00";
|
compressionMap["1011"] = "00";
|
||||||
|
@ -51,6 +51,12 @@ namespace Leonetienne::GCrypt {
|
|||||||
throw std::runtime_error("Unreachable branch reached.");
|
throw std::runtime_error("Unreachable branch reached.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GCipher::SetKey(const Key& key) {
|
||||||
|
feistel.SetKey(key);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void GCipher::operator=(const GCipher& other) {
|
void GCipher::operator=(const GCipher& other) {
|
||||||
direction = other.direction;
|
direction = other.direction;
|
||||||
feistel = other.feistel;
|
feistel = other.feistel;
|
||||||
|
@ -7,8 +7,8 @@ namespace Leonetienne::GCrypt {
|
|||||||
GHash::GHash() :
|
GHash::GHash() :
|
||||||
// Initialize our cipher with a static, but randomly distributed key.
|
// Initialize our cipher with a static, but randomly distributed key.
|
||||||
cipher(
|
cipher(
|
||||||
// Can't use Key::FromPassword here, because it depends on GHash.
|
// The key really does not matter, as it gets changed
|
||||||
// Instead use a hardcoded key.
|
// each time before digesting anything.
|
||||||
Key(StringToBitblock("nsoCZfvdqpRkeVTt9wzvPR3TT26peOW9E2kTHh3pdPCq2M7BpskvUljJHSrobUTI")),
|
Key(StringToBitblock("nsoCZfvdqpRkeVTt9wzvPR3TT26peOW9E2kTHh3pdPCq2M7BpskvUljJHSrobUTI")),
|
||||||
GCipher::DIRECTION::ENCIPHER
|
GCipher::DIRECTION::ENCIPHER
|
||||||
) {
|
) {
|
||||||
@ -18,6 +18,9 @@ namespace Leonetienne::GCrypt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GHash::DigestBlock(const Block& data) {
|
void GHash::DigestBlock(const Block& data) {
|
||||||
|
// Set the cipher key to the current data to be hashed
|
||||||
|
cipher.SetKey(Key(data));
|
||||||
|
|
||||||
// Encipher the current block, and xor it on the current hashsum
|
// Encipher the current block, and xor it on the current hashsum
|
||||||
block ^= cipher.Digest(data);
|
block ^= cipher.Digest(data);
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user