This commit is contained in:
Lily Tsuru 2023-08-21 20:50:31 -04:00
commit c88ab93a10
9 changed files with 405 additions and 0 deletions

46
.clang-format Executable file
View File

@ -0,0 +1,46 @@
# .clang-format for native code portion
BasedOnStyle: Google
# force T* or T&
DerivePointerAlignment: false
PointerAlignment: Left
TabWidth: 4
IndentWidth: 4
UseTab: Always
IndentPPDirectives: BeforeHash
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true
BinPackArguments: true
BinPackParameters: true
BreakConstructorInitializers: BeforeColon
BreakStringLiterals: false
ColumnLimit: 150
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ContinuationIndentWidth: 0
# turning this on causes major issues with initalizer lists
Cpp11BracedListStyle: false
SpaceBeforeCpp11BracedList: true
FixNamespaceComments: true
NamespaceIndentation: All
ReflowComments: true
SortIncludes: CaseInsensitive
SortUsingDeclarations: true
SpacesInSquareBrackets: false
SpaceBeforeParens: Never
SpacesBeforeTrailingComments: 1

11
.editorconfig Normal file
View File

@ -0,0 +1,11 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
indent_style = tab
indent_size = 4
# spefcifically for YAML
[yml]
indent_style = space

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
# swap files various editors produce
*.kate-swp
*.swp
.cache/
build/
cmake-build-*/

42
CMakeLists.txt Normal file
View File

