New directory structure for libghettocrypt
This commit is contained in:
38 files changed
+19406
-1721
No files matched your search
@@ -0,0 +1,46 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(GCrypt)
|
||||
|
||||
###################
|
||||
# Library project #
|
||||
###################
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
FILE(GLOB main_src src/*.cpp)
|
||||
add_library(${PROJECT_NAME}
|
||||
${main_src}
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
include
|
||||
)
|
||||
|
||||
#########
|
||||
# Tests #
|
||||
#########
|
||||
FILE(GLOB test_src test/*.cpp)
|
||||
add_executable(test
|
||||
test/Catch2.h
|
||||
${test_src}
|
||||
)
|
||||
target_link_libraries(test ${PROJECT_NAME})
|
||||
|
||||
target_include_directories(test PRIVATE
|
||||
include
|
||||
)
|
||||
|
||||
|
||||
##############
|
||||
# Executable #
|
||||
##############
|
||||
FILE(GLOB exec_src exec/*.cpp)
|
||||
add_executable(exec
|
||||
${exec_src}
|
||||
)
|
||||
target_link_libraries(exec ${PROJECT_NAME})
|
||||
|
||||
target_include_directories(exec PRIVATE
|
||||
include
|
||||
${eule_include}
|
||||
)
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#pragma once
|
||||
#include "Feistel.h"
|
||||
#include "Flexblock.h"
|
||||
|
||||
namespace GhettoCipher
|
||||
{
|
||||
/** Class to apply a block cipher to messages of arbitrary length in a distributed manner
|
||||
*/
|
||||
class Cipher
|
||||
{
|
||||
public:
|
||||
explicit Cipher(const Block& key);
|
||||
explicit Cipher(const std::string& password);
|
||||
|
||||
Cipher(const Cipher& other) = delete;
|
||||
Cipher(Cipher&& other) noexcept = delete;
|
||||
|
||||
~Cipher();
|
||||
|
||||
//! Will set the key
|
||||
void SetKey(const Block& key);
|
||||
|
||||
//! Will set the key from a password
|
||||
void SetPassword(const std::string& password);
|
||||
|
||||
//! Will encipher a flexblock of data
|
||||
Flexblock Encipher(const Flexblock& data, bool printProgress = false) const;
|
||||
|
||||
//! Will decipher a flexblock of data
|
||||
Flexblock Decipher(const Flexblock& data, bool printProgress = false) const;
|
||||
|
||||
private:
|
||||
Block key;
|
||||
|
||||
//! Will zero the memory used by the key
|
||||
void ZeroKeyMemory();
|
||||
|
||||
// Initial value for cipher block chaining
|
||||
Block initializationVector;
|
||||
};
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
#include <cstddef>
|
||||
|
||||
namespace GhettoCipher
|
||||
{
|
||||
// MUST BE A POWER OF 2 > 4
|
||||
constexpr std::size_t BLOCK_SIZE = 512;
|
||||
|
||||
// MUST BE > 2
|
||||
constexpr std::size_t N_ROUNDS = 64;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
build/
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,9 @@
|
||||
# Copy repository readme here to be used as a cover page
|
||||
tail ../readme.md -n +2 > index.md
|
||||
|
||||
# Run doxygen
|
||||
doxygen doxyfig
|
||||
|
||||
# Cleanup index.md
|
||||
rm -f index.md
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <GhettoCryptWrapper.h>
|
||||
#include <SecureBitset.h>
|
||||
#include <Util.h>
|
||||
#include <InitializationVector.h>
|
||||
|
||||
using namespace GhettoCipher;
|
||||
|
||||
void ExampleString()
|
||||
{
|
||||
std::cout << "Example on how to encrypt & decrypt a string:" << std::endl;
|
||||
|
||||
// Get some string
|
||||
const std::string input = "I am a super secret message!";
|
||||
std::cout << input << std::endl;
|
||||
|
||||
// Encrypt
|
||||
const std::string encrypted = GhettoCryptWrapper::EncryptString(input, "password1");
|
||||
std::cout << encrypted << std::endl;
|
||||
|
||||
// Decrypt
|
||||
const std::string decrypted = GhettoCryptWrapper::DecryptString(encrypted, "password1");
|
||||
std::cout << decrypted << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ExampleFiles()
|
||||
{
|
||||
std::cout << "Example on how to encrypt & decrypt any file:" << std::endl;
|
||||
|
||||
// Encrypt
|
||||
GhettoCryptWrapper::EncryptFile("main.cpp", "main.cpp.crypt", "password1");
|
||||
|
||||
// Decrypt
|
||||
GhettoCryptWrapper::DecryptFile("main.cpp.crypt", "main.cpp.clear", "password1");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
ExampleString();
|
||||
//ExampleFiles();
|
||||
|
||||
return 0;
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#include "Feistel.h"
|
||||
#include "Flexblock.h"
|
||||
|
||||
namespace GhettoCipher {
|
||||
/** Class to apply a block cipher to messages of arbitrary length in a distributed manner
|
||||
*/
|
||||
class Cipher {
|
||||
public:
|
||||
explicit Cipher(const Block& key);
|
||||
explicit Cipher(const std::string& password);
|
||||
|
||||
Cipher(const Cipher& other) = delete;
|
||||
Cipher(Cipher&& other) noexcept = delete;
|
||||
|
||||
~Cipher();
|
||||
|
||||
//! Will set the key
|
||||
void SetKey(const Block& key);
|
||||
|
||||
//! Will set the key from a password
|
||||
void SetPassword(const std::string& password);
|
||||
|
||||
//! Will encipher a flexblock of data
|
||||
Flexblock Encipher(const Flexblock& data, bool printProgress = false) const;
|
||||
|
||||
//! Will decipher a flexblock of data
|
||||
Flexblock Decipher(const Flexblock& data, bool printProgress = false) const;
|
||||
|
||||
private:
|
||||
Block key;
|
||||
|
||||
//! Will zero the memory used by the key
|
||||
void ZeroKeyMemory();
|
||||
|
||||
// Initial value for cipher block chaining
|
||||
Block initializationVector;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include <cstddef>
|
||||
|
||||
namespace GhettoCipher {
|
||||
// MUST BE A POWER OF 2 > 4
|
||||
constexpr std::size_t BLOCK_SIZE = 512;
|
||||
|
||||
// MUST BE > 2
|
||||
constexpr std::size_t N_ROUNDS = 64;
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,230 @@
|
||||
#include "CppUnitTest.h"
|
||||
#include "../GhettoCrypt/Cipher.h"
|
||||
#include "../GhettoCrypt/Util.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace GhettoCipher;
|
||||
|
||||
// THESE TESTS ASSUME BLOCK_SIZE == 512
|
||||
|
||||
namespace SimpleTests
|
||||
{
|
||||
TEST_CLASS(EncryptEqualsDecrypt)
|
||||
{
|
||||
public:
|
||||
|
||||
// Tests that encrypting a message of exactly BLOCK_SIZE yields the exact message back
|
||||
TEST_METHOD(SingleBlock_NoPadding)
|
||||
{
|
||||
// Instanciate our cipher and supply a key
|
||||
const Block key = PasswordToKey("1234");
|
||||
const Cipher cipher(key);
|
||||
|
||||
// Recode the ascii-string to bits
|
||||
const Flexblock cleartext_bits =
|
||||
"1011110011010110000010110001111000111010111101001010100100011101"
|
||||
"0101110101010010100000110100001000011000111010001001110101111111"
|
||||
"1110110101100101110001010101011110001010000010111110011011010111"
|
||||
"1100110100111000000011100101010100110010001110010011000010111001"
|
||||
"0000010000010000011001111010011110111001000000000110101000110001"
|
||||
"0110111110110110100000010100000011010001000011100100111001001011"
|
||||
"1101100100000100010000001011100010010001101111100100101100010001"
|
||||
"0000011110010110111010110110111110011110011010001100100111110101";
|
||||
|
||||
// Encrypt our cleartext bits
|
||||
const Flexblock ciphertext_bits = cipher.Encipher(cleartext_bits);
|
||||
|
||||
// Decipher it again
|
||||
const Flexblock decryptedBits = cipher.Decipher(ciphertext_bits);
|
||||
|
||||
// Assert that the decrypted text equals the plaintext
|
||||
Assert::AreEqual(
|
||||
cleartext_bits,
|
||||
decryptedBits
|
||||
);
|
||||
}
|
||||
|
||||
// Tests that encrypting a message of less than BLOCK_SIZE yields the exact message plus zero-padding back
|
||||
TEST_METHOD(SingleBlock_Padding)
|
||||
{
|
||||
// Instanciate our cipher and supply a key
|
||||
const Block key = PasswordToKey("1234");
|
||||
const Cipher cipher(key);
|
||||
|
||||
// Recode the ascii-string to bits
|
||||
const Flexblock cleartext_bits =
|
||||
"1011110011010110000010110001111000111010111101001010100100011101"
|
||||
"0101110101010010100000110100001000011000111010001001110101111111"
|
||||
"1110110101100101110001010101011110001010000010111110011011010111"
|
||||
"1100110100111000000011100101010100110010001110010011000010111001"
|
||||
"0000010000010000011001111010011110111001000000000110101000110001"
|
||||
"0110111110110110100000010100000011010001000011100100111001001011"
|
||||
"1101100100000100";
|
||||
|
||||
const Flexblock cleartext_bits_EXPECTED_RESULT =
|
||||
"1011110011010110000010110001111000111010111101001010100100011101"
|
||||
"0101110101010010100000110100001000011000111010001001110101111111"
|
||||
"1110110101100101110001010101011110001010000010111110011011010111"
|
||||
"1100110100111000000011100101010100110010001110010011000010111001"
|
||||
"0000010000010000011001111010011110111001000000000110101000110001"
|
||||
"0110111110110110100000010100000011010001000011100100111001001011"
|
||||
"1101100100000100000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
// Encrypt our cleartext bits
|
||||
const Flexblock ciphertext_bits = cipher.Encipher(cleartext_bits);
|
||||
|
||||
// Decipher it again
|
||||
const Flexblock decryptedBits = cipher.Decipher(ciphertext_bits);
|
||||
|
||||
// Assert that the decrypted text equals the plaintext
|
||||
Assert::AreEqual(
|
||||
cleartext_bits_EXPECTED_RESULT,
|
||||
decryptedBits
|
||||
);
|
||||
}
|
||||
|
||||
// Tests that a decrypted ciphertext equals its plaintrext version, using a cleartext that requires A LOT of blocks
|
||||
TEST_METHOD(MultiBlock_NoPadding)
|
||||
{
|
||||
// Instanciate our cipher and supply a key
|
||||
const Block key = PasswordToKey("1234");
|
||||
const Cipher cipher(key);
|
||||
|
||||
// Recode the ascii-string to bits
|
||||
const Flexblock cleartext_bits =
|
||||
"1011110011010110000010110001111000111010111101001010100100011101"
|
||||
"0101110101010010100000110100001000011000111010001001110101111111"
|
||||
"1110110101100101110001010101011110001010000010111110011011010111"
|
||||
"1100110100111000000011100101010100110010001110010011000010111001"
|
||||
"0000010000010000011001111010011110111001000000000110101000110001"
|
||||
"0110111110110110100000010100000011010001000011100100111001001011"
|
||||
"1101100100000100010000001011100010010001101111100100101100010001"
|
||||
"0000011110010110111010110110111110011110011010001100100111110101"
|
||||
"1000010010000000000100101011110001000101101101100000010011111011"
|
||||
"1011111010110100100111100111110011100001111101111110000110001100"
|
||||
"0001000111000111101110000111011011101010100010100101100111010100"
|
||||
"0101111110110010110000111111011001101110101101100100100011000100"
|
||||
"1000110010101001000100001001101000011111101011111100100000100101"
|
||||
"1100001100111001011111001101000111011101011101000110010110110110"
|
||||
"0111001010011010010000010110000110010101101100101110111100100011"
|
||||
"0010111110011100010100000101100101110101101011110100100000110110"
|
||||
"1001101110101001001111111000010100011100100000101000111101101111"
|
||||
"0101111011110001101010111010001000111010101111001101100100100100"
|
||||
"1110110111001100011010110000101000011001011100101100111101110000"
|
||||
"1010101111011110000111011011011110000111010110110111111010101010"
|
||||
"0111100101111001010111101000001010100000111010111100111011111001"
|
||||
"0110111000000110100011011100101101010101101000010010011111100100"
|
||||
"0010111000001011101110000110010011101001111010100111110111110101"
|
||||
"1110111000000000101011000100101010000110110111101010011001111010"
|
||||
"1101011110001110000011010111001100001100101000000101000101000010"
|
||||
"0101000011011111010010110010000010101100001110011000110111110111"
|
||||
"1110010101011110111001100010110101101011100111100011101010001011"
|
||||
"0101110010100110101100111100010000111101111100000111000110110110"
|
||||
"1001100111000000011010100000011101011000010010011010001011110000"
|
||||
"1100100111111001001000011100110000011110001100000000010000001001"
|
||||
"1110000000110010000010011010100011011011000000000111110000110111"
|
||||
"0101110011001101010110010100011001110110000110010001100110011111";
|
||||
|
||||
// Encrypt our cleartext bits
|
||||
const Flexblock ciphertext_bits = cipher.Encipher(cleartext_bits);
|
||||
|
||||
// Decipher it again
|
||||
const Flexblock decryptedBits = cipher.Decipher(ciphertext_bits);
|
||||
|
||||
// Assert that the decrypted text equals the plaintext
|
||||
Assert::AreEqual(
|
||||
cleartext_bits,
|
||||
decryptedBits
|
||||
);
|
||||
}
|
||||
|
||||
// Tests that a decrypted ciphertext equals its plaintrext version, using a cleartext that requires A LOT of blocks
|
||||
TEST_METHOD(MultiBlock_Padding)
|
||||
{
|
||||
// Instanciate our cipher and supply a key
|
||||
const Block key = PasswordToKey("1234");
|
||||
const Cipher cipher(key);
|
||||
|
||||
// Recode the ascii-string to bits
|
||||
const Flexblock cleartext_bits =
|
||||
"1011110011010110000010110001111000111010111101001010100100011101"
|
||||
"0101110101010010100000110100001000011000111010001001110101111111"
|
||||
"1110110101100101110001010101011110001010000010111110011011010111"
|
||||
"1100110100111000000011100101010100110010001110010011000010111001"
|
||||
"0000010000010000011001111010011110111001000000000110101000110001"
|
||||
"0110111110110110100000010100000011010001000011100100111001001011"
|
||||
"1101100100000100010000001011100010010001101111100100101100010001"
|
||||
"0000011110010110111010110110111110011110011010001100100111110101"
|
||||
"1000010010000000000100101011110001000101101101100000010011111011"
|
||||
"1011111010110100100111100111110011100001111101111110000110001100"
|
||||
"0001000111000111101110000111011011101010100010100101100111010100"
|
||||
"0101111110110010110000111111011001101110101101100100100011000100"
|
||||
"1000110010101001000100001001101000011111101011111100100000100101"
|
||||
"1100001100111001011111001101000111011101011101000110010110110110"
|
||||
"0111001010011010010000010110000110010101101100101110111100100011"
|
||||
"0010111110011100010100000101100101110101101011110100100000110110"
|
||||
"1001101110101001001111111000010100011100100000101000111101101111"
|
||||
"0101111011110001101010111010001000111010101111001101100100100100"
|
||||
"1110110111001100011010110000101000011001011100101100111101110000"
|
||||
"1010101111011110000111011011011110000111010110110111111010101010"
|
||||
"0111100101111001010111101000001010100000111010111100111011111001"
|
||||
"0110111000000110100011011100101101010101101000010010011111100100"
|
||||
"0010111000001011101110000110010011101001111010100111110111110101"
|
||||
"1110111000000000101011000100101010000110110111101010011001111010"
|
||||
"1101011110001110000011010111001100001100101000000101000101000010"
|
||||
"0101000011011111010010110010000010101100001110011000110111110111"
|
||||
"1110010101011110111001100010110101101011100111100011101010001011"
|
||||
"0101110010100110101100111100010000111101111100000111000110110110"
|
||||
"1001100111000000011010100000011101011000010010011010001011110000"
|
||||
"1100100111111001001000011100110000011110001100000000010000001001"
|
||||
"11100000001100100000100110101000110110110000000001111100001";
|
||||
|
||||
const Flexblock cleartext_bits_EXPECTED_RESULT =
|
||||
"1011110011010110000010110001111000111010111101001010100100011101"
|
||||
"0101110101010010100000110100001000011000111010001001110101111111"
|
||||
"1110110101100101110001010101011110001010000010111110011011010111"
|
||||
"1100110100111000000011100101010100110010001110010011000010111001"
|
||||
"0000010000010000011001111010011110111001000000000110101000110001"
|
||||
"0110111110110110100000010100000011010001000011100100111001001011"
|
||||
"1101100100000100010000001011100010010001101111100100101100010001"
|
||||
"0000011110010110111010110110111110011110011010001100100111110101"
|
||||
"1000010010000000000100101011110001000101101101100000010011111011"
|
||||
"1011111010110100100111100111110011100001111101111110000110001100"
|
||||
"0001000111000111101110000111011011101010100010100101100111010100"
|
||||
"0101111110110010110000111111011001101110101101100100100011000100"
|
||||
"1000110010101001000100001001101000011111101011111100100000100101"
|
||||
"1100001100111001011111001101000111011101011101000110010110110110"
|
||||
"0111001010011010010000010110000110010101101100101110111100100011"
|
||||
"0010111110011100010100000101100101110101101011110100100000110110"
|
||||
"1001101110101001001111111000010100011100100000101000111101101111"
|
||||
"0101111011110001101010111010001000111010101111001101100100100100"
|
||||
"1110110111001100011010110000101000011001011100101100111101110000"
|
||||
"1010101111011110000111011011011110000111010110110111111010101010"
|
||||
"0111100101111001010111101000001010100000111010111100111011111001"
|
||||
"0110111000000110100011011100101101010101101000010010011111100100"
|
||||
"0010111000001011101110000110010011101001111010100111110111110101"
|
||||
"1110111000000000101011000100101010000110110111101010011001111010"
|
||||
"1101011110001110000011010111001100001100101000000101000101000010"
|
||||
"0101000011011111010010110010000010101100001110011000110111110111"
|
||||
"1110010101011110111001100010110101101011100111100011101010001011"
|
||||
"0101110010100110101100111100010000111101111100000111000110110110"
|
||||
"1001100111000000011010100000011101011000010010011010001011110000"
|
||||
"1100100111111001001000011100110000011110001100000000010000001001"
|
||||
"1110000000110010000010011010100011011011000000000111110000100000"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
// Encrypt our cleartext bits
|
||||
const Flexblock ciphertext_bits = cipher.Encipher(cleartext_bits);
|
||||
|
||||
// Decipher it again
|
||||
const Flexblock decryptedBits = cipher.Decipher(ciphertext_bits);
|
||||
|
||||
// Assert that the decrypted text equals the plaintext
|
||||
Assert::AreEqual(
|
||||
cleartext_bits_EXPECTED_RESULT,
|
||||
decryptedBits
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#include "CppUnitTest.h"
|
||||
#include "../GhettoCrypt/GhettoCryptWrapper.h"
|
||||
#include "../GhettoCrypt/Flexblock.h"
|
||||
#include "../GhettoCrypt/Util.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace GhettoCipher;
|
||||
|
||||
namespace SimpleTests
|
||||
{
|
||||
TEST_CLASS(GCWrapper)
|
||||
{
|
||||
public:
|
||||
|
||||
// Tests that encrypting and decrypting strings using the wrapper works.
|
||||
// This test will start from scratch after encryption, to ensure EVERYTHING has to be re-calculated.
|
||||
TEST_METHOD(String)
|
||||
{
|
||||
// Setup
|
||||
const std::string plaintext = "Hello, World!";
|
||||
const std::string password = "Der Affe will Zucker";
|
||||
|
||||
std::string ciphertext;
|
||||
std::string decrypted;
|
||||
|
||||
// Encryption
|
||||
{
|
||||
ciphertext = GhettoCryptWrapper::EncryptString(plaintext, password);
|
||||
}
|
||||
|
||||
// Decryption
|
||||
{
|
||||
decrypted = GhettoCryptWrapper::DecryptString(ciphertext, password);
|
||||
}
|
||||
|
||||
// Assertion
|
||||
Assert::AreEqual(
|
||||
plaintext,
|
||||
decrypted
|
||||
);
|
||||
}
|
||||
|
||||
// Tests that encrypting and decrypting files using the wrapper works.
|
||||
// This test will start from scratch after encryption, to ensure EVERYTHING has to be re-calculated.
|
||||
TEST_METHOD(File)
|
||||
{
|
||||
// Setup
|
||||
#if defined _WIN64
|
||||
const std::string testfile_dir = "../../SimpleTests/";
|
||||
#elif defined _WIN32
|
||||
const std::string testfile_dir = "../SimpleTests/";
|
||||
#endif
|
||||
|
||||
const std::string filename_plain = testfile_dir + "testfile.png";
|
||||
const std::string filename_encrypted = testfile_dir + "testfile.png.crypt";
|
||||
const std::string filename_decrypted = testfile_dir + "testfile.png.clear.png";
|
||||
const std::string password = "Der Affe will Zucker";
|
||||
|
||||
|
||||
// Encryption
|
||||
{
|
||||
GhettoCryptWrapper::EncryptFile(filename_plain, filename_encrypted, password);
|
||||
}
|
||||
|
||||
// Decryption
|
||||
{
|
||||
GhettoCryptWrapper::DecryptFile(filename_encrypted, filename_decrypted, password);
|
||||
}
|
||||
|
||||
// Read in both the base, and the decrypted file
|
||||
const Flexblock plainfile = ReadFileToBits(filename_plain);
|
||||
const Flexblock decryptfile = ReadFileToBits(filename_decrypted);
|
||||
|
||||
// Assertion (If this fails, maybe check if the image is even readable by an image viewer)
|
||||
Assert::AreEqual(
|
||||
PadStringToLength(plainfile, decryptfile.length(), '0', false),
|
||||
decryptfile
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
#include "CppUnitTest.h"
|
||||
#include "../GhettoCrypt/Util.h"
|
||||
#include "../GhettoCrypt/Config.h"
|
||||
#include <unordered_map>
|
||||
#include <codecvt>
|
||||
#include <sstream>
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace GhettoCipher;
|
||||
|
||||
// We can generate passwords by just translating a decimal number to base "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
inline std::string Base10_2_X(const unsigned long long int i, const std::string set, unsigned int padding)
|
||||
{
|
||||
if (set.length() == 0)
|
||||
return ""; // Return empty string, if set is empty. Play stupid games, win stupid prizes.
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
{
|
||||
unsigned long long int buf = i;
|
||||
while (buf != 0)
|
||||
{
|
||||
const unsigned long long int mod = buf % set.length();
|
||||
buf /= set.length();
|
||||
ss << set[(std::size_t)mod];
|
||||
}
|
||||
}
|
||||
{
|
||||
const std::string buf = ss.str();
|
||||
ss.str("");
|
||||
for (long long int i = buf.length() - 1; i >= 0; i--)
|
||||
ss << buf[(std::size_t)i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << set[0]; // If i is 0, just pass a null-value. The algorithm would hang otherwise.
|
||||
}
|
||||
|
||||
// Add as much null-values to the left as requested.
|
||||
if (ss.str().length() < padding)
|
||||
{
|
||||
const std::size_t cachedLen = ss.str().length();
|
||||
const std::string cachedStr = ss.str();
|
||||
ss.str("");
|
||||
for (std::size_t i = 0; i < padding - cachedLen; i++)
|
||||
ss << set[0];
|
||||
ss << cachedStr;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
using convert_t = std::codecvt_utf8<wchar_t>;
|
||||
|
||||
namespace SimpleTests
|
||||
{
|
||||
TEST_CLASS(Password2Key)
|
||||
{
|
||||
public:
|
||||
|
||||
// Run a few thousand random passwords through the keygen and see if we'll find a collision.
|
||||
// This test passing does NOT mean that it's resistant! Maybe good, maybe shit! But if it fails, it's definitely shit.
|
||||
// Already validated range: Password 0 - 1.000.000
|
||||
TEST_METHOD(CollisionResistance)
|
||||
{
|
||||
// To test resistence set this to a high number around a million.
|
||||
// This will take a LONG while to execute though (about 2.5hrs on my machine), hence why it's set so low.
|
||||
constexpr std::size_t NUM_RUN_TESTS = 1000;
|
||||
|
||||
std::unordered_map<std::bitset<BLOCK_SIZE>, std::string> keys; // <key, password>
|
||||
|
||||
// Try NUM_RUN_TESTS passwords
|
||||
const std::string charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
std::wstring_convert<convert_t, wchar_t> strconverter;
|
||||
|
||||
for (std::size_t i = 0; i < NUM_RUN_TESTS; i++)
|
||||
{
|
||||
// Get password
|
||||
const std::string password = Base10_2_X(i, charset, 0);
|
||||
|
||||
// Generate key
|
||||
const std::bitset<BLOCK_SIZE> newKey = PasswordToKey(password).Get();
|
||||
|
||||
// Check if this block is already in our map
|
||||
if (keys.find(newKey) != keys.cend())
|
||||
{
|
||||
std::wstringstream wss;
|
||||
wss << "Collision found between password \""
|
||||
<< strconverter.from_bytes(password)
|
||||
<< "\" and \""
|
||||
<< strconverter.from_bytes(keys[newKey])
|
||||
<< "\". The key is \""
|
||||
<< newKey
|
||||
<< "\".";
|
||||
|
||||
Assert::Fail(wss.str().c_str());
|
||||
}
|
||||
|
||||
// All good? Insert it into our map
|
||||
keys[newKey] = password;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.5 KiB |
Reference in new issue
Block a user