Translated password2key transformation collision resistance tests to catch2
This commit is contained in:
parent
b998a51e11
commit
14e1fbe32c
@ -1,28 +1,24 @@
|
|||||||
/*
|
#include <GCrypt/Util.h>
|
||||||
#include "CppUnitTest.h"
|
#include <GCrypt/Config.h>
|
||||||
#include "../GhettoCrypt/Util.h"
|
|
||||||
#include "../GhettoCrypt/Config.h"
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <codecvt>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include "Catch2.h"
|
||||||
|
|
||||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
using namespace Leonetienne::GCrypt;
|
||||||
using namespace GhettoCipher;
|
|
||||||
|
|
||||||
// We can generate passwords by just translating a decimal number to base "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
// 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)
|
// So this is just a helper function to generate random passwords
|
||||||
{
|
inline std::string Base10_2_X(const unsigned long long int i, const std::string set, unsigned int padding) {
|
||||||
if (set.length() == 0)
|
if (set.length() == 0)
|
||||||
return ""; // Return empty string, if set is empty. Play stupid games, win stupid prizes.
|
return ""; // Return empty string, if set is empty. Play stupid games, win stupid prizes.
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
if (i != 0)
|
if (i != 0) {
|
||||||
{
|
|
||||||
{
|
{
|
||||||
unsigned long long int buf = i;
|
unsigned long long int buf = i;
|
||||||
while (buf != 0)
|
while (buf != 0) {
|
||||||
{
|
|
||||||
const unsigned long long int mod = buf % set.length();
|
const unsigned long long int mod = buf % set.length();
|
||||||
buf /= set.length();
|
buf /= set.length();
|
||||||
ss << set[(std::size_t)mod];
|
ss << set[(std::size_t)mod];
|
||||||
@ -31,42 +27,34 @@ inline std::string Base10_2_X(const unsigned long long int i, const std::string
|
|||||||
{
|
{
|
||||||
const std::string buf = ss.str();
|
const std::string buf = ss.str();
|
||||||
ss.str("");
|
ss.str("");
|
||||||
for (long long int i = buf.length() - 1; i >= 0; i--)
|
for (long long int i = buf.length() - 1; i >= 0; i--) {
|
||||||
ss << buf[(std::size_t)i];
|
ss << buf[(std::size_t)i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
else {
|
||||||
ss << set[0]; // If i is 0, just pass a null-value. The algorithm would hang otherwise.
|
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.
|
// Add as much null-values to the left as requested.
|
||||||
if (ss.str().length() < padding)
|
if (ss.str().length() < padding) {
|
||||||
{
|
|
||||||
const std::size_t cachedLen = ss.str().length();
|
const std::size_t cachedLen = ss.str().length();
|
||||||
const std::string cachedStr = ss.str();
|
const std::string cachedStr = ss.str();
|
||||||
ss.str("");
|
ss.str("");
|
||||||
for (std::size_t i = 0; i < padding - cachedLen; i++)
|
for (std::size_t i = 0; i < padding - cachedLen; i++) {
|
||||||
ss << set[0];
|
ss << set[0];
|
||||||
|
}
|
||||||
ss << cachedStr;
|
ss << cachedStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ss.str();
|
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.
|
// 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.
|
// 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
|
// Already validated range: Password 0 - 1.000.000
|
||||||
TEST_METHOD(CollisionResistance)
|
TEST_CASE(__FILE__"/Password to key transformation collision resistance", "[Key extrapolation]") {
|
||||||
{
|
|
||||||
// To test resistence set this to a high number around a million.
|
// 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.
|
// 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;
|
constexpr std::size_t NUM_RUN_TESTS = 1000;
|
||||||
@ -76,10 +64,7 @@ namespace SimpleTests
|
|||||||
// Try NUM_RUN_TESTS passwords
|
// Try NUM_RUN_TESTS passwords
|
||||||
const std::string charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
const std::string charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
std::wstring_convert<convert_t, wchar_t> strconverter;
|
for (std::size_t i = 0; i < NUM_RUN_TESTS; i++) {
|
||||||
|
|
||||||
for (std::size_t i = 0; i < NUM_RUN_TESTS; i++)
|
|
||||||
{
|
|
||||||
// Get password
|
// Get password
|
||||||
const std::string password = Base10_2_X(i, charset, 0);
|
const std::string password = Base10_2_X(i, charset, 0);
|
||||||
|
|
||||||
@ -87,18 +72,16 @@ namespace SimpleTests
|
|||||||
const std::bitset<BLOCK_SIZE> newKey = PasswordToKey(password).Get();
|
const std::bitset<BLOCK_SIZE> newKey = PasswordToKey(password).Get();
|
||||||
|
|
||||||
// Check if this block is already in our map
|
// Check if this block is already in our map
|
||||||
if (keys.find(newKey) != keys.cend())
|
if (keys.find(newKey) != keys.cend()) {
|
||||||
{
|
std::cout << "Collision found between password \""
|
||||||
std::wstringstream wss;
|
<< password
|
||||||
wss << "Collision found between password \""
|
|
||||||
<< strconverter.from_bytes(password)
|
|
||||||
<< "\" and \""
|
<< "\" and \""
|
||||||
<< strconverter.from_bytes(keys[newKey])
|
<< keys[newKey]
|
||||||
<< "\". The key is \""
|
<< "\". The key is \""
|
||||||
<< newKey
|
<< newKey
|
||||||
<< "\".";
|
<< "\".";
|
||||||
|
|
||||||
Assert::Fail(wss.str().c_str());
|
FAIL();
|
||||||
}
|
}
|
||||||
|
|
||||||
// All good? Insert it into our map
|
// All good? Insert it into our map
|
||||||
@ -107,6 +90,4 @@ namespace SimpleTests
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user