Compare commits

..

42 Commits

Author SHA1 Message Date
hashlag
0647a7c3dc DesEncryptor/DesDecryptor: expose key type.
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m57s
2026-02-08 02:57:00 +03:00
hashlag
7c86d704b7 Merge branch 'block-expose-key-size'
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m54s
Expose block ciphers' key sizes for usage in compile-time context.
2026-02-07 18:14:09 +03:00
hashlag
9f6265395d DesCryptTests: Replace magic const 8 (where used as the key length) with DesCrypt::KeySize.
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m51s
2026-02-07 18:09:42 +03:00
hashlag
151c93560c Expose DES key size through DesCrypt, DesCrypt::Encryptor, DesCrypt::Decryptor. 2026-02-07 18:02:27 +03:00
hashlag
3059bd4c66 Make SeArray::Size() static. 2026-02-07 17:54:37 +03:00
hashlag
ccf1397595 Merge branch 'exception-tests'
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m56s
Add missing ChaosException tests.
2026-02-06 18:18:45 +03:00
hashlag
6a09d81ae2 Add ChaosExceptionTests.
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 2m2s
2026-02-06 18:05:57 +03:00
hashlag
b4f015f501 Compile tests with -Wunused -Werror=unused.
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m54s
Promotes cleaner and less error-prone code.
2026-02-05 16:16:38 +03:00
hashlag
95e74db6ec Perform aggregate zero-init instead of .fill(0) where appropriate.
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m50s
Simpler and more consistent code.
2026-02-05 00:40:55 +03:00
hashlag
ed22d29af0 Merge branch 'explicit-bounds'
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m50s
Harden against out-of-bounds writes.
2026-02-04 23:52:50 +03:00
hashlag
65eb51c133 Remove unused CrunchUInt64() overload.
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m57s
2026-02-04 23:47:45 +03:00
hashlag
b34fda75ef DesCryptTests: IteratorUsage tests: Add testcases with begin == end.
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m57s
2026-02-04 23:37:05 +03:00
hashlag
15d841893c IteratorUsage tests: Add some canary nulled space before begin.
Hardening against write-before-begin.
2026-02-04 23:31:14 +03:00
hashlag
5fd27cd7b5 Merge branch 'stream-bounds-tests' into explicit-bounds
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m50s
Add some past-the-end write hardening tests for stream ciphers.
2026-02-04 01:02:56 +03:00
hashlag
1bf91a90d0 Add Arc4CryptTests, DecryptOutIteratorUsageTest.
Harden against past-the-end write.
2026-02-04 01:01:54 +03:00
hashlag
2d64389d66 Add Arc4CryptTests, EncryptOutIteratorUsageTest.
Harden against past-the-end write.
2026-02-04 00:43:40 +03:00
hashlag
ccdf14d31a Add Arc4GenTests, GenerateOutIteratorUsageTest.
Harden against past-the-end write.
2026-02-04 00:25:15 +03:00
hashlag
9734f9a517 Merge branch 'block-exp-bounds' into explicit-bounds
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m49s
Implement explicit bounds requirements for block ciphers.
2026-02-02 01:51:58 +03:00
hashlag
3de69d3298 Fix assertion style.
It should be expectation-first...
2026-02-02 01:15:38 +03:00
hashlag
a0f17ea127 Decryptor: Require end of the output span to be indicated explicitly.
Usage becomes much less error-prone.
2026-02-02 01:10:22 +03:00
hashlag
67709e5361 Encryptor: Require end of the output span to be indicated explicitly.
Usage becomes much less error-prone.
2026-02-02 00:52:08 +03:00
hashlag
d194fef1af Mark all Block::Decryptor<> methods const.
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m42s
This allows for convenient usage of const Decryptor<Impl> &.
2026-02-01 00:24:50 +03:00
hashlag
cdcab2f4f7 Mark all Block::Encryptor<> methods const.
This allows for convenient usage of const Encryptor<Impl> &.
2026-01-31 23:56:25 +03:00
hashlag
a97826da88 Expose block sizes of block ciphers.
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m45s
Both via static data members and Encryptor/Decryptor interfaces.
Crucial for safe memory allocation routine.
2026-01-31 19:26:51 +03:00
hashlag
8897d7a910 Merge branch 'block-cipher'
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m43s
Introduce fixed CRTP interfaces for block cipher
encryption and decryption.
2026-01-31 18:50:10 +03:00
hashlag
73c455901b Introduce Block::Decryptor<> CRTP base class.
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m43s
Inherit DesDecryptor from it.
2026-01-31 18:35:23 +03:00
hashlag
4cf79b61ad Introduce Block::Encryptor<> CRTP base class.
Inherit DesEncryptor from it.
2026-01-31 18:12:43 +03:00
hashlag
ba70abd2af Rename DesCrypt::Encryptor --> DesEncryptor, DesCrypt::Decryptor --> DesDecryptor.
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m43s
Maintain naming consistency with Hash subproject.
2026-01-31 17:22:14 +03:00
hashlag
9a3b6edfc3 Rename DesCrypt::Encryptor --> DesEncryptor, DesCrypt::Decryptor --> DesDecryptor.
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m46s
Maintain naming consistency with Hash subproject.
2026-01-31 17:18:25 +03:00
hashlag
3c98b75986 Create dedicated Cipher/Block directory for block ciphers
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m41s
Move Des there.
2026-01-30 01:01:48 +03:00
hashlag
b5d1f9a6fc Make CRTP base classes ctors protected
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m39s
This forbids to create base class instances which direct usage could lead to UB.
2026-01-30 00:44:24 +03:00
hashlag
2c9200ab21 Merge branch 'mac-bench'
All checks were successful
Chaos Ci / test-and-benchmark (push) Successful in 1m44s
Add benchmarks for MAC algorithms.
2026-01-29 23:43:28 +03:00
hashlag
6246bf4538 Add HmacSha1_PartialUpdate100Bench 2026-01-29 23:40:39 +03:00
hashlag
78c59dc668 Add HmacSha1_ReuseBench 2026-01-29 23:39:00 +03:00
hashlag
d4fa11795b Add HmacSha1_CreateComputeDeleteBench 2026-01-29 23:38:22 +03:00
hashlag
3780586e63 Add HmacMd5_PartialUpdate100Bench 2026-01-29 23:34:53 +03:00
hashlag
cc9963f1ca Add HmacMd5_ReuseBench 2026-01-29 23:34:20 +03:00
hashlag
05533e7c6b Add HmacMd5_CreateComputeDeleteBench 2026-01-29 23:33:45 +03:00
hashlag
961a521c57 Add HmacBenches.cpp to ChaosBenches_SOURCE 2026-01-29 23:31:15 +03:00
hashlag
029055f9a3 Add HmacMd4_PartialUpdate100Bench 2026-01-29 23:30:16 +03:00
hashlag
b5f86b5633 Add HmacMd4_ReuseBench 2026-01-29 23:29:33 +03:00
hashlag
0bc29c86e5 Add HmacMd4_CreateComputeDeleteBench 2026-01-29 23:16:07 +03:00
14 changed files with 733 additions and 178 deletions

View File