@ -0,0 +1,42 @@
cmake_minimum_required(VERSION 3.14)
project(swsf_bruteforce
LANGUAGES C CXX
)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
include(Policies)
include(ProjectFuncs)
# required system dependencies
find_package(Threads REQUIRED)
find_package(Boost REQUIRED)
# default linker
if(NOT SSXTOOLS_LINKER AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(SSXTOOLS_LINKER "lld")
elseif(NOT SSXTOOLS_LINKER)
set(SSXTOOLS_LINKER "bfd")
endif()
ssxtools_set_alternate_linker()
add_executable(swsf_scramble
src/asio_impl.cpp
src/main.cpp
)
target_compile_definitions(swsf_scramble PRIVATE
#-DBOOST_ASIO_HAS_IO_URING=1
# We compile Asio in another TU
-DBOOST_ASIO_SEPARATE_COMPILATION=1
-DBOOST_ASIO_NO_DEPRECATED=1
-DBOOST_ASIO_DISABLE_BOOST_ARRAY=1
-DBOOST_ASIO_DISABLE_BOOST_BIND=1
)
target_compile_features(swsf_scramble PRIVATE cxx_std_20)
target_include_directories(swsf_scramble PRIVATE ${PROJECT_SOURCE_DIR}/src)
ssxtools_target(swsf_scramble)

22
cmake/Policies.cmake Normal file
View File

@ -0,0 +1,22 @@
# CMake policy configuration
# Macro to enable new CMake policy.
# Makes this file a *LOT* shorter.
macro (_new_cmake_policy policy)
if(POLICY ${policy})
#message(STATUS "Enabling new policy ${policy}")
cmake_policy(SET ${policy} NEW)
endif()
endmacro()
_new_cmake_policy(CMP0026) # CMake 3.0: Disallow use of the LOCATION property for build targets.
_new_cmake_policy(CMP0042) # CMake 3.0+ (2.8.12): MacOS "@rpath" in target's install name
_new_cmake_policy(CMP0046) # warn about non-existent dependencies
_new_cmake_policy(CMP0048) # CMake 3.0+: project() command now maintains VERSION
_new_cmake_policy(CMP0054) # CMake 3.1: Only interpret if() arguments as variables or keywords when unquoted.
_new_cmake_policy(CMP0056) # try_compile() linker flags
_new_cmake_policy(CMP0066) # CMake 3.7: try_compile(): use per-config flags, like CMAKE_CXX_FLAGS_RELEASE
_new_cmake_policy(CMP0067) # CMake 3.8: try_compile(): honor language standard variables (like C++11)
_new_cmake_policy(CMP0068) # CMake 3.9+: `RPATH` settings on macOS do not affect `install_name`.
_new_cmake_policy(CMP0075) # CMake 3.12+: Include file check macros honor `CMAKE_REQUIRED_LIBRARIES`
_new_cmake_policy(CMP0077) # CMake 3.13+: option() honors normal variables.

73
cmake/ProjectFuncs.cmake Normal file
View File

@ -0,0 +1,73 @@
function(ssxtools_target target)
target_compile_definitions(${target} PRIVATE "$<$<CONFIG:DEBUG>:SSXTOOLS_DEBUG>")
# public headers reside with a component (if they exist)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_include_directories(${target} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
endif()
target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_features(${target} PUBLIC cxx_std_20)
# some sane compiler flags
set(_CORE_COMPILE_ARGS -Wall -Wextra)
set(_CORE_LINKER_ARGS "")
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
set(_CORE_COMPILE_ARGS ${_CORE_COMPILE_ARGS} -Werror)
# If on Release use link-time optimizations.
# On clang we use ThinLTO for even better build performance.
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(_CORE_COMPILE_ARGS ${_CORE_COMPILE_ARGS} -flto=thin)
set(_CORE_LINKER_ARGS ${_CORE_LINKER_ARGS} -flto=thin)
target_link_options(${target} PRIVATE -fuse-ld=${SSXTOOLS_LINKER} -flto=thin)
else()
set(_CORE_COMPILE_ARGS ${_CORE_COMPILE_ARGS} -flto)
set(_CORE_LINKER_ARGS ${_CORE_LINKER_ARGS} -flto)
target_link_options(${target} PRIVATE -fuse-ld=${SSXTOOLS_LINKER} -flto)
endif()
endif()
if("asan" IN_LIST SSXTOOLS_BUILD_FEATURES)
# Error if someone's trying to mix asan and tsan together,
# they aren't compatible.
if("tsan" IN_LIST SSXTOOLS_BUILD_FEATURES)
message(FATAL_ERROR "ASAN and TSAN cannot be used together.")
endif()
message(STATUS "Enabling ASAN for target ${target}")
set(_CORE_COMPILE_ARGS ${_CORE_COMPILE_ARGS} -fsanitize=address)
set(_CORE_LINKER_ARGS ${_CORE_LINKER_ARGS} -fsanitize=address)
endif()
if("tsan" IN_LIST SSXTOOLS_BUILD_FEATURES)
message(STATUS "Enabling TSAN for target ${target}")
set(_CORE_COMPILE_ARGS ${_CORE_COMPILE_ARGS} -fsanitize=thread)
set(_CORE_LINKER_ARGS ${_CORE_LINKER_ARGS} -fsanitize=thread)
endif()
if("ubsan" IN_LIST SSXTOOLS_BUILD_FEATURES)
message(STATUS "Enabling UBSAN for target ${target}")
set(_CORE_COMPILE_ARGS ${_CORE_COMPILE_ARGS} -fsanitize=undefined)
set(_CORE_LINKER_ARGS ${_CORE_LINKER_ARGS} -fsanitize=undefined)
endif()
target_compile_options(${target} PRIVATE ${_CORE_COMPILE_ARGS})
target_link_options(${target} PRIVATE ${_CORE_LINKER_ARGS})
endfunction()
function(ssxtools_header_only_target target)
target_include_directories(${target} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_features(${target} INTERFACE cxx_std_20)
endfunction()
function(ssxtools_set_alternate_linker)
find_program(LINKER_EXECUTABLE ld.${SSXTOOLS_LINKER} ${SSXTOOLS_LINKER})
if(LINKER_EXECUTABLE)
message(STATUS "Using ${SSXTOOLS_LINKER} as linker for ssxtools projects")
else()
message(FATAL_ERROR "Linker ${SSXTOOLS_LINKER} does not exist on your system. Please specify one which does or omit this option from your configure command.")
endif()
endfunction()

5
src/asio_impl.cpp Normal file
View File

@ -0,0 +1,5 @@
// Since we're using (BOOST_)ASIO_SEPARATE_COMPILATION, we need
// to include the <(boost/)asio/impl/src.hpp> header in some TU.
// We use this one to explicitly do so.
#include <boost/asio/impl/src.hpp>

114
src/main.cpp Normal file
View File

@ -0,0 +1,114 @@
#include <boost/asio/experimental/concurrent_channel.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/thread_pool.hpp>
#include <boost/system/detail/error_code.hpp>
#include <format>
#include <iostream>
namespace asio = boost::asio;
// nvm doesnt work lol :)
//using asio::experimental::concurrent_channel;
template <class TRandomAlgo>
std::string RandomString(std::uint32_t length, TRandomAlgo& rng) {
std::string s;
s.resize(length);
while(true) {
auto res = rng();
auto acc = 0u;
// I love bit hacks!!!
for(int i = 0; i < sizeof(res); ++i) {
std::uint8_t c = (res >> acc);
if(c >= 0x20 && c <= 0x7e) {
if(length-- <= 0)
return s;
s.push_back(c);
}
acc += CHAR_BIT;
}
}
}
std::uint32_t SwsfScramble(const std::string& code) {
auto copy = std::format("code_{}", code);
for(auto& c : copy)
c = tolower(c);
std::uint32_t tally {};
for(auto* p = copy.data(); *p; ++p)
tally = *p + (tally * 5);
return tally;
}
// using ChannelType = concurrent_channel<void(std::string& codeMatch)>;
// These is not atomic since no other threads update it
// there is no real point to making it atomic, other than
//
// maybe preventing some false sharing or other perf problem
// ... but I don't think that matters, lol
std::uint32_t code_hash = 0x2c75af55;
std::uint32_t code_length = 8;
bool NextCode(std::string& buffer, size_t start) {
size_t len = buffer.length();
for(size_t i = len - 1; i >= start; --i) {
char c = buffer[i];
if(c < 'z') {
++buffer[i];
return true;
}
buffer[i] = 'a';
}
return false;
}
void ThreadFunction(char prefix) {
for(std::uint32_t i = 2; i < code_length; ++i) {
std::string test_buffer(i, 'a');
test_buffer[0] = prefix;
// test all possible combinations
while(true) {
std::cout << std::format("trying code \"{}\"...\r", test_buffer);
if(SwsfScramble(test_buffer) == code_hash) {
std::cerr << std::format("match: {}", test_buffer);
}
if(!NextCode(test_buffer, 1))
break;
}
}
#if 0
std::string test_buffer(code_length, 'a');
test_buffer[0] = prefix;
while(true) {
std::cout << std::format("trying code \"{}\"...\r", test_buffer);
if(SwsfScramble(test_buffer) == code_hash) {
std::cerr << std::format("match: {}", test_buffer);
}
if(!NextCode(test_buffer, 1))
return;
}
#endif
}
int main(int argc, char** argv) {
asio::io_context ioc;
asio::thread_pool pool(26);
// Channel
// ChannelType channel(ioc);
// post onto the thread pool
for(int i = 0; i < 26; ++i)
asio::post(pool, [i]() { ThreadFunction('a' + i); });
pool.join();
return 0;
}

85
src/xoshiro.hpp Normal file
View File

@ -0,0 +1,85 @@
#include <cstddef>
#include <cstdint>
#include <climits> // CHAR_BIT
#include <random>
namespace swbf {
namespace detail {
template <class T>
constexpr size_t BitSizeOf() {
return sizeof(T) * CHAR_BIT;
}
constexpr std::uint64_t splitmix64(std::uint64_t x) {
std::uint64_t z = (x += 0x9e3779b97f4a7c15uLL);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9uLL;
z = (z ^ (z >> 27)) * 0x94d049bb133111ebuLL;
return z ^ (z >> 31);
}
constexpr std::uint64_t rotl(std::uint64_t x, int k) {
return (x << k) | (x >> (BitSizeOf<std::uint64_t>() - k));
}
/**
* Xoshiro256** as a C++ RandomNumberEngine,
* which can be used in C++ random algorithms.
*/
struct Xoshiro256ss {
using result_type = std::uint64_t;
std::uint64_t s[4] {};
constexpr explicit Xoshiro256ss() : Xoshiro256ss(0) {}
constexpr explicit Xoshiro256ss(std::uint64_t seed) {
s[0] = splitmix64(seed);
s[1] = splitmix64(seed);
s[2] = splitmix64(seed);
s[3] = splitmix64(seed);
}
/**
* Constructor for seeding from a `std::random_device`.
*
* \param[in] rd Random device to seed this engine with.
*/
constexpr explicit Xoshiro256ss(std::random_device& rd) {
// Get 64 bits out of the random device.
//
// This lambda is quite literal, as it fetches
// 2 iterations of the random engine, and
// shifts + OR's them into a 64bit value.
auto get_u64 = [&rd] {
std::uint64_t the_thing = rd();
return (the_thing << 32) | rd();
};
// seed with 256 bits of entropy from the random device + splitmix64
// to ensure we seed it well, as per recommendation.
s[0] = splitmix64(get_u64());
s[1] = splitmix64(get_u64());
s[2] = splitmix64(get_u64());
s[3] = splitmix64(get_u64());
}
static constexpr result_type min() { return 0; }
static constexpr result_type max() { return std::uint64_t(-1); }
constexpr result_type operator()() {
result_type result = rotl(s[1] * 5, 7) * 9;
result_type t = s[1] << 17;
s[2] ^= s[0];
s[3] ^= s[1];
s[1] ^= s[2];
s[0] ^= s[3];
s[2] ^= t;
s[3] = rotl(s[3], 45);
return result;
}
};
} // namespace detail
using detail::Xoshiro256ss;
} // namespace swbf