GCrypt/GCryptLib/src/GWrapper.cpp
2022-05-26 15:47:24 +02:00

159 lines
4.3 KiB
C++

#include "GCrypt/GWrapper.h"
#include "GCrypt/GCipher.h"
#include "GCrypt/Util.h"
#include <vector>
namespace Leonetienne::GCrypt {
std::string GWrapper::EncryptString(
const std::string& cleartext,
const Key& key)
{
// Recode the ascii-string to bits
const std::vector<Block> cleartext_blocks = StringToBitblocks(cleartext);
// Create cipher instance
GCipher cipher(key, GCipher::DIRECTION::ENCIPHER);
// Encrypt all blocks
std::vector<Block> ciphertext_blocks;
for (const Block& clearBlock : cleartext_blocks) {
ciphertext_blocks.emplace_back(cipher.Digest(clearBlock));
}
// Recode the ciphertext blocks to a hex-string
std::stringstream ss;
for (const Block& block : ciphertext_blocks) {
ss << block.ToHexString();
}
// Return it
return ss.str();
}
std::string GWrapper::DecryptString(
const std::string& ciphertext,
const Key& key)
{
// Make sure our ciphertext is a multiple of block size
if (ciphertext.length() % Block::BLOCK_SIZE*2 != 0) { // Two chars per byte
throw std::runtime_error("Leonetienne::GCrypt::GWrapper::DecryptString() received ciphertext of length not a multiple of block size.");
}
// Recode the hex-string to blocks
std::vector<Block> ciphertext_blocks;
ciphertext_blocks.reserve(ciphertext.length() / (Block::BLOCK_SIZE*2));
for (std::size_t i = 0; i < ciphertext.length(); i += Block::BLOCK_SIZE*2) {
Block block;
block.FromHexString(ciphertext.substr(i, Block::BLOCK_SIZE*2));
ciphertext_blocks.emplace_back(block);
}
// Create cipher instance
GCipher cipher(key, GCipher::DIRECTION::DECIPHER);
// Decrypt all blocks
std::vector<Block> cleartext_blocks;
for (const Block& cipherBlock : ciphertext_blocks) {
cleartext_blocks.emplace_back(cipher.Digest(cipherBlock));
}
// Recode the cleartext blocks to bytes
std::stringstream ss;
for (const Block& block : cleartext_blocks) {
ss << block.ToTextString();
}
// Return it
return ss.str();
}
bool GWrapper::EncryptFile(
const std::string& filename_in,
const std::string& filename_out,
const Key& key,
bool printProgressReport)
{
try {
// Read the file to blocks
const std::vector<Block> cleartext_blocks = ReadFileToBlocks(filename_in);
// Encrypt our cleartext blocks
std::vector<Block> ciphertext_blocks;
ciphertext_blocks.reserve(cleartext_blocks.size());
// Create cipher instance
GCipher cipher(key, GCipher::DIRECTION::ENCIPHER);
// Encrypt all blocks
for (const Block& clearBlock : cleartext_blocks) {
ciphertext_blocks.emplace_back(cipher.Digest(clearBlock));
}
// Write our ciphertext blocks to file
WriteBlocksToFile(filename_out, ciphertext_blocks);
return true;
}
catch (std::runtime_error&) {
return false;
}
}
bool GWrapper::DecryptFile(
const std::string& filename_in,
const std::string& filename_out,
const Key& key,
bool printProgressReport)
{
try {
// Read the file to blocks
const std::vector<Block> ciphertext_blocks = ReadFileToBlocks(filename_in);
// Decrypt our cleartext blocks
std::vector<Block> cleartext_blocks;
cleartext_blocks.reserve(ciphertext_blocks.size());
// Create cipher instance
GCipher cipher(key, GCipher::DIRECTION::DECIPHER);
// Decrypt all blocks
for (const Block& cipherBlock : ciphertext_blocks) {
cleartext_blocks.emplace_back(cipher.Digest(cipherBlock));
}
// Write our cleartext blocks to file
WriteBlocksToFile(filename_out, cleartext_blocks);
return true;
}
catch (std::runtime_error&) {
return false;
}
}
std::vector<Block> GWrapper::CipherBlocks(
const std::vector<Block>& data,
const Key& key,
const GCipher::DIRECTION direction)
{
// Create cipher instance
GCipher cipher(key, direction);
std::vector<Block> digested;
digested.reserve(data.size());
// Digest all our blocks
for (const Block& block : data) {
Block digestedBlock = cipher.Digest(block);
digested.emplace_back(digestedBlock);
}
// Return it
return digested;
}
}