92 lines
2.2 KiB
C++
92 lines
2.2 KiB
C++
#include <iostream>
|
|
#include <vector>
|
|
#include <stdexcept>
|
|
#include "GCrypt/GCipher.h"
|
|
#include "GCrypt/Util.h"
|
|
#include "GCrypt/InitializationVector.h"
|
|
|
|
namespace Leonetienne::GCrypt {
|
|
|
|
GCipher::GCipher() {
|
|
}
|
|
|
|
GCipher::GCipher(const Key& key, const DIRECTION direction) :
|
|
direction { direction },
|
|
lastBlock(InitializationVector(key)), // Initialize our lastBlock with some deterministic initial value, based on the key
|
|
feistel(key)
|
|
{
|
|
isInitialized = true;
|
|
return;
|
|
}
|
|
|
|
void GCipher::Initialize(const Key& key, const DIRECTION direction) {
|
|
feistel = Feistel(key);
|
|
lastBlock = InitializationVector(key);
|
|
this->direction = direction;
|
|
isInitialized = true;
|
|
|
|
return;
|
|
}
|
|
|
|
Block GCipher::Digest(const Block& input) {
|
|
|
|
if (!isInitialized) {
|
|
throw std::runtime_error("Attempted to digest data on uninitialized GCipher!");
|
|
}
|
|
|
|
switch (direction) {
|
|
case DIRECTION::ENCIPHER: {
|
|
// Rename our input to cleartext
|
|
const Block& cleartext = input;
|
|
|
|
// First, xor our cleartext with the last block, and then encipher it
|
|
Block ciphertext = feistel.Encipher(cleartext ^ lastBlock);
|
|
|
|
// Now set our lastBlock to the ciphertext of this block
|
|
lastBlock = ciphertext;
|
|
|
|
// Now return the ciphertext
|
|
return ciphertext;
|
|
}
|
|
|
|
case DIRECTION::DECIPHER: {
|
|
// Rename our input into ciphertext
|
|
const Block& ciphertext = input;
|
|
|
|
// First, decipher our ciphertext, and then xor it with our last block
|
|
Block cleartext = feistel.Decipher(ciphertext) ^ lastBlock;
|
|
|
|
// Now set our lastBLock to the ciphertext of this block
|
|
lastBlock = ciphertext;
|
|
|
|
// Now return the cleartext
|
|
return cleartext;
|
|
}
|
|
}
|
|
|
|
throw std::runtime_error("Unreachable branch reached.");
|
|
}
|
|
|
|
void GCipher::SetKey(const Key& key) {
|
|
|
|
if (!isInitialized) {
|
|
throw std::runtime_error("Attempted to set key on uninitialized GCipher!");
|
|
}
|
|
|
|
feistel.SetKey(key);
|
|
|
|
return;
|
|
}
|
|
|
|
void GCipher::operator=(const GCipher& other) {
|
|
direction = other.direction;
|
|
feistel = other.feistel;
|
|
lastBlock = other.lastBlock;
|
|
isInitialized = other.isInitialized;
|
|
|
|
return;
|
|
}
|
|
|
|
}
|
|
|