@@ -0,0 +1,46 @@
#ifndef CHAOS_CIPHER_BLOCK_DECRYPTOR_HPP
#define CHAOS_CIPHER_BLOCK_DECRYPTOR_HPP
namespace Chaos::Cipher::Block
{
template<typename T>
class Decryptor
{
public:
template<typename OutputIt, typename InputIt>
void DecryptBlock(OutputIt outBegin, OutputIt outEnd,
InputIt inBegin, InputIt inEnd) const
{
Impl().DecryptBlock(outBegin, outEnd, inBegin, inEnd);
}
template<typename Block>
auto DecryptBlock(Block block) const
{
return Impl().DecryptBlock(block);
}
auto GetBlockSize() const
{
return Impl().GetBlockSize();
}
protected:
Decryptor() = default;
private:
const T & Impl() const
{
return static_cast<const T &>(*this);
}
T & Impl()
{
return static_cast<T &>(*this);
}
};
} // namespace Chaos::Cipher::Block
#endif // CHAOS_CIPHER_BLOCK_DECRYPTOR_HPP

View File

@@ -1,5 +1,5 @@
#ifndef CHAOS_CIPHER_DES_DESCRYPT_HPP #ifndef CHAOS_CIPHER_BLOCK_DES_DESCRYPT_HPP
#define CHAOS_CIPHER_DES_DESCRYPT_HPP #define CHAOS_CIPHER_BLOCK_DES_DESCRYPT_HPP
#include <algorithm> #include <algorithm>
#include <utility> #include <utility>
@@ -7,7 +7,10 @@
#include "Service/ChaosException.hpp" #include "Service/ChaosException.hpp"
#include "Service/SeArray.hpp" #include "Service/SeArray.hpp"
namespace Chaos::Cipher::Des::Inner_ #include "Cipher/Block/Encryptor.hpp"
#include "Cipher/Block/Decryptor.hpp"
namespace Chaos::Cipher::Block::Des::Inner_
{ {
struct Bitwise struct Bitwise
@@ -80,11 +83,12 @@ struct Bitwise
} }
template<typename OutputIt> template<typename OutputIt>
static void CrunchUInt64(OutputIt out, uint64_t value) static void CrunchUInt64(OutputIt outBegin, OutputIt outEnd, uint64_t value)
{ {
for (int_fast8_t i = 0; i < 8; ++i) int_fast8_t i = 0;
for (OutputIt out = outBegin; i < 8 && out != outEnd; ++i, ++out)
{ {
*out++ = (value >> (56 - (i * 8))) & Mask<8>(); *out = (value >> (56 - (i * 8))) & Mask<8>();
} }
} }
}; };
@@ -184,15 +188,20 @@ private:
} }
}; };
} // namespace Chaos::Cipher::Des::Inner_ } // namespace Chaos::Cipher::Block::Des::Inner_
namespace Chaos::Cipher::Des namespace Chaos::Cipher::Block::Des
{ {
class DesCrypt class DesCrypt
{ {
public: public:
using Block = uint64_t; using Block = uint64_t;
static constexpr size_t BlockSize = 8;
static constexpr size_t KeySize = 8;
static_assert(BlockSize == sizeof(Block));
static_assert(KeySize == Inner_::RawKey::Size());
DesCrypt() = delete; DesCrypt() = delete;
@@ -221,15 +230,20 @@ public:
Inner_::RawKey Key_; Inner_::RawKey Key_;
}; };
class Encryptor class DesEncryptor : public Encryptor<DesEncryptor>
{ {
public: public:
Encryptor(const Key & key) using Key = DesCrypt::Key;
static constexpr size_t BlockSize = DesCrypt::BlockSize;
static constexpr size_t KeySize = DesCrypt::KeySize;
DesEncryptor(const Key & key)
: Schedule_(Inner_::KeySchedule::Direction::Encrypt, key.Key_) : Schedule_(Inner_::KeySchedule::Direction::Encrypt, key.Key_)
{ } { }
template<typename OutputIt, typename InputIt> template<typename OutputIt, typename InputIt>
void EncryptBlock(OutputIt out, InputIt inBegin, InputIt inEnd) void EncryptBlock(OutputIt outBegin, OutputIt outEnd,
InputIt inBegin, InputIt inEnd) const
{ {
RawBlockArray block; RawBlockArray block;
@@ -244,27 +258,37 @@ public:
block.End()), block.End()),
Schedule_); Schedule_);
Inner_::Bitwise::CrunchUInt64(out, encrypted); Inner_::Bitwise::CrunchUInt64(outBegin, outEnd, encrypted);
} }
Block EncryptBlock(Block block) Block EncryptBlock(Block block) const
{ {
return DesCrypt::ProcessBlock(block, Schedule_); return DesCrypt::ProcessBlock(block, Schedule_);
} }
constexpr size_t GetBlockSize() const
{
return BlockSize;
}
private: private:
Inner_::KeySchedule Schedule_; Inner_::KeySchedule Schedule_;
}; };
class Decryptor class DesDecryptor : public Decryptor<DesDecryptor>
{ {
public: public:
Decryptor(const Key & key) using Key = DesCrypt::Key;
static constexpr size_t BlockSize = DesCrypt::BlockSize;
static constexpr size_t KeySize = DesCrypt::KeySize;
DesDecryptor(const Key & key)
: Schedule_(Inner_::KeySchedule::Direction::Decrypt, key.Key_) : Schedule_(Inner_::KeySchedule::Direction::Decrypt, key.Key_)
{ } { }
template<typename OutputIt, typename InputIt> template<typename OutputIt, typename InputIt>
void DecryptBlock(OutputIt out, InputIt inBegin, InputIt inEnd) void DecryptBlock(OutputIt outBegin, OutputIt outEnd,
InputIt inBegin, InputIt inEnd) const
{ {
RawBlockArray block; RawBlockArray block;
@@ -279,14 +303,19 @@ public:
block.End()), block.End()),
Schedule_); Schedule_);
Inner_::Bitwise::CrunchUInt64(out, decrypted); Inner_::Bitwise::CrunchUInt64(outBegin, outEnd, decrypted);
} }
Block DecryptBlock(Block block) Block DecryptBlock(Block block) const
{ {
return DesCrypt::ProcessBlock(block, Schedule_); return DesCrypt::ProcessBlock(block, Schedule_);
} }
constexpr size_t GetBlockSize() const
{
return BlockSize;
}
private: private:
Inner_::KeySchedule Schedule_; Inner_::KeySchedule Schedule_;
}; };
@@ -483,6 +512,6 @@ private:
} }
}; };
} // namespace Chaos::Cipher::Des } // namespace Chaos::Cipher::Block::Des
#endif // CHAOS_CIPHER_DES_DESCRYPT_HPP #endif // CHAOS_CIPHER_BLOCK_DES_DESCRYPT_HPP

View File

