Files
chaos/Chaos/Cipher/Block/Mode/Ecb.hpp
T
hashlag bea8a84a4f
Chaos Ci / test-and-benchmark (push) Successful in 4m16s
Add ECB-mode encryptor draft implementation.
2026-07-05 21:34:36 +03:00

114 lines
3.3 KiB
C++

#ifndef CHAOS_CIPHER_BLOCK_MODE_ECB_HPP
#define CHAOS_CIPHER_BLOCK_MODE_ECB_HPP
#include <cstddef>
#include <cstdint>
#include "Service/ChaosException.hpp"
#include "Service/SeArray.hpp"
namespace Chaos::Cipher::Block::Mode
{
template<typename CipherT, typename PadderT>
class EcbMode
{
public:
class Encryptor
{
public:
Encryptor(const typename CipherT::Key & key)
: Encryptor_(key)
, BlockBytesPacked_(0)
{ }
static constexpr uint64_t PredictMaxUpdateOutput(uint64_t in)
{
return in + CipherT::BlockSize - 1;
}
static constexpr uint64_t PredictMaxFinishOutput()
{
return CipherT::BlockSize;
}
template<typename OutputIt, typename InputIt>
uint64_t Update(OutputIt outBegin, OutputIt outEnd,
InputIt inBegin, InputIt inEnd)
{
return UpdateImpl(outBegin, outEnd, inBegin, inEnd);
}
template<typename OutputIt>
uint64_t Finish(OutputIt outBegin, OutputIt outEnd)
{
PadderT::Pad(Block_.Begin() + BlockBytesPacked_, Block_.End());
Encryptor_.EncryptBlock(EncryptedBlock_.Begin(), EncryptedBlock_.End(),
Block_.Begin(), Block_.End());
EnsureCopy(outBegin, outEnd, EncryptedBlock_.Begin(), EncryptedBlock_.End());
return CipherT::BlockSize;
}
private:
typename CipherT::Encryptor Encryptor_;
uint64_t BlockBytesPacked_;
Service::SeArray<uint8_t, CipherT::BlockSize> Block_;
Service::SeArray<uint8_t, CipherT::BlockSize> EncryptedBlock_;
template<typename OutputIt, typename InputIt>
static OutputIt EnsureCopy(OutputIt outBegin, OutputIt outEnd,
InputIt inBegin, InputIt inEnd)
{
OutputIt out = outBegin;
InputIt in = inBegin;
for (; out != outEnd && in != inEnd; ++out, ++in)
{
*out = *in;
}
if (out == outEnd && in != inEnd)
{
throw Service::ChaosException("EcbMode<>::Encryptor: insufficient output "
"buffer size");
}
return out;
}
template<typename OutputIt, typename InputIt>
uint64_t UpdateImpl(OutputIt outBegin, OutputIt outEnd,
InputIt inBegin, InputIt inEnd)
{
uint64_t written = 0;
OutputIt out = outBegin;
for (InputIt in = inBegin; in != inEnd; ++in)
{
Block_[BlockBytesPacked_++] = *in;
if (BlockBytesPacked_ == Block_.Size())
{
BlockBytesPacked_ = 0;
Encryptor_.EncryptBlock(EncryptedBlock_.Begin(), EncryptedBlock_.End(),
Block_.Begin(), Block_.End());
out = EnsureCopy(out, outEnd, EncryptedBlock_.Begin(), EncryptedBlock_.End());
written += CipherT::BlockSize;
}
}
return written;
}
};
};
} // namespace Chaos::Cipher::Block::Mode
#endif // CHAOS_CIPHER_BLOCK_MODE_ECB_HPP