@@ -0,0 +1,46 @@
#ifndef CHAOS_CIPHER_BLOCK_ENCRYPTOR_HPP
#define CHAOS_CIPHER_BLOCK_ENCRYPTOR_HPP
namespace Chaos::Cipher::Block
{
template<typename T>
class Encryptor
{
public:
template<typename OutputIt, typename InputIt>
void EncryptBlock(OutputIt outBegin, OutputIt outEnd,
InputIt inBegin, InputIt inEnd) const
{
Impl().EncryptBlock(outBegin, outEnd, inBegin, inEnd);
}
template<typename Block>
auto EncryptBlock(Block block) const
{
return Impl().EncryptBlock(block);
}
auto GetBlockSize() const
{
return Impl().GetBlockSize();
}
protected:
Encryptor() = default;
private:
const T & Impl() const
{
return static_cast<const T &>(*this);
}
T & Impl()
{
return static_cast<T &>(*this);
}
};
} // namespace Chaos::Cipher::Block
#endif // CHAOS_CIPHER_BLOCK_ENCRYPTOR_HPP

View File

@@ -20,6 +20,9 @@ public:
return Impl().ToHexString(); return Impl().ToHexString();
} }
protected:
Hash() = default;
private: private:
const T & Impl() const const T & Impl() const
{ {

View File

@@ -24,6 +24,9 @@ public:
return Impl().Finish(); return Impl().Finish();
} }
protected:
Hasher() = default;
private: private:
const T & Impl() const const T & Impl() const
{ {

View File

@@ -58,11 +58,6 @@ public:
return Storage_.data() + Storage_.size(); return Storage_.data() + Storage_.size();
} }
constexpr size_t Size() const noexcept
{
return Storage_.size();
}
void Fill(const T & value) void Fill(const T & value)
{ {
Storage_.fill(value); Storage_.fill(value);
@@ -73,6 +68,11 @@ public:
EraseImpl(); EraseImpl();
} }
static constexpr size_t Size() noexcept
{
return S;
}
private: private:
std::array<T, S> Storage_; std::array<T, S> Storage_;

View File

@@ -15,7 +15,8 @@ FetchContent_MakeAvailable(googlebenchmark)
set(ChaosBenches_SOURCE BenchmarkMain.cpp set(ChaosBenches_SOURCE BenchmarkMain.cpp
Hash/Md4HasherBenches.cpp Hash/Md4HasherBenches.cpp
Hash/Md5HasherBenches.cpp Hash/Md5HasherBenches.cpp
Hash/Sha1HasherBenches.cpp) Hash/Sha1HasherBenches.cpp
Mac/HmacBenches.cpp)
add_executable(ChaosBenches ${ChaosBenches_SOURCE}) add_executable(ChaosBenches ${ChaosBenches_SOURCE})
target_link_libraries(ChaosBenches benchmark::benchmark) target_link_libraries(ChaosBenches benchmark::benchmark)

View File

@@ -0,0 +1,173 @@
#include <benchmark/benchmark.h>
#include <cstring>
#include "Mac/Hmac.hpp"
#include "Hash/Md4.hpp"
#include "Hash/Md5.hpp"
#include "Hash/Sha1.hpp"
using namespace Chaos::Mac::Hmac;
using namespace Chaos::Hash::Md4;
using namespace Chaos::Hash::Md5;
using namespace Chaos::Hash::Sha1;
static const char * KEY_BEGIN = "Niccolo01234567";
static const size_t KEY_LEN = strlen(KEY_BEGIN);
static const char * KEY_END = KEY_BEGIN + KEY_LEN;
static const char * DATA_BEGIN
= "All states, all powers, that have held and hold rule over men have been and are either republics or principalities.\n"
"Principalities are either hereditary, in which the family has been long established; or they are new.\n"
"The new are either entirely new, as was Milan to Francesco Sforza, or they are, as it were, members annexed to the hereditary state of the "
"prince who has acquired them, as was the kingdom of Naples to that of the King of Spain.\n"
"Such dominions thus acquired are either accustomed to live under a prince, or to live in freedom; and are acquired either by the arms of the "
"prince himself, or of others, or else by fortune or by ability.";
static const size_t DATA_LEN = strlen(DATA_BEGIN);
static const char * DATA_END = DATA_BEGIN + DATA_LEN;
static void HmacMd4_CreateComputeDeleteBench(benchmark::State & state)
{
for (auto _ : state)
{
Hmac<Md4Hasher> hmac(KEY_BEGIN, KEY_END);
hmac.Update(DATA_BEGIN, DATA_END);
Md4Hash result = hmac.Finish();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(HmacMd4_CreateComputeDeleteBench);
static void HmacMd4_ReuseBench(benchmark::State & state)
{
Hmac<Md4Hasher> hmac;
for (auto _ : state)
{
hmac.Rekey(KEY_BEGIN, KEY_END);
hmac.Update(DATA_BEGIN, DATA_END);
Md4Hash result = hmac.Finish();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(HmacMd4_ReuseBench);
static void HmacMd4_PartialUpdate100Bench(benchmark::State & state)
{
for (auto _ : state)
{
Hmac<Md4Hasher> hmac(KEY_BEGIN, KEY_END);
for (int i = 0; i < 100; ++i)
{
hmac.Update(DATA_BEGIN, DATA_END);
}
Md4Hash result = hmac.Finish();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(HmacMd4_PartialUpdate100Bench);
static void HmacMd5_CreateComputeDeleteBench(benchmark::State & state)
{
for (auto _ : state)
{
Hmac<Md5Hasher> hmac(KEY_BEGIN, KEY_END);
hmac.Update(DATA_BEGIN, DATA_END);
Md5Hash result = hmac.Finish();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(HmacMd5_CreateComputeDeleteBench);
static void HmacMd5_ReuseBench(benchmark::State & state)
{
Hmac<Md5Hasher> hmac;
for (auto _ : state)
{
hmac.Rekey(KEY_BEGIN, KEY_END);
hmac.Update(DATA_BEGIN, DATA_END);
Md5Hash result = hmac.Finish();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(HmacMd5_ReuseBench);
static void HmacMd5_PartialUpdate100Bench(benchmark::State & state)
{
for (auto _ : state)
{
Hmac<Md5Hasher> hmac(KEY_BEGIN, KEY_END);
for (int i = 0; i < 100; ++i)
{
hmac.Update(DATA_BEGIN, DATA_END);
}
Md5Hash result = hmac.Finish();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(HmacMd5_PartialUpdate100Bench);
static void HmacSha1_CreateComputeDeleteBench(benchmark::State & state)
{
for (auto _ : state)
{
Hmac<Sha1Hasher> hmac(KEY_BEGIN, KEY_END);
hmac.Update(DATA_BEGIN, DATA_END);
Sha1Hash result = hmac.Finish();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(HmacSha1_CreateComputeDeleteBench);
static void HmacSha1_ReuseBench(benchmark::State & state)
{
Hmac<Sha1Hasher> hmac;
for (auto _ : state)
{
hmac.Rekey(KEY_BEGIN, KEY_END);
hmac.Update(DATA_BEGIN, DATA_END);
Sha1Hash result = hmac.Finish();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(HmacSha1_ReuseBench);
static void HmacSha1_PartialUpdate100Bench(benchmark::State & state)
{
for (auto _ : state)
{
Hmac<Sha1Hasher> hmac(KEY_BEGIN, KEY_END);
for (int i = 0; i < 100; ++i)
{
hmac.Update(DATA_BEGIN, DATA_END);
}
Sha1Hash result = hmac.Finish();
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(HmacSha1_PartialUpdate100Bench);

View File

@@ -18,7 +18,8 @@ set(ChaosTests_SOURCE Hash/Md4HasherTests.cpp
Cipher/Arc4GenTests.cpp Cipher/Arc4GenTests.cpp
Cipher/Arc4CryptTests.cpp Cipher/Arc4CryptTests.cpp
Cipher/DesCryptTests.cpp Cipher/DesCryptTests.cpp
Service/SeArrayTests.cpp) Service/SeArrayTests.cpp
Service/ChaosExceptionTests.cpp)
add_executable(ChaosTests ${ChaosTests_SOURCE}) add_executable(ChaosTests ${ChaosTests_SOURCE})
target_link_libraries(ChaosTests gtest gtest_main) target_link_libraries(ChaosTests gtest gtest_main)
@@ -26,6 +27,8 @@ target_include_directories(ChaosTests PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Chaos> $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Chaos>
) )
target_compile_options(ChaosTests PRIVATE -Wunused -Werror=unused)
if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(ChaosTests PRIVATE --coverage) target_compile_options(ChaosTests PRIVATE --coverage)
target_link_options(ChaosTests PRIVATE --coverage) target_link_options(ChaosTests PRIVATE --coverage)

View File

@@ -58,11 +58,8 @@ TEST(Arc4CryptTests, UninitializedArc4CryptTest)
Arc4Crypt arc4; Arc4Crypt arc4;
{ {
std::array<uint8_t, 10> in; std::array<uint8_t, 10> in = {};
in.fill(0); std::array<uint8_t, 10> out = {};
std::array<uint8_t, 10> out;
out.fill(0);
ASSERT_THROW(arc4.Encrypt(out.begin(), in.begin(), in.size()), Chaos::Service::ChaosException); ASSERT_THROW(arc4.Encrypt(out.begin(), in.begin(), in.size()), Chaos::Service::ChaosException);
ASSERT_THROW(arc4.Decrypt(out.begin(), in.begin(), in.size()), Chaos::Service::ChaosException); ASSERT_THROW(arc4.Decrypt(out.begin(), in.begin(), in.size()), Chaos::Service::ChaosException);
@@ -107,3 +104,115 @@ TEST(Arc4CryptTests, RekeyTest)
ciphertext); ciphertext);
} }
} }
TEST(Arc4CryptTests, EncryptOutIteratorUsageTest)
{
const std::vector<uint8_t> data = StrToU8Vec("The quick brown fox jumps over the lazy dog.");
{
std::array<uint8_t, 5> key = { 0x01, 0x02, 0x03, 0x04, 0x05 };
Arc4Crypt crypt(key.begin(), key.end());
std::array<uint8_t, 47> out = {};
std::array<uint8_t, 47> expected =
{
0x00, 0x00, 0x00,
0xe6, 0x51, 0x06, 0x25, 0x81, 0x48, 0xa9, 0x44, 0xa7, 0xe3, 0x30,
0x38, 0x65, 0x66, 0x76, 0x88, 0x0f, 0xed, 0xec, 0x6f, 0x72, 0x89,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
crypt.Encrypt(out.begin() + 3, data.begin(), 22);
ASSERT_EQ(expected, out);
}
{
std::array<uint8_t, 5> key = { 0x01, 0x02, 0x03, 0x04, 0x05 };
Arc4Crypt crypt(key.begin(), key.end());
std::array<uint8_t, 47> out = {};
std::array<uint8_t, 47> expected =
{
0x00, 0x00, 0x00,
0xe6, 0x51, 0x06, 0x25, 0x81, 0x48, 0xa9, 0x44, 0xa7, 0xe3, 0x30,
0x38, 0x65, 0x66, 0x76, 0x88, 0x0f, 0xed, 0xec, 0x6f, 0x72, 0x89,
0xef, 0xa5, 0xfa, 0xe4, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
crypt.Encrypt(out.begin() + 3, data.begin(), 27);
ASSERT_EQ(expected, out);
}
{
std::array<uint8_t, 5> key = { 0x01, 0x02, 0x03, 0x04, 0x05 };
Arc4Crypt crypt(key.begin(), key.end());
std::array<uint8_t, 44> out = {};
std::array<uint8_t, 44> expected = {};
crypt.Encrypt(out.begin() + 3, data.begin(), 0);
ASSERT_EQ(expected, out);
}
}
TEST(Arc4CryptTests, DecryptOutIteratorUsageTest)
{
const std::array<uint8_t, 14> data = { 0x45, 0xA0, 0x1F, 0x64, 0x5F, 0xC3, 0x5B,
0x38, 0x35, 0x52, 0x54, 0x4B, 0x9B, 0xF5 };
const std::vector<uint8_t> key = StrToU8Vec("Secret");
{
Arc4Crypt crypt(key.begin(), key.end());
std::array<uint8_t, 17> out = {};
std::array<uint8_t, 17> expected =
{
0x00, 0x00, 0x00,
'A', 't', 't', 'a', 'c', 'k', ' ', 'a', 't', ' ', 'd', 'a',
0x00, 0x00
};
crypt.Decrypt(out.begin() + 3, data.begin(), 12);
ASSERT_EQ(expected, out);
}
{
Arc4Crypt crypt(key.begin(), key.end());
std::array<uint8_t, 17> out = {};
std::array<uint8_t, 17> expected =
{
0x00, 0x00, 0x00,
'A', 't', 't', 'a', 'c', 'k', ' ',
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
crypt.Decrypt(out.begin() + 3, data.begin(), 7);
ASSERT_EQ(expected, out);
}
{
Arc4Crypt crypt(key.begin(), key.end());
std::array<uint8_t, 14> out = {};
std::array<uint8_t, 14> expected = {};
crypt.Decrypt(out.begin() + 3, data.begin(), 0);
ASSERT_EQ(expected, out);
}
}

View File

@@ -353,3 +353,56 @@ TEST(Arc4GenTests, UninitializedGenTest)
ASSERT_THROW(gen.Drop(256), Chaos::Service::ChaosException); ASSERT_THROW(gen.Drop(256), Chaos::Service::ChaosException);
} }
} }
TEST(Arc4GenTests, GenerateOutIteratorUsageTest)
{
{
uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
Arc4Gen gen(key, key + std::size(key));
std::array<uint8_t, 23> out = {};
std::array<uint8_t, 23> expected =
{
0x00, 0x00, 0x00,
0xb2, 0x39, 0x63, 0x05, 0xf0, 0x3d, 0xc0, 0x27,
0xcc, 0xc3, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
gen.Generate(out.begin() + 3, 11);
ASSERT_EQ(expected, out);
}
{
uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
Arc4Gen gen(key, key + std::size(key));
std::array<uint8_t, 23> out = {};
std::array<uint8_t, 23> expected =
{
0x00, 0x00, 0x00,
0xb2, 0x39, 0x63, 0x05, 0xf0, 0x3d, 0xc0, 0x27,
0xcc, 0xc3, 0x52, 0x4a, 0x0a, 0x11, 0x18, 0xa8,
0x69, 0x82, 0x00, 0x00
};
gen.Generate(out.begin() + 3, 18);
ASSERT_EQ(expected, out);
}
{
uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
Arc4Gen gen(key, key + std::size(key));
std::array<uint8_t, 20> out = {};
std::array<uint8_t, 20> expected = {};
gen.Generate(out.begin() + 3, 0);
ASSERT_EQ(expected, out);
}
}

View File

@@ -1,8 +1,10 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "Cipher/Des/DesCrypt.hpp" #include "Cipher/Block/Des/DesCrypt.hpp"
#include "Cipher/Block/Encryptor.hpp"
using namespace Chaos::Cipher::Des; using namespace Chaos::Cipher::Block::Des;
using namespace Chaos::Cipher::Block;
TEST(DesCryptTests, KeyScheduleTest) TEST(DesCryptTests, KeyScheduleTest)
{ {
@@ -41,15 +43,14 @@ TEST(DesCryptTests, EncryptTest)
{ {
struct Helper struct Helper
{ {
std::array<uint8_t, 8> operator()(const std::array<uint8_t, 8> & data, std::array<uint8_t, DesCrypt::BlockSize> operator()(const std::array<uint8_t, DesCrypt::BlockSize> & data,
const std::array<uint8_t, 8> & key) const const std::array<uint8_t, DesCrypt::KeySize> & key) const
{ {
std::array<uint8_t, 8> result; std::array<uint8_t, DesCrypt::BlockSize> result = {};
result.fill(0);
DesCrypt::Key desKey(key.begin(), key.end()); DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::Encryptor enc(desKey); DesCrypt::DesEncryptor enc(desKey);
enc.EncryptBlock(result.begin(), data.begin(), data.end()); enc.EncryptBlock(result.begin(), result.end(), data.begin(), data.end());
return result; return result;
} }
@@ -58,28 +59,28 @@ TEST(DesCryptTests, EncryptTest)
Helper des; Helper des;
{ {
std::array<uint8_t, 8> data = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; std::array<uint8_t, DesCrypt::BlockSize> data = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
std::array<uint8_t, 8> key = { 0x13, 0x34, 0x57, 0x79, 0x9b, 0xbc, 0xdf, 0xf1 }; std::array<uint8_t, DesCrypt::KeySize> key = { 0x13, 0x34, 0x57, 0x79, 0x9b, 0xbc, 0xdf, 0xf1 };
std::array<uint8_t, 8> expected = { 0x85, 0xe8, 0x13, 0x54, 0x0f, 0x0a, 0xb4, 0x05 }; std::array<uint8_t, DesCrypt::BlockSize> expected = { 0x85, 0xe8, 0x13, 0x54, 0x0f, 0x0a, 0xb4, 0x05 };
ASSERT_EQ(expected, des(data, key)); ASSERT_EQ(expected, des(data, key));
} }
{ {
std::array<uint8_t, 8> data = { 0xaa, 0xf3, 0x83, 0x16, 0x2d, 0x2e, 0x6b, 0xcb }; std::array<uint8_t, DesCrypt::BlockSize> data = { 0xaa, 0xf3, 0x83, 0x16, 0x2d, 0x2e, 0x6b, 0xcb };
std::array<uint8_t, 8> key = { 0x44, 0xbf, 0x32, 0x19, 0x99, 0x25, 0x81, 0x51 }; std::array<uint8_t, DesCrypt::KeySize> key = { 0x44, 0xbf, 0x32, 0x19, 0x99, 0x25, 0x81, 0x51 };
std::array<uint8_t, 8> expected = { 0x07, 0xe8, 0x7f, 0xaa, 0xb3, 0x17, 0x13, 0x18 }; std::array<uint8_t, DesCrypt::BlockSize> expected = { 0x07, 0xe8, 0x7f, 0xaa, 0xb3, 0x17, 0x13, 0x18 };
ASSERT_EQ(expected, des(data, key)); ASSERT_EQ(expected, des(data, key));
} }
{ {
std::array<uint8_t, 8> data = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0xa7, 0x93, 0x44 }; std::array<uint8_t, DesCrypt::BlockSize> data = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0xa7, 0x93, 0x44 };
std::array<uint8_t, 8> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab }; std::array<uint8_t, DesCrypt::KeySize> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab };
std::array<uint8_t, 8> expected = { 0x42, 0x27, 0x88, 0xa6, 0x7b, 0x6c, 0x18, 0xed }; std::array<uint8_t, DesCrypt::BlockSize> expected = { 0x42, 0x27, 0x88, 0xa6, 0x7b, 0x6c, 0x18, 0xed };
ASSERT_EQ(expected, des(data, key)); ASSERT_EQ(expected, des(data, key));
} }
@@ -90,10 +91,10 @@ TEST(DesCryptTests, EncryptUInt64BlockTest)
struct Helper struct Helper
{ {
uint64_t operator()(uint64_t data, uint64_t operator()(uint64_t data,
const std::array<uint8_t, 8> & key) const const std::array<uint8_t, DesCrypt::KeySize> & key) const
{ {
DesCrypt::Key desKey(key.begin(), key.end()); DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::Encryptor enc(desKey); DesCrypt::DesEncryptor enc(desKey);
return enc.EncryptBlock(data); return enc.EncryptBlock(data);
} }
@@ -103,7 +104,7 @@ TEST(DesCryptTests, EncryptUInt64BlockTest)
{ {
uint64_t data = 0x0123456789abcdef; uint64_t data = 0x0123456789abcdef;
std::array<uint8_t, 8> key = { 0x13, 0x34, 0x57, 0x79, 0x9b, 0xbc, 0xdf, 0xf1 }; std::array<uint8_t, DesCrypt::KeySize> key = { 0x13, 0x34, 0x57, 0x79, 0x9b, 0xbc, 0xdf, 0xf1 };
uint64_t expected = 0x85e813540f0ab405; uint64_t expected = 0x85e813540f0ab405;
@@ -112,7 +113,7 @@ TEST(DesCryptTests, EncryptUInt64BlockTest)
{ {
uint64_t data = 0xaaf383162d2e6bcb; uint64_t data = 0xaaf383162d2e6bcb;
std::array<uint8_t, 8> key = { 0x44, 0xbf, 0x32, 0x19, 0x99, 0x25, 0x81, 0x51 }; std::array<uint8_t, DesCrypt::KeySize> key = { 0x44, 0xbf, 0x32, 0x19, 0x99, 0x25, 0x81, 0x51 };
uint64_t expected = 0x07e87faab3171318; uint64_t expected = 0x07e87faab3171318;
@@ -121,7 +122,7 @@ TEST(DesCryptTests, EncryptUInt64BlockTest)
{ {
uint64_t data = 0xe51a9fd419a79344; uint64_t data = 0xe51a9fd419a79344;
std::array<uint8_t, 8> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab }; std::array<uint8_t, DesCrypt::KeySize> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab };
uint64_t expected = 0x422788a67b6c18ed; uint64_t expected = 0x422788a67b6c18ed;
@@ -137,11 +138,11 @@ TEST(DesCryptTests, EncryptShortDataTest)
const std::vector<uint8_t> & key) const std::vector<uint8_t> & key)
{ {
std::vector<uint8_t> result; std::vector<uint8_t> result;
result.resize(8, 0); result.resize(DesCrypt::BlockSize, 0);
DesCrypt::Key desKey(key.begin(), key.end()); DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::Encryptor enc(desKey); DesCrypt::DesEncryptor enc(desKey);
enc.EncryptBlock(result.begin(), data.begin(), data.end()); enc.EncryptBlock(result.begin(), result.end(), data.begin(), data.end());
return result; return result;
} }
@@ -171,11 +172,11 @@ TEST(DesCryptTests, EncryptLongDataTest)
const std::vector<uint8_t> & key) const std::vector<uint8_t> & key)
{ {
std::vector<uint8_t> result; std::vector<uint8_t> result;
result.resize(8, 0); result.resize(DesCrypt::BlockSize, 0);
DesCrypt::Key desKey(key.begin(), key.end()); DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::Encryptor enc(desKey); DesCrypt::DesEncryptor enc(desKey);
enc.EncryptBlock(result.begin(), data.begin(), data.end()); enc.EncryptBlock(result.begin(), result.end(), data.begin(), data.end());
return result; return result;
} }
@@ -201,15 +202,14 @@ TEST(DesCryptTests, DecryptTest)
{ {
struct Helper struct Helper
{ {
std::array<uint8_t, 8> operator()(const std::array<uint8_t, 8> & data, std::array<uint8_t, DesCrypt::BlockSize> operator()(const std::array<uint8_t, DesCrypt::BlockSize> & data,
const std::array<uint8_t, 8> & key) const const std::array<uint8_t, DesCrypt::KeySize> & key) const
{ {
std::array<uint8_t, 8> result; std::array<uint8_t, DesCrypt::BlockSize> result = {};
result.fill(0);
DesCrypt::Key desKey(key.begin(), key.end()); DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::Decryptor dec(desKey); DesCrypt::DesDecryptor dec(desKey);
dec.DecryptBlock(result.begin(), data.begin(), data.end()); dec.DecryptBlock(result.begin(), result.end(), data.begin(), data.end());
return result; return result;
} }
@@ -218,28 +218,28 @@ TEST(DesCryptTests, DecryptTest)
Helper des; Helper des;
{ {
std::array<uint8_t, 8> data = { 0x85, 0xe8, 0x13, 0x54, 0x0f, 0x0a, 0xb4, 0x05 }; std::array<uint8_t, DesCrypt::BlockSize> data = { 0x85, 0xe8, 0x13, 0x54, 0x0f, 0x0a, 0xb4, 0x05 };
std::array<uint8_t, 8> key = { 0x13, 0x34, 0x57, 0x79, 0x9b, 0xbc, 0xdf, 0xf1 }; std::array<uint8_t, DesCrypt::KeySize> key = { 0x13, 0x34, 0x57, 0x79, 0x9b, 0xbc, 0xdf, 0xf1 };
std::array<uint8_t, 8> expected = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; std::array<uint8_t, DesCrypt::BlockSize> expected = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
ASSERT_EQ(expected, des(data, key)); ASSERT_EQ(expected, des(data, key));
} }
{ {
std::array<uint8_t, 8> data = { 0x07, 0xe8, 0x7f, 0xaa, 0xb3, 0x17, 0x13, 0x18 }; std::array<uint8_t, DesCrypt::BlockSize> data = { 0x07, 0xe8, 0x7f, 0xaa, 0xb3, 0x17, 0x13, 0x18 };
std::array<uint8_t, 8> key = { 0x44, 0xbf, 0x32, 0x19, 0x99, 0x25, 0x81, 0x51 }; std::array<uint8_t, DesCrypt::KeySize> key = { 0x44, 0xbf, 0x32, 0x19, 0x99, 0x25, 0x81, 0x51 };
std::array<uint8_t, 8> expected = { 0xaa, 0xf3, 0x83, 0x16, 0x2d, 0x2e, 0x6b, 0xcb }; std::array<uint8_t, DesCrypt::BlockSize> expected = { 0xaa, 0xf3, 0x83, 0x16, 0x2d, 0x2e, 0x6b, 0xcb };
ASSERT_EQ(expected, des(data, key)); ASSERT_EQ(expected, des(data, key));
} }
{ {
std::array<uint8_t, 8> data = { 0x42, 0x27, 0x88, 0xa6, 0x7b, 0x6c, 0x18, 0xed }; std::array<uint8_t, DesCrypt::BlockSize> data = { 0x42, 0x27, 0x88, 0xa6, 0x7b, 0x6c, 0x18, 0xed };
std::array<uint8_t, 8> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab }; std::array<uint8_t, DesCrypt::KeySize> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab };
std::array<uint8_t, 8> expected = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0xa7, 0x93, 0x44 }; std::array<uint8_t, DesCrypt::BlockSize> expected = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0xa7, 0x93, 0x44 };
ASSERT_EQ(expected, des(data, key)); ASSERT_EQ(expected, des(data, key));
} }
@@ -250,10 +250,10 @@ TEST(DesCryptTests, DecryptUInt64BlockTest)
struct Helper struct Helper
{ {
uint64_t operator()(uint64_t data, uint64_t operator()(uint64_t data,
const std::array<uint8_t, 8> & key) const const std::array<uint8_t, DesCrypt::KeySize> & key) const
{ {
DesCrypt::Key desKey(key.begin(), key.end()); DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::Decryptor dec(desKey); DesCrypt::DesDecryptor dec(desKey);
return dec.DecryptBlock(data); return dec.DecryptBlock(data);
} }
@@ -263,7 +263,7 @@ TEST(DesCryptTests, DecryptUInt64BlockTest)
{ {
uint64_t data = 0x85e813540f0ab405; uint64_t data = 0x85e813540f0ab405;
std::array<uint8_t, 8> key = { 0x13, 0x34, 0x57, 0x79, 0x9b, 0xbc, 0xdf, 0xf1 }; std::array<uint8_t, DesCrypt::KeySize> key = { 0x13, 0x34, 0x57, 0x79, 0x9b, 0xbc, 0xdf, 0xf1 };
uint64_t expected = 0x0123456789abcdef; uint64_t expected = 0x0123456789abcdef;
@@ -272,7 +272,7 @@ TEST(DesCryptTests, DecryptUInt64BlockTest)
{ {
uint64_t data = 0x07e87faab3171318; uint64_t data = 0x07e87faab3171318;
std::array<uint8_t, 8> key = { 0x44, 0xbf, 0x32, 0x19, 0x99, 0x25, 0x81, 0x51 }; std::array<uint8_t, DesCrypt::KeySize> key = { 0x44, 0xbf, 0x32, 0x19, 0x99, 0x25, 0x81, 0x51 };
uint64_t expected = 0xaaf383162d2e6bcb; uint64_t expected = 0xaaf383162d2e6bcb;
@@ -281,7 +281,7 @@ TEST(DesCryptTests, DecryptUInt64BlockTest)
{ {
uint64_t data = 0x422788a67b6c18ed; uint64_t data = 0x422788a67b6c18ed;
std::array<uint8_t, 8> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab }; std::array<uint8_t, DesCrypt::KeySize> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab };
uint64_t expected = 0xe51a9fd419a79344; uint64_t expected = 0xe51a9fd419a79344;
@@ -297,11 +297,11 @@ TEST(DesCryptTests, DecryptShortDataTest)
const std::vector<uint8_t> & key) const std::vector<uint8_t> & key)
{ {
std::vector<uint8_t> result; std::vector<uint8_t> result;
result.resize(8, 0); result.resize(DesCrypt::BlockSize, 0);
DesCrypt::Key desKey(key.begin(), key.end()); DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::Decryptor dec(desKey); DesCrypt::DesDecryptor dec(desKey);
dec.DecryptBlock(result.begin(), data.begin(), data.end()); dec.DecryptBlock(result.begin(), result.end(), data.begin(), data.end());
return result; return result;
} }
@@ -331,11 +331,11 @@ TEST(DesCryptTests, DecryptLongDataTest)
const std::vector<uint8_t> & key) const std::vector<uint8_t> & key)
{ {
std::vector<uint8_t> result; std::vector<uint8_t> result;
result.resize(8, 0); result.resize(DesCrypt::BlockSize, 0);
DesCrypt::Key desKey(key.begin(), key.end()); DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::Decryptor dec(desKey); DesCrypt::DesDecryptor dec(desKey);
dec.DecryptBlock(result.begin(), data.begin(), data.end()); dec.DecryptBlock(result.begin(), result.end(), data.begin(), data.end());
return result; return result;
} }
@@ -360,7 +360,7 @@ TEST(DesCryptTests, DecryptLongDataTest)
TEST(DesCryptTests, ShortKeyTest) TEST(DesCryptTests, ShortKeyTest)
{ {
{ {
std::array<uint8_t, 7> key = {}; std::array<uint8_t, DesCrypt::KeySize - 1> key = {};
ASSERT_THROW(DesCrypt::Key(key.begin(), key.end()), Chaos::Service::ChaosException); ASSERT_THROW(DesCrypt::Key(key.begin(), key.end()), Chaos::Service::ChaosException);
} }
} }
@@ -368,129 +368,187 @@ TEST(DesCryptTests, ShortKeyTest)
TEST(DesCryptTests, LongKeyTest) TEST(DesCryptTests, LongKeyTest)
{ {
{ {
std::array<uint8_t, 9> key = {}; std::array<uint8_t, DesCrypt::KeySize + 1> key = {};
ASSERT_THROW(DesCrypt::Key(key.begin(), key.end()), Chaos::Service::ChaosException); ASSERT_THROW(DesCrypt::Key(key.begin(), key.end()), Chaos::Service::ChaosException);
} }
} }
TEST(DesCryptTests, OutIteratorUsageEncryptTest) TEST(DesCryptTests, OutIteratorUsageEncryptTest)
{ {
struct OutputItMock
{ {
OutputItMock(size_t & asteriskCalls, size_t & incrementCalls) std::array<uint8_t, DesCrypt::BlockSize> data = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0xa7, 0x93, 0x44 };
: AsteriskCalls_(asteriskCalls) std::array<uint8_t, DesCrypt::KeySize> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab };
, IncrementCalls_(incrementCalls)
{ }
uint8_t & operator*() std::array<uint8_t, 11> fact = {};
{ // First and last 3 bytes should be untouched.
++AsteriskCalls_; std::array<uint8_t, 11> expected = { 0x00, 0x00, 0x00, 0x42, 0x27, 0x88, 0xa6, 0x7b, 0x00, 0x00, 0x00 };
static uint8_t dummy = 0;
return dummy;
}
OutputItMock operator++(int)
{
++IncrementCalls_;
return *this;
}
size_t & AsteriskCalls_;
size_t & IncrementCalls_;
};
{
std::array<uint8_t, 8> data = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0xa7, 0x93, 0x44 };
std::array<uint8_t, 8> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab };
size_t asteriskCalls = 0;
size_t incrementCalls = 0;
OutputItMock it(asteriskCalls, incrementCalls);
DesCrypt::Key desKey(key.begin(), key.end()); DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::Encryptor enc(desKey); DesCrypt::DesEncryptor enc(desKey);
enc.EncryptBlock(it, data.begin(), data.end()); enc.EncryptBlock(fact.begin() + 3, fact.end() - 3, data.begin(), data.end());
ASSERT_EQ(8, asteriskCalls); ASSERT_EQ(expected, fact);
ASSERT_EQ(8, incrementCalls);
} }
{ {
std::array<uint8_t, 11> data = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f }; std::array<uint8_t, DesCrypt::BlockSize + 2> data = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0xa7, 0x93, 0x44, 0x44, 0x44 };
std::array<uint8_t, 8> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab }; std::array<uint8_t, DesCrypt::KeySize> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab };
size_t asteriskCalls = 0; std::array<uint8_t, 12> fact = {};
size_t incrementCalls = 0; // First and last 4 bytes should be untouched.
OutputItMock it(asteriskCalls, incrementCalls); std::array<uint8_t, 12> expected = { 0x00, 0x00, 0x00, 0x00, 0x42, 0x27, 0x88, 0xa6, 0x00, 0x00, 0x00, 0x00 };
DesCrypt::Key desKey(key.begin(), key.end()); DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::Encryptor enc(desKey); DesCrypt::DesEncryptor enc(desKey);
enc.EncryptBlock(it, data.begin(), data.end()); enc.EncryptBlock(fact.begin() + 4, fact.end() - 4, data.begin(), data.end());
ASSERT_EQ(8, asteriskCalls); ASSERT_EQ(expected, fact);
ASSERT_EQ(8, incrementCalls); }
{
std::array<uint8_t, DesCrypt::BlockSize + 2> data = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0xa7, 0x93, 0x44, 0x44, 0x44 };
std::array<uint8_t, DesCrypt::KeySize> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab };
std::array<uint8_t, 12> fact = {};
std::array<uint8_t, 12> expected = {};
DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::DesEncryptor enc(desKey);
enc.EncryptBlock(fact.begin() + 3, fact.begin() + 3, data.begin(), data.end());
ASSERT_EQ(expected, fact);
} }
} }
TEST(DesCryptTests, OutIteratorUsageDecryptTest) TEST(DesCryptTests, OutIteratorUsageDecryptTest)
{ {
struct OutputItMock
{ {
OutputItMock(size_t & asteriskCalls, size_t & incrementCalls) std::array<uint8_t, DesCrypt::BlockSize> data = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0xa7, 0x93, 0x44 };
: AsteriskCalls_(asteriskCalls) std::array<uint8_t, DesCrypt::KeySize> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab };
, IncrementCalls_(incrementCalls)
{ }
uint8_t & operator*() std::array<uint8_t, 11> fact = {};
{ // First and last 3 bytes should be untouched.
++AsteriskCalls_; std::array<uint8_t, 11> expected = { 0x00, 0x00, 0x00, 0x45, 0x69, 0x71, 0x17, 0x13, 0x00, 0x00, 0x00 };
static uint8_t dummy = 0;
return dummy;
}
OutputItMock operator++(int)
{
++IncrementCalls_;
return *this;
}
size_t & AsteriskCalls_;
size_t & IncrementCalls_;
};
{
std::array<uint8_t, 8> data = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0xa7, 0x93, 0x44 };
std::array<uint8_t, 8> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab };
size_t asteriskCalls = 0;
size_t incrementCalls = 0;
OutputItMock it(asteriskCalls, incrementCalls);
DesCrypt::Key desKey(key.begin(), key.end()); DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::Decryptor dec(desKey); DesCrypt::DesDecryptor dec(desKey);
dec.DecryptBlock(it, data.begin(), data.end()); dec.DecryptBlock(fact.begin() + 3, fact.end() - 3, data.begin(), data.end());
ASSERT_EQ(8, asteriskCalls); ASSERT_EQ(expected, fact);
ASSERT_EQ(8, incrementCalls);
} }
{ {
std::array<uint8_t, 11> data = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f }; std::array<uint8_t, DesCrypt::BlockSize + 2> data = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0xa7, 0x93, 0x44, 0x44, 0x44 };
std::array<uint8_t, 8> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab }; std::array<uint8_t, DesCrypt::KeySize> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab };
size_t asteriskCalls = 0; std::array<uint8_t, 12> fact = {};
size_t incrementCalls = 0; // First and last 4 bytes should be untouched.
OutputItMock it(asteriskCalls, incrementCalls); std::array<uint8_t, 12> expected = { 0x00, 0x00, 0x00, 0x00, 0x45, 0x69, 0x71, 0x17, 0x00, 0x00, 0x00, 0x00 };
DesCrypt::Key desKey(key.begin(), key.end()); DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::Decryptor dec(desKey); DesCrypt::DesDecryptor dec(desKey);
dec.DecryptBlock(it, data.begin(), data.end()); dec.DecryptBlock(fact.begin() + 4, fact.end() - 4, data.begin(), data.end());
ASSERT_EQ(8, asteriskCalls); ASSERT_EQ(expected, fact);
ASSERT_EQ(8, incrementCalls); }
{
std::array<uint8_t, DesCrypt::BlockSize + 2> data = { 0xe5, 0x1a, 0x9f, 0xd4, 0x19, 0xa7, 0x93, 0x44, 0x44, 0x44 };
std::array<uint8_t, DesCrypt::KeySize> key = { 0xda, 0xec, 0x68, 0xae, 0x83, 0xe0, 0x1e, 0xab };
std::array<uint8_t, 12> fact = {};
std::array<uint8_t, 12> expected = {};
DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::DesDecryptor dec(desKey);
dec.DecryptBlock(fact.begin() + 3, fact.begin() + 3, data.begin(), data.end());
ASSERT_EQ(expected, fact);
} }
} }
template<typename Impl, typename InputIt>
static std::vector<uint8_t> EncryptThroughBase(const Encryptor<Impl> & enc,
InputIt begin, InputIt end)
{
std::vector<uint8_t> result;
result.resize(enc.GetBlockSize(), 0);
enc.EncryptBlock(result.begin(), result.end(), begin, end);
return result;
}
TEST(DesCryptTests, EncryptThroughBaseTest)
{
std::array<uint8_t, DesCrypt::KeySize> key = { 0x13, 0x34, 0x57, 0x79, 0x9b, 0xbc, 0xdf, 0xf1 };
std::vector<uint8_t> data = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
std::vector<uint8_t> expected = { 0x85, 0xe8, 0x13, 0x54, 0x0f, 0x0a, 0xb4, 0x05 };
DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::DesEncryptor enc(desKey);
ASSERT_EQ(expected, EncryptThroughBase(enc, data.begin(), data.end()));
}
template<typename Impl>
static uint64_t EncryptUInt64BlockThroughBase(const Encryptor<Impl> & enc, uint64_t block)
{
return enc.EncryptBlock(block);
}
TEST(DesCryptTests, EncryptUInt64BlockThroughBaseTest)
{
std::array<uint8_t, DesCrypt::KeySize> key = { 0x13, 0x34, 0x57, 0x79, 0x9b, 0xbc, 0xdf, 0xf1 };
uint64_t data = 0x0123456789abcdef;
uint64_t expected = 0x85e813540f0ab405;
DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::DesEncryptor enc(desKey);
ASSERT_EQ(expected, EncryptUInt64BlockThroughBase(enc, data));
}
template<typename Impl, typename InputIt>
static std::vector<uint8_t> DecryptThroughBase(const Decryptor<Impl> & dec,
InputIt begin, InputIt end)
{
std::vector<uint8_t> result;
result.resize(dec.GetBlockSize(), 0);
dec.DecryptBlock(result.begin(), result.end(), begin, end);
return result;
}
TEST(DesCryptTests, DecryptThroughBaseTest)
{
std::array<uint8_t, DesCrypt::KeySize> key = { 0x13, 0x34, 0x57, 0x79, 0x9b, 0xbc, 0xdf, 0xf1 };
std::vector<uint8_t> data = { 0x85, 0xe8, 0x13, 0x54, 0x0f, 0x0a, 0xb4, 0x05 };
std::vector<uint8_t> expected = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::DesDecryptor dec(desKey);
ASSERT_EQ(expected, DecryptThroughBase(dec, data.begin(), data.end()));
}
template<typename Impl>
static uint64_t DecryptUInt64BlockThroughBase(const Decryptor<Impl> & dec, uint64_t block)
{
return dec.DecryptBlock(block);
}
TEST(DesCryptTests, DecryptUInt64BlockThroughBaseTest)
{
std::array<uint8_t, DesCrypt::KeySize> key = { 0x13, 0x34, 0x57, 0x79, 0x9b, 0xbc, 0xdf, 0xf1 };
uint64_t data = 0x85e813540f0ab405;
uint64_t expected = 0x0123456789abcdef;
DesCrypt::Key desKey(key.begin(), key.end());
DesCrypt::DesDecryptor dec(desKey);
ASSERT_EQ(expected, DecryptUInt64BlockThroughBase(dec, data));
}

View File

@@ -99,8 +99,7 @@ TEST(HmacTests, LongKeyTest)
TEST(HmacTests, UninitializedHmacTest) TEST(HmacTests, UninitializedHmacTest)
{ {
std::array<uint8_t, 10> in; std::array<uint8_t, 10> in = {};
in.fill(0);
{ {
Hmac<Md5Hasher> hmac; Hmac<Md5Hasher> hmac;

View File

@@ -0,0 +1,32 @@
#include <gtest/gtest.h>
#include <string>
#include "Service/ChaosException.hpp"
using namespace Chaos::Service;
TEST(ChaosExceptionTests, RvalueRefCtorTest)
{
try
{
throw ChaosException("everything's alright :D");
}
catch (const ChaosException & ex)
{
ASSERT_EQ("everything's alright :D", ex.GetMessage());
}
}
TEST(ChaosExceptionTests, ConstLvalueRefCtorTest)
{
const std::string message = "everything's alright :D";
try
{
throw ChaosException(message);
}
catch (const ChaosException & ex)
{
ASSERT_EQ("everything's alright :D", ex.GetMessage());
}
}