From fc32f219e4635afaa5fe6969141361144b99c666 Mon Sep 17 00:00:00 2001 From: Twilight-Dream-Of-Magic <1187791459@qq.com> Date: Sat, 16 Jul 2022 10:52:44 +0800 Subject: [PATCH] [This is a fix change] First, fix the legacy bugs Then, make the source code about generation random number seeds. Also, fixed compiler errors on posix linux systems, and my build project scripts It also refactored the error logic of the Cryptograph::DataPermutation::HexadecimalStringCoder class to make it easier to provide encoding and decoding methods for the data in other modules. --- CMakeLists.txt | 8 +- build-project.bat | 7 +- build-project.sh | 11 +- include/CommonSecurity/BlockDataCryption.hpp | 200 ++++++--- include/CommonSecurity/CommonSecurity.hpp | 415 +++++++++++------- include/CommonSecurity/DataHashingWrapper.hpp | 20 +- .../KeyDerivationFunction/AlgorithmArgon2.hpp | 20 +- .../RefactoringCodeImplement.hpp | 288 ++++++------ .../SecureHashProvider/AlgorithmBlake3.hpp | 66 ++- .../SecureHashProvider/Hasher.hpp | 30 +- .../SecureHashProviderBase.hpp | 22 +- include/CommonSecurity/StreamDataCryption.hpp | 157 ++++--- .../CommonToolkit/BytesExchangeInteger.hpp | 69 ++- include/CommonToolkit/CPP2020_Concept.hpp | 8 +- include/CommonToolkit/CommonToolkit.hpp | 115 ++--- .../ByteSubstitutionBoxToolkit.hpp | 16 +- .../CrypticDataThreadingWrapper.hpp | 309 ++++++------- include/CustomSecurity/CryptionWorker.hpp | 34 +- include/CustomSecurity/CustomCryption.hpp | 116 +++-- include/CustomSecurity/DataObfuscator.hpp | 62 ++- include/FileProcessing/FileOperationNew.hpp | 88 ++-- include/FileProcessing/FileProcessing.hpp | 28 +- include/Support+Library/Support-Library.hpp | 12 +- include/UtilTools/CompressDataProcessing.hpp | 2 + include/UtilTools/DataFormating.hpp | 1 - include/UtilTools/DataStreamConverter.hpp | 22 +- source-code/IsFor_EODF_Reborn.hpp | 72 +-- 27 files changed, 1268 insertions(+), 930 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 62c9303..757a244 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,10 +11,10 @@ set(CMAKE_BUILD_TYPE release) # set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) -#set(SOURCES -# src/Main.cpp -# src/IsFor_EODF_Reborn.hpp -#) +set(SOURCES + src/Main.cpp + src/IsFor_EODF_Reborn.hpp +) add_subdirectory(${PROJECT_SOURCE_DIR}/extra/mio) diff --git a/build-project.bat b/build-project.bat index 2f05fe5..bf22db6 100644 --- a/build-project.bat +++ b/build-project.bat @@ -7,12 +7,13 @@ IF NOT EXIST ".\build-project" ( CD /d ".\build-project" -cmake .. +cmake -S ..\ -B . IF EXIST ".\Makefile" ( - make . + make help + make TDOM-EncryptOrDecryptFile-Reborn ) ELSE ( msbuild TDOM-EncryptOrDecryptFile-Reborn.sln ) -PAUSE \ No newline at end of file +PAUSE diff --git a/build-project.sh b/build-project.sh index 3d1abb9..2e631f1 100644 --- a/build-project.sh +++ b/build-project.sh @@ -2,11 +2,16 @@ # --parents -if [ -d "./build-project"]; +if [ -d "./build-project" ]; then mkdir --verbose "./build-project" fi cd "./build-project" -cmake ../CMakeLists.txt -make . + +#cmake -S is SourceCodePath +#cmake -B is BuildScriptPath + +sudo cmake -S ../ -B . +sudo make help +sudo make TDOM-EncryptOrDecryptFile-Reborn diff --git a/include/CommonSecurity/BlockDataCryption.hpp b/include/CommonSecurity/BlockDataCryption.hpp index 2bd33e6..11ff601 100644 --- a/include/CommonSecurity/BlockDataCryption.hpp +++ b/include/CommonSecurity/BlockDataCryption.hpp @@ -761,7 +761,7 @@ namespace CommonSecurity::AES * @param out; The result of AES encryption (std::deque). * @return Encryption result as boolean (true: SUCCESS; false: FAILED). */ - bool EncryptionWithECB(std::vector input, const std::vector& key, std::vector& output) + bool EncryptionWithECB(const std::vector& input, const std::vector& key, std::vector& output) { if(this->Number_Key_Data_Block_Size == 0 && this->Number_Execute_Round_Count == 0) { @@ -774,20 +774,22 @@ namespace CommonSecurity::AES if(input.empty()) return false; - DataPadding(input); + std::vector data_copy_input(input.begin(), input.end()); + + DataPadding(data_copy_input); //Key data for extension //密钥数据进行扩展 std::vector expandedWordRoundKeyBlock; this->KeyExpansion(key, expandedWordRoundKeyBlock); - auto iteratorBegin_input = input.begin(); - auto iteratorEnd_input = input.end(); + auto iteratorBegin_input = data_copy_input.begin(); + auto iteratorEnd_input = data_copy_input.end(); auto iteratorBegin_output = output.begin(); auto iteratorEnd_output = output.end(); - for (std::size_t index = 0; index < input.size(); index += this->Number_Block_Data_Byte_Size) + for (std::size_t index = 0; index < data_copy_input.size(); index += this->Number_Block_Data_Byte_Size) { std::size_t iteratorOffset = this->Number_Block_Data_Byte_Size; std::size_t iteratorOffset2 = this->Number_Block_Data_Byte_Size; @@ -804,6 +806,11 @@ namespace CommonSecurity::AES output.insert(output.end(), outputDataSubrange.begin(), outputDataSubrange.end()); } + data_copy_input.clear(); + data_copy_input.shrink_to_fit(); + expandedWordRoundKeyBlock.clear(); + expandedWordRoundKeyBlock.shrink_to_fit(); + return true; } @@ -815,7 +822,7 @@ namespace CommonSecurity::AES * @param out; The result of AES decryption (deque). * @return Decryption result as boolean (true: SUCCESS; false: FAILED). */ - bool DecryptionWithECB(std::vector input, const std::vector& key, std::vector& output) + bool DecryptionWithECB(const std::vector& input, const std::vector& key, std::vector& output) { if(this->Number_Key_Data_Block_Size == 0 && this->Number_Execute_Round_Count == 0) { @@ -828,18 +835,20 @@ namespace CommonSecurity::AES if (input.empty() || (input.size() % this->Number_Block_Data_Byte_Size != 0)) return false; + std::vector data_copy_input(input.begin(), input.end()); + //Key data for extension //密钥数据进行扩展 std::vector expandedWordRoundKeyBlock; this->KeyExpansion(key, expandedWordRoundKeyBlock); - auto iteratorBegin_input = input.begin(); - auto iteratorEnd_input = input.end(); + auto iteratorBegin_input = data_copy_input.begin(); + auto iteratorEnd_input = data_copy_input.end(); auto iteratorBegin_output = output.begin(); auto iteratorEnd_output = output.end(); - for (std::size_t index = 0; index < input.size(); index += this->Number_Block_Data_Byte_Size) + for (std::size_t index = 0; index < data_copy_input.size(); index += this->Number_Block_Data_Byte_Size) { std::size_t iteratorOffset = this->Number_Block_Data_Byte_Size; std::size_t iteratorOffset2 = this->Number_Block_Data_Byte_Size; @@ -857,6 +866,11 @@ namespace CommonSecurity::AES } DataUnpadding(output); + + data_copy_input.clear(); + data_copy_input.shrink_to_fit(); + expandedWordRoundKeyBlock.clear(); + expandedWordRoundKeyBlock.shrink_to_fit(); return true; } @@ -902,7 +916,7 @@ namespace CommonSecurity::AES * @param out; The result of AES encryption (deque). * @return Encryption result as boolean (true: SUCCESS; false: FAILED). */ - bool EncryptionWithCBC(std::vector input, const std::vector& key, const std::vector& initialVector, std::vector& output) + bool EncryptionWithCBC(const std::vector& input, const std::vector& key, const std::vector& initialVector, std::vector& output) { using namespace AES::ProcedureFunctions; @@ -919,22 +933,24 @@ namespace CommonSecurity::AES if (initialVector.size() != this->Number_Block_Data_Byte_Size) return false; - DataPadding(input); + std::vector data_copy_input(input.begin(), input.end()); + DataPadding(data_copy_input); + //Key data for extension //密钥数据进行扩展 std::vector expandedWordRoundKeyBlock; this->KeyExpansion(key, expandedWordRoundKeyBlock); - auto iteratorBegin_input = input.begin(); - auto iteratorEnd_input = input.end(); + auto iteratorBegin_input = data_copy_input.begin(); + auto iteratorEnd_input = data_copy_input.end(); auto iteratorBegin_output = output.begin(); auto iteratorEnd_output = output.end(); std::vector initialVectorBlock(initialVector); - for (std::size_t index = 0; index < input.size(); index += this->Number_Block_Data_Byte_Size) + for (std::size_t index = 0; index < data_copy_input.size(); index += this->Number_Block_Data_Byte_Size) { std::size_t iteratorOffset = this->Number_Block_Data_Byte_Size; std::size_t iteratorOffset2 = this->Number_Block_Data_Byte_Size; @@ -961,6 +977,13 @@ namespace CommonSecurity::AES //下一轮的初始向量数据是输出数据 } + data_copy_input.clear(); + data_copy_input.shrink_to_fit(); + initialVectorBlock.clear(); + initialVectorBlock.shrink_to_fit(); + expandedWordRoundKeyBlock.clear(); + expandedWordRoundKeyBlock.shrink_to_fit(); + return true; } @@ -972,7 +995,7 @@ namespace CommonSecurity::AES * @param out; The result of AES decryption (deque). * @return Decryption result as boolean (true: SUCCESS; false: FAILED). */ - bool DecryptionWithCBC(std::vector input, const std::vector& key, const std::vector& initialVector, std::vector& output) + bool DecryptionWithCBC(const std::vector& input, const std::vector& key, const std::vector& initialVector, std::vector& output) { using namespace AES::ProcedureFunctions; @@ -989,20 +1012,22 @@ namespace CommonSecurity::AES if (initialVector.size() != this->Number_Block_Data_Byte_Size) return false; + std::vector data_copy_input(input.begin(), input.end()); + //Key data for extension //密钥数据进行扩展 std::vector expandedWordRoundKeyBlock; this->KeyExpansion(key, expandedWordRoundKeyBlock); - auto iteratorBegin_input = input.begin(); - auto iteratorEnd_input = input.end(); + auto iteratorBegin_input = data_copy_input.begin(); + auto iteratorEnd_input = data_copy_input.end(); auto iteratorBegin_output = output.begin(); auto iteratorEnd_output = output.end(); std::vector initialVectorBlock(initialVector); - for (std::size_t index = 0; index < input.size(); index += this->Number_Block_Data_Byte_Size) + for (std::size_t index = 0; index < data_copy_input.size(); index += this->Number_Block_Data_Byte_Size) { std::size_t iteratorOffset = this->Number_Block_Data_Byte_Size; std::size_t iteratorOffset2 = this->Number_Block_Data_Byte_Size; @@ -1031,6 +1056,13 @@ namespace CommonSecurity::AES DataUnpadding(output); + data_copy_input.clear(); + data_copy_input.shrink_to_fit(); + initialVectorBlock.clear(); + initialVectorBlock.shrink_to_fit(); + expandedWordRoundKeyBlock.clear(); + expandedWordRoundKeyBlock.shrink_to_fit(); + return true; } @@ -1059,7 +1091,7 @@ namespace CommonSecurity::AES * @param out; The result of AES encryption (deque). * @return Encryption result as boolean (true: SUCCESS; false: FAILED). */ - bool EncryptionWithPCBC(std::vector input, const std::vector& key, const std::vector& initialVector, std::vector& output) + bool EncryptionWithPCBC(const std::vector& input, const std::vector& key, const std::vector& initialVector, std::vector& output) { using namespace AES::ProcedureFunctions; @@ -1076,22 +1108,24 @@ namespace CommonSecurity::AES if (initialVector.size() != this->Number_Block_Data_Byte_Size) return false; - DataPadding(input); + std::vector data_copy_input(input.begin(), input.end()); + + DataPadding(data_copy_input); //Key data for extension //密钥数据进行扩展 std::vector expandedWordRoundKeyBlock; this->KeyExpansion(key, expandedWordRoundKeyBlock); - auto iteratorBegin_input = input.begin(); - auto iteratorEnd_input = input.end(); + auto iteratorBegin_input = data_copy_input.begin(); + auto iteratorEnd_input = data_copy_input.end(); auto iteratorBegin_output = output.begin(); auto iteratorEnd_output = output.end(); std::vector initialVectorBlock(initialVector); - for (std::size_t index = 0; index < input.size(); index += this->Number_Block_Data_Byte_Size) + for (std::size_t index = 0; index < data_copy_input.size(); index += this->Number_Block_Data_Byte_Size) { std::size_t iteratorOffset = this->Number_Block_Data_Byte_Size; std::size_t iteratorOffset2 = this->Number_Block_Data_Byte_Size; @@ -1118,6 +1152,13 @@ namespace CommonSecurity::AES //下一轮的初始向量数据是输出数据 } + data_copy_input.clear(); + data_copy_input.shrink_to_fit(); + initialVectorBlock.clear(); + initialVectorBlock.shrink_to_fit(); + expandedWordRoundKeyBlock.clear(); + expandedWordRoundKeyBlock.shrink_to_fit(); + return true; } @@ -1129,7 +1170,7 @@ namespace CommonSecurity::AES * @param out; The result of AES decryption (deque). * @return Decryption result as boolean (true: SUCCESS; false: FAILED). */ - bool DecryptionWithPCBC(std::vector input, const std::vector& key, const std::vector& initialVector, std::vector& output) + bool DecryptionWithPCBC(const std::vector& input, const std::vector& key, const std::vector& initialVector, std::vector& output) { using namespace AES::ProcedureFunctions; @@ -1146,20 +1187,22 @@ namespace CommonSecurity::AES if (initialVector.size() != this->Number_Block_Data_Byte_Size) return false; + std::vector data_copy_input(input.begin(), input.end()); + //Key data for extension //密钥数据进行扩展 std::vector expandedWordRoundKeyBlock; this->KeyExpansion(key, expandedWordRoundKeyBlock); - auto iteratorBegin_input = input.begin(); - auto iteratorEnd_input = input.end(); + auto iteratorBegin_input = data_copy_input.begin(); + auto iteratorEnd_input = data_copy_input.end(); auto iteratorBegin_output = output.begin(); auto iteratorEnd_output = output.end(); std::vector initialVectorBlock(initialVector); - for (std::size_t index = 0; index < input.size(); index += this->Number_Block_Data_Byte_Size) + for (std::size_t index = 0; index < data_copy_input.size(); index += this->Number_Block_Data_Byte_Size) { std::size_t iteratorOffset = this->Number_Block_Data_Byte_Size; std::size_t iteratorOffset2 = this->Number_Block_Data_Byte_Size; @@ -1188,6 +1231,13 @@ namespace CommonSecurity::AES DataUnpadding(output); + data_copy_input.clear(); + data_copy_input.shrink_to_fit(); + initialVectorBlock.clear(); + initialVectorBlock.shrink_to_fit(); + expandedWordRoundKeyBlock.clear(); + expandedWordRoundKeyBlock.shrink_to_fit(); + return true; } @@ -1218,7 +1268,7 @@ namespace CommonSecurity::AES * @param out; The result of AES encryption (deque). * @return Encryption result as boolean (true: SUCCESS; false: FAILED). */ - bool EncryptionWithCFB(std::vector input, const std::vector& key, std::vector initialVector, std::vector& output) + bool EncryptionWithCFB(const std::vector& input, const std::vector& key, const std::vector& initialVector, std::vector& output) { using namespace AES::ProcedureFunctions; @@ -1235,22 +1285,24 @@ namespace CommonSecurity::AES if (initialVector.size() != this->Number_Block_Data_Byte_Size) return false; - DataPadding(input); + std::vector data_copy_input(input.begin(), input.end()); + DataPadding(data_copy_input); + //Key data for extension //密钥数据进行扩展 std::vector expandedWordRoundKeyBlock; this->KeyExpansion(key, expandedWordRoundKeyBlock); - auto iteratorBegin_input = input.begin(); - auto iteratorEnd_input = input.end(); + auto iteratorBegin_input = data_copy_input.begin(); + auto iteratorEnd_input = data_copy_input.end(); auto iteratorBegin_output = output.begin(); auto iteratorEnd_output = output.end(); std::vector initialVectorBlock(initialVector); - for (std::size_t index = 0; index < input.size(); index += this->Number_Block_Data_Byte_Size) + for (std::size_t index = 0; index < data_copy_input.size(); index += this->Number_Block_Data_Byte_Size) { std::size_t iteratorOffset = this->Number_Block_Data_Byte_Size; std::size_t iteratorOffset2 = this->Number_Block_Data_Byte_Size; @@ -1274,6 +1326,13 @@ namespace CommonSecurity::AES outputDataSubrange.clear(); } + data_copy_input.clear(); + data_copy_input.shrink_to_fit(); + initialVectorBlock.clear(); + initialVectorBlock.shrink_to_fit(); + expandedWordRoundKeyBlock.clear(); + expandedWordRoundKeyBlock.shrink_to_fit(); + return true; } @@ -1285,7 +1344,7 @@ namespace CommonSecurity::AES * @param out; The result of AES decryption (deque). * @return Decryption result as boolean (true: SUCCESS; false: FAILED). */ - bool DecryptionWithCFB(std::vector input, const std::vector& key, std::vector initialVector, std::vector& output) + bool DecryptionWithCFB(const std::vector& input, const std::vector& key, const std::vector& initialVector, std::vector& output) { using namespace AES::ProcedureFunctions; @@ -1302,20 +1361,22 @@ namespace CommonSecurity::AES if (initialVector.size() != this->Number_Block_Data_Byte_Size) return false; + std::vector data_copy_input(input.begin(), input.end()); + //Key data for extension //密钥数据进行扩展 std::vector expandedWordRoundKeyBlock; this->KeyExpansion(key, expandedWordRoundKeyBlock); - auto iteratorBegin_input = input.begin(); - auto iteratorEnd_input = input.end(); + auto iteratorBegin_input = data_copy_input.begin(); + auto iteratorEnd_input = data_copy_input.end(); auto iteratorBegin_output = output.begin(); auto iteratorEnd_output = output.end(); std::vector initialVectorBlock(initialVector); - for (std::size_t index = 0; index < input.size(); index += this->Number_Block_Data_Byte_Size) + for (std::size_t index = 0; index < data_copy_input.size(); index += this->Number_Block_Data_Byte_Size) { std::size_t iteratorOffset = this->Number_Block_Data_Byte_Size; std::size_t iteratorOffset2 = this->Number_Block_Data_Byte_Size; @@ -1339,7 +1400,16 @@ namespace CommonSecurity::AES outputDataSubrange.clear(); } + data_copy_input.clear(); + data_copy_input.shrink_to_fit(); + initialVectorBlock.clear(); + initialVectorBlock.shrink_to_fit(); + expandedWordRoundKeyBlock.clear(); + expandedWordRoundKeyBlock.shrink_to_fit(); + DataUnpadding(output); + + return true; } /* @@ -1367,7 +1437,7 @@ namespace CommonSecurity::AES * @param out; The result of AES encryption (deque). * @return Encryption result as boolean (true: SUCCESS; false: FAILED). */ - bool EncryptionWithOFB(std::vector input, const std::vector& key, std::vector initialVector, std::vector& output) + bool EncryptionWithOFB(const std::vector& input, const std::vector& key, const std::vector& initialVector, std::vector& output) { using namespace AES::ProcedureFunctions; @@ -1384,22 +1454,24 @@ namespace CommonSecurity::AES if (initialVector.size() != this->Number_Block_Data_Byte_Size) return false; - DataPadding(input); + std::vector data_copy_input(input.begin(), input.end()); + DataPadding(data_copy_input); + //Key data for extension //密钥数据进行扩展 std::vector expandedWordRoundKeyBlock; this->KeyExpansion(key, expandedWordRoundKeyBlock); - auto iteratorBegin_input = input.begin(); - auto iteratorEnd_input = input.end(); + auto iteratorBegin_input = data_copy_input.begin(); + auto iteratorEnd_input = data_copy_input.end(); auto iteratorBegin_output = output.begin(); auto iteratorEnd_output = output.end(); std::vector initialVectorBlock(initialVector); - for (std::size_t index = 0; index < input.size(); index += this->Number_Block_Data_Byte_Size) + for (std::size_t index = 0; index < data_copy_input.size(); index += this->Number_Block_Data_Byte_Size) { std::size_t iteratorOffset = this->Number_Block_Data_Byte_Size; std::size_t iteratorOffset2 = this->Number_Block_Data_Byte_Size; @@ -1423,6 +1495,13 @@ namespace CommonSecurity::AES outputDataSubrange.clear(); } + data_copy_input.clear(); + data_copy_input.shrink_to_fit(); + initialVectorBlock.clear(); + initialVectorBlock.shrink_to_fit(); + expandedWordRoundKeyBlock.clear(); + expandedWordRoundKeyBlock.shrink_to_fit(); + return true; } @@ -1434,7 +1513,7 @@ namespace CommonSecurity::AES * @param out; The result of AES decryption (deque). * @return Decryption result as boolean (true: SUCCESS; false: FAILED). */ - bool DecryptionWithOFB(std::vector input, const std::vector& key, std::vector initialVector, std::vector& output) + bool DecryptionWithOFB(const std::vector& input, const std::vector& key, const std::vector& initialVector, std::vector& output) { using namespace AES::ProcedureFunctions; @@ -1451,20 +1530,22 @@ namespace CommonSecurity::AES if (initialVector.size() != this->Number_Block_Data_Byte_Size) return false; + std::vector data_copy_input(input.begin(), input.end()); + //Key data for extension //密钥数据进行扩展 std::vector expandedWordRoundKeyBlock; this->KeyExpansion(key, expandedWordRoundKeyBlock); - auto iteratorBegin_input = input.begin(); - auto iteratorEnd_input = input.end(); + auto iteratorBegin_input = data_copy_input.begin(); + auto iteratorEnd_input = data_copy_input.end(); auto iteratorBegin_output = output.begin(); auto iteratorEnd_output = output.end(); std::vector initialVectorBlock(initialVector); - for (std::size_t index = 0; index < input.size(); index += this->Number_Block_Data_Byte_Size) + for (std::size_t index = 0; index < data_copy_input.size(); index += this->Number_Block_Data_Byte_Size) { std::size_t iteratorOffset = this->Number_Block_Data_Byte_Size; std::size_t iteratorOffset2 = this->Number_Block_Data_Byte_Size; @@ -1488,7 +1569,16 @@ namespace CommonSecurity::AES outputDataSubrange.clear(); } + data_copy_input.clear(); + data_copy_input.shrink_to_fit(); + initialVectorBlock.clear(); + initialVectorBlock.shrink_to_fit(); + expandedWordRoundKeyBlock.clear(); + expandedWordRoundKeyBlock.shrink_to_fit(); + DataUnpadding(output); + + return true; } Worker(AES_SecurityLevel SecurityLevel) : Number_Block_Data_Byte_Size(this->ONE_WORD_BYTE_SIZE * this->NUMBER_DATA_BLOCK_COUNT * sizeof(unsigned char)) @@ -3353,6 +3443,11 @@ namespace CommonSecurity::TripleDES for(std::size_t index = Bitset64_Keys.size() - 1; index > 0; index -= 3) { + if(index >= Bitset64_Keys.size()) + { + break; + } + //Use Decryption Main Round Key 1 DES_Worker.UpadateMainKeyAndSubKey(Bitset64_Keys.operator[](index)); temporaryDataBlock = DES_Worker.DES_Executor(buffer, Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_DECRYPTER, temporaryDataBlock, false); @@ -3793,32 +3888,31 @@ namespace CommonSecurity::RC6 //PKCS is Public Key Cryptography Standards /* https://en.wikipedia.org/wiki/Padding_(cryptography) - https://datatracker.ietf.org/doc/html/rfc5652 - PKCS#7 is described in RFC 5652. (section-6.3) Padding is in whole bytes. The value of each added byte is the number of bytes that are added, i.e. bytes, each of value are added. The number of bytes added will depend on the block boundary to which the message needs to be extended. */ - //Padding Data + //Padding Data #5 standard + if(dataBlockByteSize % 16 != 0) { if(dataBlockByteSize > 16) { std::size_t paddingDataByteSize = 16 - (dataBlockByteSize % 16); - const std::vector paddingDataBytes(static_cast(paddingDataByteSize), paddingDataByteSize); + const std::vector paddingDataBytes(paddingDataByteSize, static_cast(paddingDataByteSize)); dataBlockCopy.insert( dataBlockCopy.end(), paddingDataBytes.begin(), paddingDataBytes.end() ); } else if(dataBlockByteSize < 16) { std::size_t paddingDataByteSize = 16 - dataBlockByteSize; - const std::vector paddingDataBytes(static_cast(paddingDataByteSize), paddingDataByteSize); + const std::vector paddingDataBytes(paddingDataByteSize, static_cast(paddingDataByteSize)); dataBlockCopy.insert( dataBlockCopy.end(), paddingDataBytes.begin(), paddingDataBytes.end() ); } } else { - const std::vector paddingDataBytes(static_cast(16), 16); + const std::vector paddingDataBytes(16, static_cast(16)); dataBlockCopy.insert( dataBlockCopy.end(), paddingDataBytes.begin(), paddingDataBytes.end() ); } @@ -3842,14 +3936,12 @@ namespace CommonSecurity::RC6 //PKCS is Public Key Cryptography Standards /* https://en.wikipedia.org/wiki/Padding_(cryptography) - https://datatracker.ietf.org/doc/html/rfc5652 - PKCS#7 is described in RFC 5652. (section-6.3) Padding is in whole bytes. The value of each added byte is the number of bytes that are added, i.e. bytes, each of value are added. The number of bytes added will depend on the block boundary to which the message needs to be extended. */ - //Unpadding Data + //Unpadding Data #5 standard unsigned int paddingDataByteSize = processedDataBlock.back(); diff --git a/include/CommonSecurity/CommonSecurity.hpp b/include/CommonSecurity/CommonSecurity.hpp index 42ef296..47a8b14 100644 --- a/include/CommonSecurity/CommonSecurity.hpp +++ b/include/CommonSecurity/CommonSecurity.hpp @@ -8,7 +8,7 @@ * 发布 TDOM-EncryptOrDecryptFile-Reborn 是希望它能有用,但是并无保障;甚至连可销售和符合某个特定的目的都不保证。请参看 GNU 通用公共许可证,了解详情。 * 你应该随程序获得一份 GNU 通用公共许可证的复本。如果没有,请看 。 */ - + /* * Copyright (C) 2021-2022 Twilight-Dream * @@ -138,6 +138,73 @@ namespace CommonSecurity #endif + //生成安全的随机数 + //Generate secure random number + inline auto GenerateSecureRandomNumber(std::random_device& true_hardware_random_device) + { + //This is current timestamp + //当前时间戳 + + auto system_clock_current_timestamp = std::chrono::duration_cast + ( + std::chrono::system_clock::now().time_since_epoch() + ).count(); + + auto high_resolution_clock_current_timestamp = std::chrono::duration_cast + ( + std::chrono::high_resolution_clock::now().time_since_epoch() + ).count(); + + + /*return static_cast(true_hardware_random_device()) + ^ static_cast(system_clock_current_timestamp) + ^ static_cast(high_resolution_clock_current_timestamp);*/ + + /*return static_cast(true_hardware_random_device()) + ^ static_cast(system_clock_current_timestamp) + ^ static_cast(high_resolution_clock_current_timestamp >> 32) + ^ static_cast(high_resolution_clock_current_timestamp) + ^ static_cast(system_clock_current_timestamp >> 32);*/ + + return static_cast(true_hardware_random_device()) + ^ static_cast(system_clock_current_timestamp) + ^ static_cast(high_resolution_clock_current_timestamp >> 32) + ^ static_cast(high_resolution_clock_current_timestamp) + ^ static_cast(system_clock_current_timestamp >> 32); + } + + //生成安全的随机数种子 + //Generate secure random number seeds + template requires std::integral + inline RandomNumberSeedType GenerateSecureRandomNumberSeed(std::random_device& true_hardware_random_device) + { + /* + RandomNumberSeedType random_number_value = CURRENT_SYSTEM_BITS == 64 + ? static_cast( GenerateSecureRandomNumber(true_hardware_random_device) ) ^ static_cast( GenerateSecureRandomNumber(true_hardware_random_device) >> 32) + : static_cast( GenerateSecureRandomNumber(true_hardware_random_device) ); + */ + + RandomNumberSeedType random_number_value = static_cast( GenerateSecureRandomNumber(true_hardware_random_device) ); + + return random_number_value; + } + + //生成安全的随机数种子序列 + //Generate a secure sequence of random number seeds + template requires std::integral + inline std::vector GenerateSecureRandomNumberSeedSequence(std::size_t size) + { + std::random_device true_hardware_random_device; + std::vector random_number_seed_sequence(size, 0); + + for(auto& current_random_number : random_number_seed_sequence) + { + current_random_number = GenerateSecureRandomNumberSeed(true_hardware_random_device); + } + + return random_number_seed_sequence; + } + namespace RNG_SimpleImplementation { class ExampleGenerator @@ -151,7 +218,7 @@ namespace CommonSecurity _SEED_NUMBER_ = ( _SEED_NUMBER_ * 0x41c64e6dU + 0x3039U ) & 0x7fffffff; return _SEED_NUMBER_; } - + public: static unsigned int _SEED_NUMBER_; @@ -163,7 +230,7 @@ namespace CommonSecurity ExampleGenerator( std::random_device& random_device_object ) { - _SEED_NUMBER_ = random_device_object(); + _SEED_NUMBER_ = GenerateSecureRandomNumberSeed(random_device_object); } ExampleGenerator( int seed_number ) @@ -210,7 +277,7 @@ namespace CommonSecurity seed_number = seed_number * 214013 + 2531011; return (seed_number >> 16) & 0x7fff; } - + public: static int _SEED_NUMBER_; @@ -222,7 +289,7 @@ namespace CommonSecurity ExampleGenerator2( std::random_device& random_device_object ) { - _SEED_NUMBER_ = random_device_object(); + _SEED_NUMBER_ = GenerateSecureRandomNumberSeed(random_device_object); } ExampleGenerator2( unsigned int seed_number ) @@ -262,26 +329,26 @@ namespace CommonSecurity }; /* - An improved random number generation package. + An improved random number generation package. In addition to the standard rand()/srand() like interface, this package also has a special state info interface. The initial_state() routine is called with a seed, an array of bytes, and a count of how many bytes are being passed in; - this array is then initialized to contain information for random number generation with that much state information. + this array is then initialized to contain information for random number generation with that much state information. Good sizes for the amount of state information are 32, 64, 128, and 256 bytes. The state can be switched by calling the change_state() function with the same array as was initialized with initial_state(). - By default, the package runs with 128 bytes of state information and generates far better random numbers than a linear congruential generator. + By default, the package runs with 128 bytes of state information and generates far better random numbers than a linear congruential generator. If the amount of state information is less than 32 bytes, a simple linear congruential R.N.G. is used. - Internally, the state information is treated as an array of longs; + Internally, the state information is treated as an array of longs; the zeroth element of the array is the type of R.N.G. being used (small integer); the remainder of the array is the state information for the R.N.G. Thus, 32 bytes of state information will give 7 longs worth of state information, which will allow a degree seven polynomial. (Note: The zeroth word of state information also has some other information stored in it; see setstate for details). The random number generation technique is a linear feedback shift register approach, employing trinomials (since there are fewer terms to sum up that way). In this approach, the least significant bit of all the numbers in the state table will act as a linear feedback shift register, and will have period 2^deg - 1 (where deg is the degree of the polynomial being used, assuming that the polynomial is irreducible and primitive). - The higher order bits will have longer periods, since their values are also influenced by pseudo-random carries out of the lower bits. + The higher order bits will have longer periods, since their values are also influenced by pseudo-random carries out of the lower bits. The total period of the generator is approximately deg*(2**deg - 1); thus doubling the amount of state information has a vast influence on the period of the generator. Note: The deg*(2**deg - 1) is an approximation only good for large deg, when the period of the shift register is the dominant factor. With deg equal to seven, the period is actually much longer than the 7*(2**7 - 1) predicted by this formula. - + Reference code: https://sourceware.org/git/?p=glibc.git @@ -323,7 +390,7 @@ namespace CommonSecurity /* Array versions of the above information to make code run faster. Relies on fact that TYPE_i == i. */ LIMIT_TYPES = 5 }; - + /* For each of the currently supported random number generators, we have a break value on the amount of state information @@ -392,8 +459,8 @@ namespace CommonSecurity the degree of the current polynomial being used, and the separation between the two pointers. Note that for efficiency of random, we remember the first location of the state information, not the zeroth. Hence it is valid to access state[-1], which is used to store the type of the R.N.G. - Also, we remember the last location, - since this is more efficient than indexing every time to find the address of the last element to see if the front and rear pointers have wrapped. + Also, we remember the last location, + since this is more efficient than indexing every time to find the address of the last element to see if the front and rear pointers have wrapped. */ /* Front pointer. (Iterator pointer a) */ @@ -407,7 +474,7 @@ namespace CommonSecurity /* Type of random number generator. */ RandomMathPolynomialType math_polynomial_type; - + /* Degree of random number generator. */ int degree = 0; /* Degree of random number generator. */ @@ -444,7 +511,7 @@ namespace CommonSecurity for(std::size_t index = 0; index < this->degree; ++index) { - /* + /* This does: state[index] = (16807 * state[index - 1]) update% 2147483647; but avoids overflowing 31 bits. @@ -551,7 +618,7 @@ namespace CommonSecurity std::int32_t* rear_pointer = random_state_buffer.rear_pointer; std::int32_t* right_boundaries_state_element_pointer = random_state_buffer.right_boundaries_state_element_pointer; - + std::uint32_t value = *front_pointer += static_cast(*rear_pointer); /* Chunking least random bit. */ @@ -595,7 +662,7 @@ namespace CommonSecurity auto& [seed, bytes_state_span] = state_argument; std::int32_t* word_state_pointer = std::bit_cast( bytes_state_span.data() ) + 1; - + random_state_buffer.left_boundaries_state_element_pointer = word_state_pointer; random_state_buffer.right_boundaries_state_element_pointer = &( word_state_pointer[random_state_buffer.degree] ); @@ -625,12 +692,12 @@ namespace CommonSecurity } /* - Initialize the state information in the given array of bytes_state_size bytes for future random number generation. - Based on the number of bytes we are given, + Initialize the state information in the given array of bytes_state_size bytes for future random number generation. + Based on the number of bytes we are given, and the break values for the different R.N.G.'s, - we choose the best (largest) one we can and set things up for it. - seed_random is then called to initialize the state information. - Note that on return from seed_random, + we choose the best (largest) one we can and set things up for it. + seed_random is then called to initialize the state information. + Note that on return from seed_random, we set state[-1] to be the type multiplexed with the current value of the rear pointer; this is so successive calls to initstate won't lose this information and will be able to restart with update_state. Note: The first thing we do is save the current state, if any, just like @@ -673,9 +740,9 @@ namespace CommonSecurity Note: It is important that we also remember the locations of the pointers in the current state information, and restore the locations of the pointers from the old state information. This is done by multiplexing the pointer location into the zeroth word of the state information. - Note that due to the order in which things are done, + Note that due to the order in which things are done, it is OK to call update_state with the same state as the current state - Returns true-value on success, false-value on failure. + Returns true-value on success, false-value on failure. */ bool _update_state_(std::pair>& state_argument, RandomStateData& random_state_buffer) { @@ -695,7 +762,7 @@ namespace CommonSecurity update_math_polynomial_type = RandomMathPolynomialType::TYPE_0; else update_math_polynomial_type = bytes_state_size < _BREAK_BYTE_2_ ? RandomMathPolynomialType::TYPE_1 : RandomMathPolynomialType::TYPE_2; - + if(update_math_polynomial_type < RandomMathPolynomialType::TYPE_0 || update_math_polynomial_type > RandomMathPolynomialType::TYPE_4) return false; @@ -715,24 +782,24 @@ namespace CommonSecurity void seed( std::random_device& device ) { - is_use_busy.wait(true, std::memory_order::memory_order_seq_cst); + is_use_busy.wait(true, std::memory_order_seq_cst); - is_use_busy.store(true, std::memory_order::memory_order_seq_cst); + is_use_busy.store(true, std::memory_order_seq_cst); std::uint32_t seed_number = device(); this->seed( seed_number ); - is_use_busy.store(false, std::memory_order::memory_order_relaxed); + is_use_busy.store(false, std::memory_order_relaxed); is_use_busy.notify_all(); } void seed( int seed_number ) { - is_use_busy.wait(true, std::memory_order::memory_order_seq_cst); + is_use_busy.wait(true, std::memory_order_seq_cst); - is_use_busy.store(true, std::memory_order::memory_order_seq_cst); + is_use_busy.store(true, std::memory_order_seq_cst); if(!state_argument_double_queue.empty()) { @@ -747,21 +814,21 @@ namespace CommonSecurity unsafe_random_state.change_state_table(seed_number, true); } - is_use_busy.store(false, std::memory_order::memory_order_relaxed); + is_use_busy.store(false, std::memory_order_relaxed); is_use_busy.notify_all(); } int operator()() { - is_use_busy.wait(true, std::memory_order::memory_order_seq_cst); + is_use_busy.wait(true, std::memory_order_seq_cst); - is_use_busy.store(true, std::memory_order::memory_order_seq_cst); + is_use_busy.store(true, std::memory_order_seq_cst); std::int32_t result_number = 0; this->compute_number(unsafe_random_state, result_number); - is_use_busy.store(false, std::memory_order::memory_order_relaxed); + is_use_busy.store(false, std::memory_order_relaxed); is_use_busy.notify_all(); @@ -770,7 +837,7 @@ namespace CommonSecurity /* Initialize the random number generator to use state buffer (STATEBUFFFER), - of length (STATELENTH), and seed it with SEED. + of length (STATELENTH), and seed it with SEED. Optimal lengths are 8, 16, 32, 64, 128 and 256, the bigger the better; values less than 8 will cause an error and values greater than 256 will be rounded down. @@ -784,13 +851,13 @@ namespace CommonSecurity */ std::optional> initial_state(std::pair>& state_argument) { - is_use_busy.wait(true, std::memory_order::memory_order_seq_cst); + is_use_busy.wait(true, std::memory_order_seq_cst); - is_use_busy.store(true, std::memory_order::memory_order_seq_cst); + is_use_busy.store(true, std::memory_order_seq_cst); auto random_state_data = this->_initial_state_(state_argument, this->unsafe_random_state); - is_use_busy.store(false, std::memory_order::memory_order_relaxed); + is_use_busy.store(false, std::memory_order_relaxed); is_use_busy.notify_all(); @@ -808,10 +875,10 @@ namespace CommonSecurity /* Switch the random number generator to state buffer (STATEBUFFFER), - which should have been previously initialized by `initial_state'. + which should have been previously initialized by `initial_state'. Restore the state from the given state array. - Note: It is important that we also remember the locations of the pointers in the current state information, + Note: It is important that we also remember the locations of the pointers in the current state information, and restore the locations of the pointers from the old state information. This is done by multiplexing the pointer location into the zeroth word of the state information. Note that due to the order in which things are done, @@ -819,13 +886,13 @@ namespace CommonSecurity */ std::optional update_state(std::pair>& state_argument, RandomStateData& default_random_state_data) { - is_use_busy.wait(true, std::memory_order::memory_order_seq_cst); + is_use_busy.wait(true, std::memory_order_seq_cst); - is_use_busy.store(true, std::memory_order::memory_order_seq_cst); + is_use_busy.store(true, std::memory_order_seq_cst); bool is_done = this->_update_state_(state_argument, default_random_state_data); - is_use_busy.store(false, std::memory_order::memory_order_relaxed); + is_use_busy.store(false, std::memory_order_relaxed); is_use_busy.notify_all(); @@ -837,13 +904,13 @@ namespace CommonSecurity void change_state(RandomStateData& initialized_random_state_data) { - is_use_busy.wait(true, std::memory_order::memory_order_seq_cst); + is_use_busy.wait(true, std::memory_order_seq_cst); - is_use_busy.store(true, std::memory_order::memory_order_seq_cst); + is_use_busy.store(true, std::memory_order_seq_cst); unsafe_random_state = initialized_random_state_data; - is_use_busy.store(false, std::memory_order::memory_order_relaxed); + is_use_busy.store(false, std::memory_order_relaxed); is_use_busy.notify_all(); } @@ -858,17 +925,17 @@ namespace CommonSecurity return RandomStateData(static_cast(type_number)); } - int easy_compute_number( std::random_device& device ) + int easy_compute_number( std::random_device& random_device_object ) { - is_use_busy.wait(true, std::memory_order::memory_order_seq_cst); + is_use_busy.wait(true, std::memory_order_seq_cst); - is_use_busy.store(true, std::memory_order::memory_order_seq_cst); + is_use_busy.store(true, std::memory_order_seq_cst); - std::uint32_t seed_number = device(); + auto seed_number = GenerateSecureRandomNumberSeed(random_device_object); auto result_random_number = this->easy_compute_number( seed_number ); - is_use_busy.store(false, std::memory_order::memory_order_relaxed); + is_use_busy.store(false, std::memory_order_relaxed); is_use_busy.notify_all(); @@ -877,9 +944,9 @@ namespace CommonSecurity int easy_compute_number( unsigned int& seed_number ) { - is_use_busy.wait(true, std::memory_order::memory_order_seq_cst); + is_use_busy.wait(true, std::memory_order_seq_cst); - is_use_busy.store(true, std::memory_order::memory_order_seq_cst); + is_use_busy.store(true, std::memory_order_seq_cst); if(seed_number == 0) seed_number = 1; @@ -901,7 +968,7 @@ namespace CommonSecurity seed_number = update_value; - is_use_busy.store(false, std::memory_order::memory_order_relaxed); + is_use_busy.store(false, std::memory_order_relaxed); is_use_busy.notify_all(); @@ -988,9 +1055,11 @@ namespace CommonSecurity *this = xoshiro256( q ); } - void seed( std::random_device device ) noexcept + void seed( std::random_device random_device_object ) noexcept { - *this = xoshiro256( device() ); + auto seed_number = GenerateSecureRandomNumberSeed(random_device_object); + + *this = xoshiro256( seed_number ); } static constexpr result_type min() noexcept @@ -1005,7 +1074,7 @@ namespace CommonSecurity constexpr result_type operator()() noexcept { // xorshiro256+: - // const auto result = state[0] + state[3];\ + // const auto result = state[0] + state[3]; // xorshiro256++: // const auto result = std::rotl(state[0] + state[3], 23) + state[0]; @@ -1138,12 +1207,12 @@ namespace CommonSecurity http://rosettacode.org/wiki/The_ISAAC_Cipher This work is derived from the ISAAC random number generator, created by Bob Jenkins, - which he has generously put in the public domain. + which he has generously put in the public domain. All design credit goes to Bob Jenkins. - Details of the algorithm, and the original C source can be found at + Details of the algorithm, and the original C source can be found at http://burtleburtle.net/bob/rand/isaacafa.html. This work is a C++ translation and re-packaging of the original C code to make it meet the requirements for a random number engine, - as specified in paragraph 26.5.1.4 of the C++ language standard. + as specified in paragraph 26.5.1.4 of the C++ language standard. As such, it can be used in conjunction with other elements in the random number generation facility, such as distributions and engine adaptors. Created by David Curtis, 2016. Public Domain. @@ -1200,19 +1269,19 @@ namespace CommonSecurity { seed(seed_number); } - + template requires( not std::convertible_to ) explicit RNG_ISAAC_BASE( SeedSeq& number_sequence ) { seed(number_sequence); } - + RNG_ISAAC_BASE(const std::vector& seed_vector) { seed(seed_vector); } - + template RNG_ISAAC_BASE ( @@ -1227,7 +1296,7 @@ namespace CommonSecurity { seed(begin, end); } - + RNG_ISAAC_BASE(std::random_device& random_device_object) { seed(random_device_object); @@ -1256,7 +1325,7 @@ namespace CommonSecurity { return std::numeric_limits::max(); } - + inline void seed(result_type seed_number = default_seed) { for (std::size_t index = 0; index < state_size; ++index) @@ -1265,13 +1334,14 @@ namespace CommonSecurity } init(); } - + template requires( not std::convertible_to ) constexpr void seed( SeedSeq& number_sequence ) { + std::seed_seq my_seed_sequence(number_sequence.begin(), number_sequence.end()); std::array seed_array; - number_sequence.generate(seed_array.begin(), seed_array.end()); + my_seed_sequence.generate(seed_array.begin(), seed_array.end()); for (std::size_t index = 0; index < state_size; ++index) { issac_base_member_result[index] = seed_array[index]; @@ -1299,32 +1369,34 @@ namespace CommonSecurity } init(); } - + void seed(std::random_device& random_device_object) { - std::vector seed_vec; - seed_vec.reserve(state_size); + std::vector random_seed_vector; + random_seed_vector.reserve(state_size); for (std::size_t round = 0; round < state_size; ++round) { - result_type value; - value = random_device_object(); + result_type seed_number_value = GenerateSecureRandomNumberSeed(random_device_object); + std::size_t bytes_filled{sizeof(std::random_device::result_type)}; while(bytes_filled < sizeof(result_type)) { - value <<= (sizeof(std::random_device::result_type) * 8); - value |= random_device_object(); + result_type seed_number_value2 = GenerateSecureRandomNumberSeed(random_device_object); + + seed_number_value <<= (sizeof(std::random_device::result_type) * 8); + seed_number_value |= seed_number_value2; bytes_filled += sizeof(std::random_device::result_type); } - seed_vec.push_back(value); + random_seed_vector.push_back(seed_number_value); } - seed(seed_vec.begin(), seed_vec.end()); + seed(random_seed_vector.begin(), random_seed_vector.end()); } inline result_type operator()() { return (!issac_base_member_counter--) ? (do_isaac(), issac_base_member_counter = state_size - 1, issac_base_member_result[issac_base_member_counter]) : issac_base_member_result[issac_base_member_counter]; } - + inline void discard(unsigned long long z) { for (; z; --z) operator()(); @@ -1379,7 +1451,7 @@ namespace CommonSecurity os.flags(format_flags); return os; } - + template friend std::basic_istream& operator>>(std::basic_istream& is, RNG_ISAAC_BASE& isaac_base_object) @@ -1391,16 +1463,16 @@ namespace CommonSecurity result_type temporary_register_b = 0; result_type temporary_register_c = 0; std::size_t temporary_register_counter = 0; - + auto format_flags = is.flags(); is.flags(std::ios_base::dec | std::ios_base::skipws); - + is >> temporary_register_counter; if (is.fail()) { failed = true; } - + std::size_t process_counter = 0; while (process_counter != 5) @@ -1456,7 +1528,7 @@ namespace CommonSecurity ++process_counter; } - + if (!failed) { for (std::size_t i = 0; i < state_size; ++i) @@ -1490,17 +1562,17 @@ namespace CommonSecurity result_type f = golden(); result_type g = golden(); result_type h = golden(); - + issac_base_member_register_a = 0; issac_base_member_register_b = 0; issac_base_member_register_c = 0; - + /* scramble it */ for (std::size_t index = 0; index < 4; ++index) { mix(a,b,c,d,e,f,g,h); } - + /* initialize using the contents of issac_base_member_result[] as the seed */ for (std::size_t index = 0; index < state_size; index += 8) { @@ -1512,9 +1584,9 @@ namespace CommonSecurity f += issac_base_member_result[index+5]; g += issac_base_member_result[index+6]; h += issac_base_member_result[index+7]; - + mix(a,b,c,d,e,f,g,h); - + issac_base_member_memory[index] = a; issac_base_member_memory[index+1] = b; issac_base_member_memory[index+2] = c; @@ -1524,7 +1596,7 @@ namespace CommonSecurity issac_base_member_memory[index+6] = g; issac_base_member_memory[index+7] = h; } - + /* do a second pass to make all of the seed affect all of issac_base_member_memory */ for (std::size_t index = 0; index < state_size; index += 8) { @@ -1536,9 +1608,9 @@ namespace CommonSecurity f += issac_base_member_memory[index+5]; g += issac_base_member_memory[index+6]; h += issac_base_member_memory[index+7]; - + mix(a,b,c,d,e,f,g,h); - + issac_base_member_memory[index] = a; issac_base_member_memory[index+1] = b; issac_base_member_memory[index+2] = c; @@ -1555,22 +1627,22 @@ namespace CommonSecurity /* prepare to use the first set of results */ issac_base_member_counter = state_size; } - + inline void do_isaac() { static_cast(this)->derived_implementation_isaac(); } - + inline result_type golden() { return static_cast(this)->derived_implementation_golden_number(); } - + inline void mix(result_type& a, result_type& b, result_type& c, result_type& d, result_type& e, result_type& f, result_type& g, result_type& h) { static_cast(this)->derived_implementation_mix(a, b, c, d, e, f, g, h); } - + result_type issac_base_member_result[state_size]; result_type issac_base_member_memory[state_size]; result_type issac_base_member_register_a; @@ -1586,23 +1658,23 @@ namespace CommonSecurity public: using base = RNG_ISAAC_BASE; - + friend class RNG_ISAAC_BASE; - + using result_type = std::uint32_t; - - explicit isaac(result_type s = base::default_seed) + + explicit isaac(result_type random_seed_number = base::default_seed) : - base::RNG_ISAAC_BASE(s) + base::RNG_ISAAC_BASE(random_seed_number) {} - template + template requires( not std::convertible_to ) - explicit isaac(SeedSeq& q) + explicit isaac(SeedSeq& random_seed_number_sequence) : - base::RNG_ISAAC_BASE(q) + base::RNG_ISAAC_BASE(random_seed_number_sequence) {} - + template isaac ( @@ -1629,7 +1701,7 @@ namespace CommonSecurity {} private: - + static constexpr result_type derived_implementation_golden_number() { /* the golden ratio */ @@ -1708,7 +1780,7 @@ namespace CommonSecurity */ result_type index = 0, x = 0, y = 0, state_random_value = 0; - + result_type accumulate = this->issac_base_member_register_a; result_type bit_result = this->issac_base_member_register_b + (++(this->issac_base_member_register_c)); //b ← (c + 1) @@ -1718,7 +1790,7 @@ namespace CommonSecurity x = this->issac_base_member_memory[index]; /* //barrel shift - + function(a, index) { if index ≡ 0 mod 4 @@ -1730,7 +1802,7 @@ namespace CommonSecurity if index ≡ 3 mod 4 return a ^= a << 16 } - + mix_index ← function(a, index); */ switch (index & 3) @@ -1804,7 +1876,7 @@ namespace CommonSecurity So assuming that Alpha is an 8-bit state, the value of this->state_size is: "1 << 8 == 256" And after understanding the bit manipulation, we know that the calculation of the power of 2 is: "2 & (number - 1)". So the ISAAC paper gives the calculation of "state[index] + 128 mod 256, and the derivation should be: state[index + (this->state_size / 2) & (this-> state_size - 1)]" - + This is the same as the initialization part of the previous for loop new_memory_array_address = new_memory_array = update_memory_array + (this->state_size / 2); */ @@ -1826,7 +1898,7 @@ namespace CommonSecurity result_type* update_memory_array = nullptr; result_type* new_memory_array = nullptr; result_type* new_memory_array_address = nullptr; - + result_type* old_memory_array = this->issac_base_member_memory; result_type* current_result_array = this->issac_base_member_result; result_type a = this->issac_base_member_register_a; @@ -1857,25 +1929,25 @@ namespace CommonSecurity class isaac64 : public RNG_ISAAC_BASE, Alpha, std::uint64_t> { public: - + using result_type = std::uint64_t; using base = RNG_ISAAC_BASE; friend class RNG_ISAAC_BASE; - - explicit isaac64(result_type s = base::default_seed) + + explicit isaac64(result_type random_seed_number = base::default_seed) : - base::RNG_ISAAC_BASE(s) + base::RNG_ISAAC_BASE(random_seed_number) {} template requires( not std::convertible_to ) - explicit isaac64(SeedSeq& q) + explicit isaac64(SeedSeq& random_seed_number_sequence) : - base::RNG_ISAAC_BASE(q) + base::RNG_ISAAC_BASE(random_seed_number_sequence) {} - + template isaac64 ( @@ -1958,7 +2030,7 @@ namespace CommonSecurity ISAAC-64 generates a different sequence than ISAAC, but it uses the same principles. It uses 64-bit arithmetic. It generates a 64-bit result every 19 instructions. All cycles are at least 2(^)72 values, and the average cycle length is 2(^)16583. - The following files implement ISAAC-64. + The following files implement ISAAC-64. The constants were tuned for a 64-bit machine, and a complement was thrown in so that all-zero states become nonzero faster. */ @@ -1982,7 +2054,7 @@ namespace CommonSecurity */ result_type index = 0, x = 0, y = 0, state_random_value = 0; - + result_type accumulate = this->issac_base_member_register_a; result_type bit_result = this->issac_base_member_register_b + (++(this->issac_base_member_register_c)); //b ← (c + 1) @@ -1992,7 +2064,7 @@ namespace CommonSecurity x = this->issac_base_member_memory[index]; /* //barrel shift - + function(a, index) { if index ≡ 0 mod 4 @@ -2004,7 +2076,7 @@ namespace CommonSecurity if index ≡ 3 mod 4 return a ^= a << 33 } - + mix_index ← function(a, index); */ switch (index & 3) @@ -2079,7 +2151,7 @@ namespace CommonSecurity So assuming that Alpha is an 8-bit state, the value of this->state_size is: "1 << 8 == 256" And after understanding the bit manipulation, we know that the calculation of the power of 2 is: "2 & (number - 1)". So the ISAAC paper gives the calculation of "state[index] + 128 mod 256, and the derivation should be: state[index + (this->state_size / 2) & (this-> state_size - 1)]" - + This is the same as the initialization part of the previous for loop new_memory_array_address = new_memory_array = update_memory_array + (this->state_size / 2); */ @@ -2101,7 +2173,7 @@ namespace CommonSecurity result_type* update_memory_array = nullptr; result_type* new_memory_array = nullptr; result_type* new_memory_array_address = nullptr; - + result_type* old_memory_array = this->issac_base_member_memory; result_type* current_result_array = this->issac_base_member_result; result_type a = this->issac_base_member_register_a; @@ -2131,7 +2203,7 @@ namespace CommonSecurity /* A counter-based random number generation (CBRNG, also known as a counter-based pseudo-random number generator, or CBPRNG) is a kind of pseudorandom number generator that uses only an integer counter as its internal state. - + Improved version from Middle Square Method, invented by John Von Neumann. Reference papers: https://arxiv.org/abs/1704.00358 and https://arxiv.org/abs/2004.06278 @@ -2151,10 +2223,8 @@ namespace CommonSecurity public: - void reseed() + void reseed(std::size_t a, std::size_t b) { - std::vector random_byte_datas(16, 0x00); - /* Xorshift random number generators, also called shift-register generators, are a class of pseudorandom number generators that were discovered by George Marsaglia.[1] They are a subset of linear-feedback shift registers (LFSRs) which allow a particularly efficient implementation in software without using excessively sparse polynomials.[2] @@ -2171,13 +2241,13 @@ namespace CommonSecurity https://en.wikipedia.org/wiki/Xorshift */ - std::size_t undefine_behavior_number; + std::size_t number = std::rotr(b, 32); std::size_t xorshift_random_seed = _resultRandomNumber; if(_resultRandomNumber == 0) - undefine_behavior_number = 0; + number = 0; - _oddNumber = static_cast(_simpleImplementationGenerator() << 32); + _oddNumber = static_cast( std::rotl(a, 32) ); while ((_oddNumber & 1) == 0) { auto difference = _oddNumber - std::numeric_limits::min(); @@ -2198,11 +2268,11 @@ namespace CommonSecurity xorshift_random_seed ^= (xorshift_random_seed >> 17); xorshift_random_seed ^= (xorshift_random_seed << 5); - undefine_behavior_number = xorshift_random_seed; + number = xorshift_random_seed; - undefine_behavior_number ^= (undefine_behavior_number << 13); - undefine_behavior_number ^= (undefine_behavior_number >> 17); - undefine_behavior_number ^= (undefine_behavior_number << 5); + number ^= (number << 13); + number ^= (number >> 17); + number ^= (number << 5); } else { @@ -2212,22 +2282,22 @@ namespace CommonSecurity xorshift_random_seed ^= (xorshift_random_seed >> 7); xorshift_random_seed ^= (xorshift_random_seed << 17); - undefine_behavior_number = xorshift_random_seed; + number = xorshift_random_seed; - undefine_behavior_number ^= (undefine_behavior_number << 13); - undefine_behavior_number ^= (undefine_behavior_number >> 7); - undefine_behavior_number ^= (undefine_behavior_number << 17); + number ^= (number << 13); + number ^= (number >> 7); + number ^= (number << 17); } //Toggles an odd number of bits in an odd position, so an even number becomes an odd number //切换一个奇数位置的比特位,所以偶数变成了奇数 - _oddNumber ^= static_cast(1 << static_cast(undefine_behavior_number & (CURRENT_SYSTEM_BITS - 1)) ); + _oddNumber ^= static_cast(1 << static_cast(number & (CURRENT_SYSTEM_BITS - 1)) ); } } //Use xorshift128 - std::array xorshift128_state { undefine_behavior_number, undefine_behavior_number -= _oddNumber, xorshift_random_seed , xorshift_random_seed -= _oddNumber }; + std::array xorshift128_state { number, number -= _oddNumber, xorshift_random_seed , xorshift_random_seed -= _oddNumber }; std::uint32_t t = xorshift128_state[3]; std::uint32_t s = xorshift128_state[0]; @@ -2240,21 +2310,32 @@ namespace CommonSecurity xorshift128_state[0] = t ^ s ^ (s >> 19); - _simpleImplementationGenerator.seed( xorshift128_state[0] ); + _sequenceWeylSequence ^= xorshift128_state[0]; + _resultRandomNumber += xorshift128_state[1]; + _sequenceWeylSequence += (xorshift128_state[3] - xorshift128_state[2]); + _resultRandomNumber ^= (xorshift128_state[2] - xorshift128_state[3]); + } - for( auto& byte : random_byte_datas ) - { - byte = static_cast( _simpleImplementationGenerator() ); - } + //Using hardware devices to generate true random numbers + //As the seed value for this CBRNG generator + //使用硬件设备生成真随机数 + //作为这个CBRNG生成器的种子数值 + void reseed() + { + std::vector random_seed_vector = GenerateSecureRandomNumberSeedSequence(32); + std::seed_seq random_seed_sequence_obejct(random_seed_vector.begin(), random_seed_vector.end()); + std::mt19937_64 pseudo_random_generator_object(random_seed_sequence_obejct); + + _simpleImplementationGenerator.seed( static_cast(random_seed_vector.back()) ^ static_cast(random_seed_vector.back() >> 32)); - std::span random_byte_datas_span{ random_byte_datas }; - CommonToolkit::MessagePacking( random_byte_datas_span, &_sequenceWeylSequence ); - CommonToolkit::MessagePacking( random_byte_datas_span.subspan(8, 8), &_resultRandomNumber ); + _sequenceWeylSequence = pseudo_random_generator_object(); + _resultRandomNumber = pseudo_random_generator_object() ^ _simpleImplementationGenerator(); } void seed(std::random_device& random_device_object) { - std::uint32_t seed_value = random_device_object(); + auto seed_value = GenerateSecureRandomNumberSeed(random_device_object); + this->seed(seed_value); } @@ -2306,19 +2387,19 @@ namespace CommonSecurity /* The squares RNG was derived using ideas from “Middle-Square Weyl Sequence RNG”[7]. The msws generator uses a half-square implementation. - That is, only half of the actual square is computed. + That is, only half of the actual square is computed. The upper bits of this half square are the “middle” that is returned. These middle bits are easily obtained by either rotating or shifting the result. - The middle square provides the randomization. + The middle square provides the randomization. Uniformity and period length are obtained by adding in a Weyl sequence. - For the squares RNG, we replaced the Weyl sequence (w += s) with a counter multiplied by a key. + For the squares RNG, we replaced the Weyl sequence (w += s) with a counter multiplied by a key. This turns out to be in effect the same thing. - Mathematically, (w += s) is equivalent to w = i * s mod 2(^)64 for i = 0 to 2(^)64 − 1. + Mathematically, (w += s) is equivalent to w = i * s mod 2(^)64 for i = 0 to 2(^)64 − 1. That is, i * s will produce the same sequence as (w += s). - In place of i and s, we use a counter and a key. - So, if we add counter * key to a square, we should see the same effect as adding a Weyl sequence. + In place of i and s, we use a counter and a key. + So, if we add counter * key to a square, we should see the same effect as adding a Weyl sequence. The output will be uniform and 264 random numbers will be available per key(^)1. - In the squares RNG, several rounds of squaring and adding are computed and the result is returned. + In the squares RNG, several rounds of squaring and adding are computed and the result is returned. Four rounds have been shown to be sufficient to pass the statistical tests. */ namespace ExampleCode @@ -2329,7 +2410,7 @@ namespace CommonSecurity { return number * number; } - + static inline uint32_t squares32bit(uint64_t counter, uint64_t key) { std::uint64_t x, y, z; @@ -2363,7 +2444,7 @@ namespace CommonSecurity unsigned int compute_number(unsigned long long counter_word, unsigned long long key_word) { unsigned long long a = 0, b = 0, c = 0; - + b = a = counter_word * key_word; c = b + key_word; @@ -2821,7 +2902,7 @@ namespace CommonSecurity if (!is_nonlinear_mode) { static ShufflingRangeDataDetails::UniformIntegerDistribution number_distribution( minimum, maximum ); - + if constexpr(std::signed_integral) { auto random_unsigned_number = number_distribution( random_generator ); @@ -2831,7 +2912,7 @@ namespace CommonSecurity { auto can_be_subtracted_count = minimum; ~can_be_subtracted_count; - + RegenerateNumber: while(random_unsigned_number > can_be_subtracted_count - 1 || random_unsigned_number == 0) @@ -2960,7 +3041,7 @@ namespace CommonSecurity }; inline UnifromShuffleRangeImplement ShuffleRangeData; - + #if 0 template < typename IntegerType > @@ -3492,7 +3573,7 @@ namespace Cryptograph::Bitset //A with B split to C and D: //C is: 0001'101'0011'0011 //D is: 0010'011'0010'0100 - + /* The process of implementation: High Digit Binary data calculation: @@ -3566,7 +3647,7 @@ namespace Cryptograph::Bitset else { /* - + 10 <-> 1010 11 <-> 1011 @@ -3593,7 +3674,7 @@ namespace Cryptograph::Bitset Target Binary Pair: 1010011100 01110011100 - + */ if constexpr(SplitPosition_OnePartSize < SplitPosition_TwoPartSize) @@ -3622,7 +3703,7 @@ namespace Cryptograph::Bitset //Discard the original high bits of data //丢弃原高位比特的数据 LowDigitPartDataWithInteger = LowDigitPartDataWithInteger >> SplitPosition_OnePartSize; - + //By left (circular shift) rotation, the high bits of the binary data are moved to the low bits (and reversed) //Used to recover the original low bits of data //通过左(循环移位)旋转,将二进制的高位比特的数据,移动至低位(并且反向) @@ -3668,7 +3749,7 @@ namespace Cryptograph::Bitset //Discard the original high bits of data //丢弃原高位比特的数据 LowDigitPartDataWithInteger = LowDigitPartDataWithInteger >> SplitPosition_OnePartSize; - + //By left (circular shift) rotation, the high bits of the binary data are moved to the low bits (and reversed) //Used to recover the original low bits of data //通过左(循环移位)旋转,将二进制的高位比特的数据,移动至低位(并且反向) @@ -3801,4 +3882,4 @@ namespace Cryptograph::Bitset std::vector ByteArray { reinterpret_cast( &TemporaryInteger ), reinterpret_cast( &TemporaryInteger + 1 ) }; return ByteArray; } -} \ No newline at end of file +} diff --git a/include/CommonSecurity/DataHashingWrapper.hpp b/include/CommonSecurity/DataHashingWrapper.hpp index 1eff097..64134af 100644 --- a/include/CommonSecurity/DataHashingWrapper.hpp +++ b/include/CommonSecurity/DataHashingWrapper.hpp @@ -377,12 +377,10 @@ namespace CommonSecurity::DataHashingWrapper ByteData = TRNG() % std::numeric_limits::max(); } - //This is current timestamp - //当前时间戳 - std::size_t CurrentTimestamp = std::chrono::system_clock::now().time_since_epoch().count(); - std::size_t CurrentTimestamp2 = std::chrono::system_clock::now().time_since_epoch().count(); + std::size_t CurrentRandomSeed = GenerateSecureRandomNumberSeed(TRNG); + std::size_t CurrentRandomSeed2 = GenerateSecureRandomNumberSeed(TRNG); - auto ExportedObfuscatorResultTable = this->ApplyCustomDataObfuscation(static_cast(TRNG() ^ CurrentTimestamp), static_cast(TRNG() ^ CurrentTimestamp2), ExtendedChacha20_Key, true); + auto ExportedObfuscatorResultTable = this->ApplyCustomDataObfuscation(CurrentRandomSeed, CurrentRandomSeed2, ExtendedChacha20_Key, true); std::destroy_at(&ExportedObfuscatorResultTable); } @@ -478,7 +476,17 @@ namespace CommonSecurity::DataHashingWrapper PasswordStreamBytes.clear(); PasswordStreamBytes.shrink_to_fit(); - PRNE.InitialBySeed( PasswordStreamWords.begin(), PasswordStreamWords.end(), 0, false ); + //Does it use a true random number generator? + //是否使用真随机数生成器? + if constexpr(false) + { + std::vector RandomNumberSeedSequence = GenerateSecureRandomNumberSeedSequence(PasswordStreamWords.size()); + PRNE.InitialBySeed( RandomNumberSeedSequence.begin(), RandomNumberSeedSequence.end(), 0, false ); + } + else + { + PRNE.InitialBySeed( PasswordStreamWords.begin(), PasswordStreamWords.end(), 0, false ); + } CommonSecurity::ShuffleRangeData( PasswordStreamWords.begin(), PasswordStreamWords.end(), PRNE.random_generator ); diff --git a/include/CommonSecurity/KeyDerivationFunction/AlgorithmArgon2.hpp b/include/CommonSecurity/KeyDerivationFunction/AlgorithmArgon2.hpp index aa6247d..f51fd79 100644 --- a/include/CommonSecurity/KeyDerivationFunction/AlgorithmArgon2.hpp +++ b/include/CommonSecurity/KeyDerivationFunction/AlgorithmArgon2.hpp @@ -281,14 +281,14 @@ namespace CommonSecurity::KDF::Argon2 /* 2 blocks per slice(column) */ constexpr std::size_t MINIMUM_MEMORY_BLOCK_BYTE_COUNT = 2 * SYNC_POINTS; - constexpr std::size_t CHOSE1_MINIMUM_MEMORY_BLOCK_BITS = static_cast(32); - constexpr std::size_t CHOSE2_MINIMUM_MEMORY_BLOCK_BITS = ( sizeof(void *) * std::numeric_limits::digits - 10 - 1 ); - constexpr std::size_t MINIMUM_MEMORY_BLOCK_BITS = ( CHOSE1_MINIMUM_MEMORY_BLOCK_BITS < CHOSE2_MINIMUM_MEMORY_BLOCK_BITS ) ? CHOSE1_MINIMUM_MEMORY_BLOCK_BITS : CHOSE1_MINIMUM_MEMORY_BLOCK_BITS; + constexpr std::uint32_t CHOSE1_MINIMUM_MEMORY_BLOCK_BITS = static_cast(32); + constexpr std::uint32_t CHOSE2_MINIMUM_MEMORY_BLOCK_BITS = ( sizeof(void *) * std::numeric_limits::digits - 10 - 1 ); + constexpr std::size_t MINIMUM_MEMORY_BLOCK_BITS = ( CHOSE1_MINIMUM_MEMORY_BLOCK_BITS < CHOSE2_MINIMUM_MEMORY_BLOCK_BITS ) ? CHOSE1_MINIMUM_MEMORY_BLOCK_BITS : CHOSE2_MINIMUM_MEMORY_BLOCK_BITS; /* Max memory size is half the addressing space, topping at 2^32 blocks (4 TB)*/ //Integer (8 * parallelism_block_row_number ~ power(2,32)-1) Amount of memory (in kilobytes) to use - constexpr std::size_t CHOSE1_MEMORY_BLOCK_BYTE_COUNT = std::numeric_limits::max(); - constexpr std::size_t CHOSE2_MEMORY_BLOCK_BYTE_COUNT = static_cast(1) << MINIMUM_MEMORY_BLOCK_BITS; + constexpr std::uint64_t CHOSE1_MEMORY_BLOCK_BYTE_COUNT = std::numeric_limits::max(); + constexpr std::uint64_t CHOSE2_MEMORY_BLOCK_BYTE_COUNT = static_cast(1) << MINIMUM_MEMORY_BLOCK_BITS; constexpr std::size_t MAXIMUM_MEMORY_BLOCK_BYTE_COUNT = ( CHOSE1_MEMORY_BLOCK_BYTE_COUNT < CHOSE2_MEMORY_BLOCK_BYTE_COUNT ) ? CHOSE1_MEMORY_BLOCK_BYTE_COUNT : CHOSE2_MEMORY_BLOCK_BYTE_COUNT; /* Minimum and maximum number of passes */ @@ -672,7 +672,9 @@ namespace CommonSecurity::KDF::Argon2 auto lambda_Blake64Bit = [](const std::vector& input_bytes, const std::vector& output_size_bytes, const std::size_t& output_size) -> std::vector { - auto Hasher_Blake2OrdinaryMode = CommonSecurity::Blake2::HashProvider( std::numeric_limits::digits * output_size ); + constexpr std::size_t HASH_BIT_SIZE = CURRENT_SYSTEM_BITS == 64 ? std::numeric_limits::digits * Constants::PRE_HASHING_DIGEST_SIZE : (std::numeric_limits::digits * Constants::PRE_HASHING_DIGEST_SIZE) / 2; + + auto Hasher_Blake2OrdinaryMode = CommonSecurity::Blake2::HashProvider( HASH_BIT_SIZE ); Hasher_Blake2OrdinaryMode.StepInitialize(); @@ -804,8 +806,10 @@ namespace CommonSecurity::KDF::Argon2 auto algorithm_hash_mode_type = static_cast(argon2_parameters_context._hash_mode_type_); auto algorithm_mode_type_number_bytes = CommonToolkit::MessageUnpacking(&(algorithm_hash_mode_type), 1); - - CommonSecurity::Blake2::HashProvider Hasher_Blake2OrdinaryMode( std::numeric_limits::digits * Constants::PRE_HASHING_DIGEST_SIZE); + constexpr std::size_t HASH_BIT_SIZE = CURRENT_SYSTEM_BITS == 64 ? std::numeric_limits::digits * Constants::PRE_HASHING_DIGEST_SIZE : (std::numeric_limits::digits * Constants::PRE_HASHING_DIGEST_SIZE) / 2; + + CommonSecurity::Blake2::HashProvider Hasher_Blake2OrdinaryMode( HASH_BIT_SIZE ); + Hasher_Blake2OrdinaryMode.StepInitialize(); Hasher_Blake2OrdinaryMode.StepUpdate(parallelism_block_lanes_and_rows_number_bytes); diff --git a/include/CommonSecurity/RefactoringCodeImplement.hpp b/include/CommonSecurity/RefactoringCodeImplement.hpp index badd37b..3c3131e 100644 --- a/include/CommonSecurity/RefactoringCodeImplement.hpp +++ b/include/CommonSecurity/RefactoringCodeImplement.hpp @@ -8,7 +8,7 @@ * 发布 TDOM-EncryptOrDecryptFile-Reborn 是希望它能有用,但是并无保障;甚至连可销售和符合某个特定的目的都不保证。请参看 GNU 通用公共许可证,了解详情。 * 你应该随程序获得一份 GNU 通用公共许可证的复本。如果没有,请看 。 */ - + /* * Copyright (C) 2021-2022 Twilight-Dream * @@ -311,12 +311,12 @@ namespace CommonSecurity::AES::ProcedureFunctions Finite fields are fundamental in a number of areas of mathematics and computer science, including number theory, algebraic geometry, Galois theory, finite geometry, cryptography and coding theory. Paper 3.2 Bytes (Part) - - All byte values in the AES algorithm will be presented as the concatenation of its individual bit + + All byte values in the AES algorithm will be presented as the concatenation of its individual bit values (0 or 1) between braces in the order - Byte {bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0}. - These bytes are - interpreted as finite field elements using a polynomial representation: + Byte {bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0}. + These bytes are + interpreted as finite field elements using a polynomial representation: Mathematical equations 3.1 bit7*x^7 + bit6*x^6 + bit5*x^5 + bit4*x^4 + bit3*x^3 + bit2*x^2 + bit1*x + bit0 @@ -329,7 +329,7 @@ namespace CommonSecurity::AES::ProcedureFunctions 在AES算法中,所有的字节值都将以其单独的比特值(0或1)的串联形式出现在大括号中。 值(0或1)在大括号之间的连接,顺序为 字节{bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0}。 - 这些字节被 + 这些字节被 被解释为使用多项式表示的有限场元素。 数学方程式 3.1 @@ -338,12 +338,12 @@ namespace CommonSecurity::AES::ProcedureFunctions 例如,{01100011}确定了具体的有限场元素x x^6 + x^5 + x +1 - Paper 4. Mathematical Preliminaries - All bytes in the AES algorithm are interpreted as finite field elements using the notation introduced in Sec. 3.2. - Finite field elements can be added and multiplied, but these operations are different from those used for numbers. - The following subsections introduce the basic mathematical concepts needed for Sec. 5. + Paper 4. Mathematical Preliminaries + All bytes in the AES algorithm are interpreted as finite field elements using the notation introduced in Sec. 3.2. + Finite field elements can be added and multiplied, but these operations are different from those used for numbers. + The following subsections introduce the basic mathematical concepts needed for Sec. 5. - 论文 4. 数学预演 + 论文 4. 数学预演 在AES算法中,所有的字节都被解释为有限场元素,使用的符号是 3.2节中介绍的符号。 有限场元素可以被添加和相乘,但这些操作 与用于数字的操作不同。 下面几个小节介绍了 第5章所需的基本数学概念。 @@ -351,7 +351,7 @@ namespace CommonSecurity::AES::ProcedureFunctions Parer 4.1 Addition The addition of two elements in a finite field is achieved by "adding" the coefficients for the corresponding powers in the polynomials for the two elements. - The addition is performed with the XOR operation (denoted by (Exclusive-OR) ) - i.e., modulo 2 - so that 1 Exclusive-OR 1 = 0 , 1 Exclusive-OR 0 = 1, and 0 Exclusive-OR 0 = 0 . + The addition is performed with the XOR operation (denoted by (Exclusive-OR) ) - i.e., modulo 2 - so that 1 Exclusive-OR 1 = 0 , 1 Exclusive-OR 0 = 1, and 0 Exclusive-OR 0 = 0 . Consequently, subtraction of polynomials is identical to addition of polynomials. Alternatively, addition of finite field elements can be described as the modulo 2 addition of corresponding bits in the byte. @@ -361,11 +361,11 @@ namespace CommonSecurity::AES::ProcedureFunctions For example, the following expressions are equivalent to one another: (x^6 + x^4 + x^2 + x + 1) + (x^7 + x + 1) = x^7 + x^6 + x^4 + x^2 (polynomial notation) {01010111} (+) {10000011} = {11010100} (binary notation); - {57} (+) {83} = {d4} (hexadecimal notation). + {57} (+) {83} = {d4} (hexadecimal notation). 论文 4.1 加法 有限域中两个元素的相加是通过 "添加 "这两个元素的多项式中的相应幂的系数来实现的。 - 加法是通过XOR操作(用(Exclusive-OR)表示)进行的。- 即模数2--因此,1 Exclusive-OR 1 = 0 ,1 Exclusive-OR 0 = 1,0 Exclusive-OR 0 = 0。 + 加法是通过XOR操作(用(Exclusive-OR)表示)进行的。- 即模数2--因此,1 Exclusive-OR 1 = 0 ,1 Exclusive-OR 0 = 1,0 Exclusive-OR 0 = 0。 因此,多项式的减法与多项式的加法是相同的。 另外,有限场元素的加法可以描述为字节中相应位的模2加法。 @@ -377,10 +377,10 @@ namespace CommonSecurity::AES::ProcedureFunctions {01010111} (+) {10000011} = {11010100}(二进制记法) {57}(+){83}={d4}(十六进制记法) - Paper 4.2 Multiplication - In the polynomial representation, multiplication in GF(2^8) (denoted by •) corresponds with the multiplication of polynomials modulo an irreducible polynomial of degree 8. - A polynomial is irreducible if its only divisors are one and itself. - + Paper 4.2 Multiplication + In the polynomial representation, multiplication in GF(2^8) (denoted by •) corresponds with the multiplication of polynomials modulo an irreducible polynomial of degree 8. + A polynomial is irreducible if its only divisors are one and itself. + For the AES algorithm, this irreducible polynomial is Mathematical equations 4.1 @@ -393,33 +393,33 @@ namespace CommonSecurity::AES::ProcedureFunctions (x^6 + x^4 + x^2 + x + 1)*(x^7 + x + 1) = x^13 + x^11 + x^9 + x^8 + x^7 + x^7 + x^5 + x^3 + x^2 + x + x^6 + x^4 + x^2 + x + 1 = x^13 + x^11 + x^9 + x^8 + x^5 + x^4 + x^3 + 1 - + and x^13 + x^11 + x^9 + x^8 + x^5 + x^4 + x^3 + 1 modulo (x^8 + x^4 + x^3 + x + 1) = x^7 + x^6 + 1 - The modular reduction by m(x) ensures that the result will be a binary polynomial of degree less than 8, and thus can be represented by a byte. - Unlike addition, there is no simple operation at the byte level that corresponds to this multiplication. - The multiplication defined above is associative, and the element {01} is the multiplicative identity. - For any non-zero binary polynomial b(x) of degree less than 8, the multiplicative inverse of b(x), denoted b^-1(x), can be found as follows: the extended Euclidean algorithm [7] - is used to compute polynomials a(x) and c(x) such that - + The modular reduction by m(x) ensures that the result will be a binary polynomial of degree less than 8, and thus can be represented by a byte. + Unlike addition, there is no simple operation at the byte level that corresponds to this multiplication. + The multiplication defined above is associative, and the element {01} is the multiplicative identity. + For any non-zero binary polynomial b(x) of degree less than 8, the multiplicative inverse of b(x), denoted b^-1(x), can be found as follows: the extended Euclidean algorithm [7] + is used to compute polynomials a(x) and c(x) such that + Mathematical equations 4.2 b(x)*a(x) + m(x)*c(x) = 1 - + Hence, a(x) • b(x) mod(m(x)) = 1 which means Mathematical equations 4.3 b^-1 (x) = a(x) mod m(x) - Moreover, for any a(x), b(x) and c(x) in the field, it holds that - a(x) • (b(x) + c(x)) = a(x) • b(x) + a(x) • c(x). - It follows that the set of 256 possible byte values, with (Exclusive-OR operation) used as addition and the multiplication defined as above, has the structure of the finite field GF(2^8). + Moreover, for any a(x), b(x) and c(x) in the field, it holds that + a(x) • (b(x) + c(x)) = a(x) • b(x) + a(x) • c(x). + It follows that the set of 256 possible byte values, with (Exclusive-OR operation) used as addition and the multiplication defined as above, has the structure of the finite field GF(2^8). 论文 4.2 乘法 - 在多项式表示中,GF(2^8)中的乘法(用•表示)对应于多项式与8度的不可还原多项式的乘法。 - 如果一个多项式的除数只有一个和它本身,那么它就是不可还原的。 - + 在多项式表示中,GF(2^8)中的乘法(用•表示)对应于多项式与8度的不可还原多项式的乘法。 + 如果一个多项式的除数只有一个和它本身,那么它就是不可还原的。 + 对于AES算法,这个不可还原的多项式是 数学方程式 4.1 @@ -432,7 +432,7 @@ namespace CommonSecurity::AES::ProcedureFunctions (x^6 + x^4 + x^2 + x + 1)*(x^7 + x + 1) = x^13 + x^11 + x^9 + x^8 + x^7 + x^7 + x^5 + x^3 + x^2 + x + x^6 + x^4 + x^2 + x + 1 = x^13 + x^11 + x^9 + x^8 + x^5 + x^4 + x^3 + 1 - + and x^13 + x^11 + x^9 + x^8 + x^5 + x^4 + x^3 + 1 modulo (x^8 + x^4 + x^3 + x + 1) = x^7 + x^6 + 1 @@ -440,36 +440,36 @@ namespace CommonSecurity::AES::ProcedureFunctions 与加法不同的是,在字节级没有对应于这种乘法的简单操作。 上面定义的乘法是关联性的,元素{01}是乘法的身份。 对于任何小于8度的非零二元多项式b(x),b(x)的乘法逆数,表示为b^-1(x),可以按如下方法找到:扩展的欧几里得算法[7] 。 - 用来计算多项式a(x)和c(x),以便于 + 用来计算多项式a(x)和c(x),以便于 数学方程式 4.2 b(x)*a(x)+m(x)*c(x)=1 因此,a(x)• b(x)mod(m(x))= 1 这意味着 数学方程式 4.3 b^-1 (x) = a(x) mod m(x) - 此外,对于场中的任何a(x), b(x)和c(x),可以看出 + 此外,对于场中的任何a(x), b(x)和c(x),可以看出 a(x) - (b(x) + c(x)) = a(x) - b(x) + a(x) - c(x)。 由此可见,256个可能的字节值的集合,用(Exclusive-OR操作)作为加法,乘法定义如上,具有有限域GF(2^8)的结构。 - Paper 4.2.1 Multiplication by x + Paper 4.2.1 Multiplication by x - Multiplying the binary polynomial defined in equation (3.1) with the polynomial x results in + Multiplying the binary polynomial defined in equation (3.1) with the polynomial x results in Mathematical equations 4.4 bit7*x^8 + bit6*x^7 + bit5*x^6 + bit4*x^5 + bit3*x^4 + bit2*x^3 + bit1*x^2 + bit0*x The result x • b(x) is obtained by reducing the above result modulo m(x), as defined in math equation (4.1) - If bit7 = 0, the result is already in reduced form. - Else bit7 = 1, the reduction is accomplished by subtracting (i.e., (Exclusive-OR operation)ing) the polynomial m(x). - It follows that multiplication by x (i.e., {00000010} or {02}) can be implemented at the byte level as a left shift and a subsequent conditional bitwise (+) with {1b}. - - This operation on bytes is denoted by xtime(). - Multiplication by higher powers of x can be implemented by repeated application of xtime(). + If bit7 = 0, the result is already in reduced form. + Else bit7 = 1, the reduction is accomplished by subtracting (i.e., (Exclusive-OR operation)ing) the polynomial m(x). + It follows that multiplication by x (i.e., {00000010} or {02}) can be implemented at the byte level as a left shift and a subsequent conditional bitwise (+) with {1b}. + + This operation on bytes is denoted by xtime(). + Multiplication by higher powers of x can be implemented by repeated application of xtime(). By adding intermediate results, multiplication by any constant can be implemented. 论文 4.2.1 乘以x - 将数学方程式(3.1)中定义的二元多项式与多项式x相乘的结果是 + 将数学方程式(3.1)中定义的二元多项式与多项式x相乘的结果是 数学方程式4.4 bit7*x^8 + bit6*x^7 + bit5*x^6 + bit4*x^5 + bit3*x^4 + bit2*x^3 + bit1*x^2 + bit0*x @@ -478,7 +478,7 @@ namespace CommonSecurity::AES::ProcedureFunctions 如果binray bit7 = 0,结果已经是还原形式。 否则binray bit7 = 1, 减少是通过减去(即(Exclusive-OR操作))多项式m(x)来完成的。 由此可见,x的乘法(即{00000010}或{02})可以在字节级实现为左移和随后与{1b}的条件性位操作(+)。 - + 这种对字节的操作用xtime()来表示。 x的高次幂乘法可以通过重复应用xtime()来实现。 通过添加中间结果,可以实现与任何常数的乘法。 @@ -487,7 +487,7 @@ namespace CommonSecurity::AES::ProcedureFunctions { unsigned char bitMask = 0x80, moduloInnumerableMask = 0x1b; unsigned char highBit = Xbyte & bitMask; - + // Rotate ByteA left (multiply by (?) in GF(2^8)) Xbyte <<= 1; //Xbyte = Xbyte << 1; @@ -505,9 +505,9 @@ namespace CommonSecurity::AES::ProcedureFunctions } /*********************************************************************************************** - * This function implements GF(2^8) mulitplication using a variation of peasent multiplication. + * This function implements GF(2^8) mulitplication using a variation of peasent multiplication. * This algo takes advantage of multiplication's distributive property. - * + * * e.g. 4 * 9 = 4 * (1* 2^0 + 0 * 2^1 + 0 * 2^2 + 1 * 2^3) * by the modulo polynomial relation x^8 + x^4 + x^3 + x + 1 = 0 * (the other way being to do carryless multiplication followed by a modular reduction) @@ -531,10 +531,10 @@ namespace CommonSecurity::AES::ProcedureFunctions // ByteA >= 128 = 0b0100'0000 /* GF modulo: if a has a nonzero term x^7, then must be reduced when it becomes x^8 */ unsigned char Bit = (ByteB & BitMask); - + if (Bit != static_cast(0x00)) { - unsigned XByte = ByteA; + unsigned XByte = ByteA; for (int counter2 = 0; counter2 < counter; ++counter2) { @@ -561,8 +561,8 @@ namespace CommonSecurity::AES::ProcedureFunctions { //Byte data - unsigned char constantByteForThisRound = unsigned char(1); - + unsigned char constantByteForThisRound { 1 }; + for(signed int indexCount = 0; indexCount < roundCount - 1; ++indexCount) { constantByteForThisRound = XTime(constantByteForThisRound); @@ -589,7 +589,7 @@ namespace CommonSecurity::AES::ProcedureFunctions ( const std::array &lhs, const std::array &rhs - ) + ) { std::array result; std::ranges::transform @@ -599,7 +599,7 @@ namespace CommonSecurity::AES::ProcedureFunctions lhs.begin(), result.begin(), [](const unsigned char &rhs_byte, const unsigned char &lhs_byte) -> unsigned char - { + { return rhs_byte ^ lhs_byte; } ); @@ -607,18 +607,18 @@ namespace CommonSecurity::AES::ProcedureFunctions } //在密钥扩展例程中使用的函数,它接收一个四字节的输入字,并对四个字节中的每个字节应用一个S-box,以产生一个输出字。 - //Function used in the Key Expansion routine that takes a four-byte input word and applies an S-box to each of the four bytes to produce an output word. + //Function used in the Key Expansion routine that takes a four-byte input word and applies an S-box to each of the four bytes to produce an output word. inline void KeyWordAES_Subtitute(std::array& Word) { using namespace AES::DefineConstants; std::ranges::transform ( - Word.begin(), - Word.end(), Word.begin(), - [](const unsigned char &byte) -> unsigned char - { + Word.end(), + Word.begin(), + [](const unsigned char &byte) -> unsigned char + { return Forward_S_Box[byte / 16][byte % 16]; } ); @@ -640,9 +640,9 @@ namespace CommonSecurity::AES::ProcedureFunctions std::ranges::rotate(s, s.begin() + k); std::cout << "Rotate left (" << k << "): " << s << '\n'; } - + std::cout << '\n'; - + for (int k{}; k != 5; ++k) { std::iota(s.begin(), s.end(), 'A'); std::ranges::rotate(s, s.end() - k); @@ -669,8 +669,8 @@ namespace CommonSecurity::AES::ProcedureFunctions //} /* - The MixColumns() transformation operates on the State column-by-column, treating each column as a four-term polynomial as described in Sec. 4.3. - The columns are considered as polynomials over GF(2^8) and multiplied modulo x^4 + 1 with a fixed polynomial a(x), given by + The MixColumns() transformation operates on the State column-by-column, treating each column as a four-term polynomial as described in Sec. 4.3. + The columns are considered as polynomials over GF(2^8) and multiplied modulo x^4 + 1 with a fixed polynomial a(x), given by Mathematical equations 5.5 a(x) = {03}x^3 + {01}x^2 + {01}x + {02} @@ -685,8 +685,8 @@ namespace CommonSecurity::AES::ProcedureFunctions state'[2][column] = state[0][column] (+) state[1][column] (+) ({02} • state[2][column]) (+) ({03} • state[3][column]) state'[3][column] = ({03} • state[0][column]) (+) state[1][column] (+) state[2][column] (+) ({02} • state[3][column]) - MixColumns()转换对状态逐列操作,如第4.3节所述,将每一列作为一个四项多项式处理。 - 这些列被视为GF(2^8)上的多项式,并与固定的多项式a(x)相乘以x^4+1,给出如下 + MixColumns()转换对状态逐列操作,如第4.3节所述,将每一列作为一个四项多项式处理。 + 这些列被视为GF(2^8)上的多项式,并与固定的多项式a(x)相乘以x^4+1,给出如下 数学公式5.5 a(x) = {03}x^3 + {01}x^2 + {01}x + {02} @@ -700,7 +700,7 @@ namespace CommonSecurity::AES::ProcedureFunctions state'[1][column] = state[0][column] (+) ({02} • state[1][column]) (+) ({03} • state[2][column]) (+) state[3][column] state'[2][column] = state[0][column] (+) state[1][column] (+) ({02} • state[2][column]) (+) ({03} • state[3][column]) state'[3][column] = ({03} • state[0][column]) (+) state[1][column] (+) state[2][column] (+) ({02} • state[3][column]) - + In the MixColumns step, the four bytes of each column of the state are combined using an invertible linear transformation. The MixColumns function takes four bytes as input and outputs four bytes, where each input byte affects all four output bytes. Together with ShiftRows, MixColumns provides diffusion in the cryptographs. @@ -732,7 +732,7 @@ namespace CommonSecurity::AES::ProcedureFunctions for(unsigned int column = 0; column < 4; ++column) { _stateByteDataBlock.operator[](row).operator[](column) = 0x00; - + // Dot product of row (r) of the MixColumns and the column (c) of the state // MixColumns的r行与状态的c列的点积 _stateByteDataBlock.operator[](row).operator[](column) ^= MultiplicationOfByteWithGaloisField(CMDS.operator[](row).operator[](column), stateByteDataBlock.operator[](row).operator[](column)); @@ -767,16 +767,16 @@ namespace CommonSecurity::AES::ProcedureFunctions } /* - - InvMixColumns() is the inverse of the MixColumns() transformation. - InvMixColumns() operates on the State column-by-column, treating each column as a fourterm polynomial as described in Sec. 4.3. + + InvMixColumns() is the inverse of the MixColumns() transformation. + InvMixColumns() operates on the State column-by-column, treating each column as a fourterm polynomial as described in Sec. 4.3. The columns are considered as polynomials over GF(2^8) and multiplied modulo x^4 + 1 with a fixed polynomial a^-1*(x), given by Mathematical equations 5.9 a^-1*x = {0b}*x^3 + {0d}*x^2 + {09}*x + {0e} Mathematical equations 5.10 - As described in Sec. 4.3, this can be written as a matrix multiplication. + As described in Sec. 4.3, this can be written as a matrix multiplication. state'[x] = a^-1*x (*) state[x] As a result of this multiplication, the four bytes in a column are replaced by the following: @@ -828,7 +828,7 @@ namespace CommonSecurity::AES::ProcedureFunctions for(unsigned int column = 0; column < 4; ++column) { _stateByteDataBlock.operator[](row).operator[](column) = 0x00; - + // Dot product of row (r) of the InverseMixColumns and the column (c) of the state // InverseMixColumns的r行与状态的c列的点积 _stateByteDataBlock.operator[](row).operator[](column) ^= MultiplicationOfByteWithGaloisField(INVERSE_CMDS.operator[](row).operator[](column), stateByteDataBlock.operator[](row).operator[](column)); @@ -861,51 +861,51 @@ namespace CommonSecurity::AES::ProcedureFunctions #endif } - - //Transformation in the Cipher that processes the State by cyclically shifting the last three rows of the State by different offsets. + + //Transformation in the Cipher that processes the State by cyclically shifting the last three rows of the State by different offsets. //密码中的转换,通过循环处理状态 将状态的最后三行按不同的偏移量进行移位。 /* - In the ShiftRows() transformation, the bytes in the last three rows of the State are cyclically shifted over different numbers of bytes (offsets). - The first row, r = 0, is not shifted. - Specifically, the ShiftRows() transformation proceeds as follows: - + In the ShiftRows() transformation, the bytes in the last three rows of the State are cyclically shifted over different numbers of bytes (offsets). + The first row, r = 0, is not shifted. + Specifically, the ShiftRows() transformation proceeds as follows: + Mathematical equations 5.3 function(State[row], (column + shift(row, Nb))) mod Nb = function(State[row], column) - where the shift value shift(row,Nb) depends on the row number, row, as follows (recall that Nb = 4): - - Mathematical equations 5.4 - shift(1,4) = 1; - shift(2,4) = 2; + where the shift value shift(row,Nb) depends on the row number, row, as follows (recall that Nb = 4): + + Mathematical equations 5.4 + shift(1,4) = 1; + shift(2,4) = 2; shift(3,4) = 3; - - This has the effect of moving bytes to "lower" positions in the row (i.e., lower values of column in a given row), + + This has the effect of moving bytes to "lower" positions in the row (i.e., lower values of column in a given row), While the "lowest "bytes wrap around into the "top" of the row (i.e., higher values of column in a given row). - 在ShiftRows()转换中,State最后三行的字节在不同的字节数(偏移量)上被循环移位 + 在ShiftRows()转换中,State最后三行的字节在不同的字节数(偏移量)上被循环移位 第一行,r = 0,不被移位。 具体来说,ShiftRows()转换的过程如下。 - + 数学公式5.3 function(State[row], (column + shift(row, Nb))) mod Nb = function(State[row], column) 其中移位值shift(row,Nb)取决于行数row,如下所示(记得Nb=4) - - 数学公式5.4 - shift(1,4) = 1; - shift(2,4) = 2; + + 数学公式5.4 + shift(1,4) = 1; + shift(2,4) = 2; shift(3,4) = 3。 - + 这样做的效果是将字节移到行中的 "较低 "位置(即在给定行中列的低值) 而 "最低的 "字节则环绕到行的 "顶部"(即某一行中列的数值较高) - - The ShiftRows step operates on the rows of the state; - It cyclically shifts the bytes in each row by a certain offset. - In this way, each column of the output state of the ShiftRows step is composed of bytes from each column of the input state. + + The ShiftRows step operates on the rows of the state; + It cyclically shifts the bytes in each row by a certain offset. + In this way, each column of the output state of the ShiftRows step is composed of bytes from each column of the input state. The importance of this step is to avoid the columns being encrypted independently, in which case AES would degenerate into four independent block ciphers. - ShiftRows步骤对状态的行进行操作。 + ShiftRows步骤对状态的行进行操作。 它循环地将每一行的字节按一定的偏移量移动。 这样,ShiftRows步骤的输出状态的每一列都是由输入状态的每一列的字节组成。 这一步的重要性在于避免各列被独立加密,在这种情况下,AES将退化为四个独立的块密码。 @@ -922,22 +922,22 @@ namespace CommonSecurity::AES::ProcedureFunctions /* This is the inverse of the ShiftRows() transformation. - The bytes in the last three rows of the State are cyclically shifted over different numbers of bytes (offsets). + The bytes in the last three rows of the State are cyclically shifted over different numbers of bytes (offsets). The first row, r = 0, is not shifted. - The bottom three rows are cyclically shifted by Nb - shift(r, Nb) bytes, where the shift value shift(r,Nb) depends on the row number, and is given in equation (5.4) - (see Sec. 5.1.2). + The bottom three rows are cyclically shifted by Nb - shift(r, Nb) bytes, where the shift value shift(r,Nb) depends on the row number, and is given in equation (5.4) + (see Sec. 5.1.2). - Specifically, the InvShiftRows() transformation proceeds as follows: + Specifically, the InvShiftRows() transformation proceeds as follows: function(State[row], (column + shift(row, Nb))) mod Nb = function(State[row], column) Conditions for variables: 0 < row < 4 and 0 <= column < Nb 这是ShiftRows()转换的逆运算。 - 最后三行的字节在不同的字节数(偏移量)上被循环移位。 + 最后三行的字节在不同的字节数(偏移量)上被循环移位。 第一行,row = 0,不被移位。 - 最下面的三行被循环移位Nb-shift(r,Nb)字节,其中shift(r,Nb)的值取决于行数,在公式(5.4)中给出 - (见第5.1.2节)。 + 最下面的三行被循环移位Nb-shift(r,Nb)字节,其中shift(r,Nb)的值取决于行数,在公式(5.4)中给出 + (见第5.1.2节)。 - 具体来说,InvShiftRows()转换的过程如下。 + 具体来说,InvShiftRows()转换的过程如下。 function(State[row], (column + shift(row, Nb))) mod Nb = function(State[row], column) 变量的条件:0 < row < 4 和 0 <= column < Nb */ @@ -952,16 +952,16 @@ namespace CommonSecurity::AES::ProcedureFunctions } /* - The SubBytes() transformation is a non-linear byte substitution that operates independently on each byte of the State using a substitution table (S-box). - This S-box which is invertible, is constructed by composing two transformations: - 1. Take the multiplicative inverse in the finite field GF(2^8), described in Sec. 4.2; - the element {00} is mapped to itself. - 2. Apply the following affine transformation (over GF(2) ): + The SubBytes() transformation is a non-linear byte substitution that operates independently on each byte of the State using a substitution table (S-box). + This S-box which is invertible, is constructed by composing two transformations: + 1. Take the multiplicative inverse in the finite field GF(2^8), described in Sec. 4.2; + the element {00} is mapped to itself. + 2. Apply the following affine transformation (over GF(2) ): Mathematical equations 5.1 bit[index] = bit[index] (+) bit[index + 4 mod 8] (+) bit[index + 5 mod 8] (+) bit[index + 6 mod 8] (+) bit[index + 7 mod 8] (+) c[index] - for 0 <= index < 8 , where bit[index] is the index ^ the bit of the byte, and c[index] is the index ^ the bit of a byte c with the value {63} or {01100011}. - Here and elsewhere, a prime on a variable (e.g., bit' ) indicates that the variable is to be updated with the value on the right. + for 0 <= index < 8 , where bit[index] is the index ^ the bit of the byte, and c[index] is the index ^ the bit of a byte c with the value {63} or {01100011}. + Here and elsewhere, a prime on a variable (e.g., bit' ) indicates that the variable is to be updated with the value on the right. SubBytes()转换是一种非线性的字节替换,它使用一个替换表(S-box)对State的每个字节独立操作。 这个S-box是可反转的,它是由两个转换组成的。 @@ -972,26 +972,26 @@ namespace CommonSecurity::AES::ProcedureFunctions bit[index] = bit[index] (+) bit[index + 4 mod 8] (+) bit[index + 5 mod 8] (+) bit[index + 6 mod 8] (+) bit[index + 7 mod 8] (+) c[index] for 0 <= index < 8 , 其中bit[index]是字节的index ^ the位,c[index]是字节c的index ^ the位,值为{63}或{01100011}。 在这里和其他地方,变量上的素数(例如,bit')表示该变量要用右边的值来更新。 - - In the SubBytes step, each byte arrays[i][j] in the state array is replaced with a SubByte S-box[arrays[i][j]] using an 8-bit substitution box. - Note that before round 0, the state array is simply the plaintext/input. - This operation provides the non-linearity in the cipher. - The S-box used is derived from the multiplicative inverse over GF(2^8), known to have good non-linearity properties. - To avoid attacks based on simple algebraic properties, the S-box is constructed by combining the inverse function with an invertible affine transformation. - The S-box is also chosen to avoid any fixed points (and so is a derangement), i.e., S-box[arrays[i][j]] != arrays[i][j] , and also any opposite fixed points, i.e., S-box[arrays[i][j]] (+) arrays[i][j] != FF16. + + In the SubBytes step, each byte arrays[i][j] in the state array is replaced with a SubByte S-box[arrays[i][j]] using an 8-bit substitution box. + Note that before round 0, the state array is simply the plaintext/input. + This operation provides the non-linearity in the cipher. + The S-box used is derived from the multiplicative inverse over GF(2^8), known to have good non-linearity properties. + To avoid attacks based on simple algebraic properties, the S-box is constructed by combining the inverse function with an invertible affine transformation. + The S-box is also chosen to avoid any fixed points (and so is a derangement), i.e., S-box[arrays[i][j]] != arrays[i][j] , and also any opposite fixed points, i.e., S-box[arrays[i][j]] (+) arrays[i][j] != FF16. While performing the decryption, the InvSubBytes step (the inverse of SubBytes) is used, which requires first taking the inverse of the affine transformation and then finding the multiplicative inverse. - 在SubBytes步骤中,状态数组中的每个字节arrays[i][j]被替换为SubByte S-box[arrays[i][j]],使用一个8位替换框。 - 注意,在第0轮之前,状态数组只是明文/输入。 - 这个操作提供了密码中的非线性。 - 所用的S-box是由GF(2^8)上的乘法逆推而来,已知其具有良好的非线性特性。 - 为了避免基于简单代数特性的攻击,S-box是通过将反函数与可反转的仿射变换相结合而构建的。 - S-box的选择也是为了避免任何固定点(因此是一个脱轨),即S-box[arrays[i][j]] != arrays[i][j] ,以及任何相反的固定点,即S-box[ arrays[i][j] ] (+) arrays[i][j] != FF16。 + 在SubBytes步骤中,状态数组中的每个字节arrays[i][j]被替换为SubByte S-box[arrays[i][j]],使用一个8位替换框。 + 注意,在第0轮之前,状态数组只是明文/输入。 + 这个操作提供了密码中的非线性。 + 所用的S-box是由GF(2^8)上的乘法逆推而来,已知其具有良好的非线性特性。 + 为了避免基于简单代数特性的攻击,S-box是通过将反函数与可反转的仿射变换相结合而构建的。 + S-box的选择也是为了避免任何固定点(因此是一个脱轨),即S-box[arrays[i][j]] != arrays[i][j] ,以及任何相反的固定点,即S-box[ arrays[i][j] ] (+) arrays[i][j] != FF16。 在进行解密时,使用了InvSubBytes步骤(SubBytes的逆),这需要先取仿射变换的逆,然后找到乘法的逆。 */ //在密钥扩展例程中使用的函数,它接收一个四字节的输入字,并对四个字节中的每个字节应用一个S-box,以产生一个输出字。 - //Function used in the Key Expansion routine that takes a four-byte input word and applies an S-box to each of the four bytes to produce an output word. + //Function used in the Key Expansion routine that takes a four-byte input word and applies an S-box to each of the four bytes to produce an output word. inline void SubtituteBytes(std::array, 4>& stateByteDataBlock) { using namespace AES::DefineConstants; @@ -1037,11 +1037,11 @@ namespace CommonSecurity::AES::ProcedureFunctions { std::ranges::transform ( - row.begin(), - row.end(), row.begin(), - [](const unsigned char &byte) -> unsigned char - { + row.end(), + row.begin(), + [](const unsigned char &byte) -> unsigned char + { return Forward_S_Box[byte / 16][byte % 16]; } ); @@ -1051,10 +1051,10 @@ namespace CommonSecurity::AES::ProcedureFunctions } /* - InvSubBytes() is the inverse of the byte substitution transformation, in which the inverse S-box is applied to each byte of the State. + InvSubBytes() is the inverse of the byte substitution transformation, in which the inverse S-box is applied to each byte of the State. This is obtained by applying the inverse of the affine transformation (5.1) followed by taking the multiplicative inverse in GF(2^8). - InvSubBytes()是字节替换变换的逆运算,其中逆S-box被应用于状态的每个字节。 + InvSubBytes()是字节替换变换的逆运算,其中逆S-box被应用于状态的每个字节。 这是由应用仿射变换的逆(5.1),然后在GF(2^8)中取乘法逆得到的。 */ inline void InverseSubtituteBytes(std::array, 4>& stateByteDataBlock) @@ -1102,11 +1102,11 @@ namespace CommonSecurity::AES::ProcedureFunctions { std::ranges::transform ( - row.begin(), - row.end(), row.begin(), - [](const unsigned char &byte) -> unsigned char - { + row.end(), + row.begin(), + [](const unsigned char &byte) -> unsigned char + { return Backward_S_Box[byte / 16][byte % 16]; } ); @@ -1117,14 +1117,14 @@ namespace CommonSecurity::AES::ProcedureFunctions /* In the AddRoundKey step, the subkey is combined with the state. - For each round, a subkey is derived from the main key using Rijndael's key schedule; each subkey is the same size as the state. + For each round, a subkey is derived from the main key using Rijndael's key schedule; each subkey is the same size as the state. The subkey is added by combining each byte of the state with the corresponding byte of the subkey using bitwise (+). 在AddRoundKey步骤中,子密钥与状态相结合。 对于每一轮,使用Rijndael的密钥计划从主密钥中导出一个子密钥;每个子密钥的大小与状态相同。 子密钥的添加是通过将状态的每个字节与子密钥的相应字节用位法(+)结合起来。 - Transformation in the Cipher and Inverse Cipher in which a Round Key is added to the State using an XOR operation. + Transformation in the Cipher and Inverse Cipher in which a Round Key is added to the State using an XOR operation. The length of a Round Key equals the size of the State data block (i.e., for Nb = 4, the Round Key length equals 128 bits/16 bytes). 在密码器和反密码器中的转换,其中一个轮密钥是使用XOR操作添加到状态数据中 @@ -1149,21 +1149,21 @@ namespace CommonSecurity::RC6::DefineConstants constexpr unsigned int KEY_BIT_SIZE_MAX_LIMIT = 8 * 255; /* - + double GOLDEN_RATIO 0.618033988749895 = 1 / ((1 + std::sqrt(5)) / 2) is 1 / 1.618033988749895; (std::numbers::phi == 1 / 0.618033988749895) is true (0.618033988749895 == 1 / std::numbers::phi) is true where Φ is the golden ratio constant - + */ constexpr double GOLDEN_RATIO = std::numbers::phi - 1; /* - + double BASE_OF_THE_NATURAL_LOGARITHM = sum( 1/(factorial(items_number)) + 1/(factorial(items_number - 1 )) + 1/(factorial(items_number - 2)) ..... + 1/(factorial(1)) + 1/(factorial(0)) ) is 2.718281828459045 If items_number approaches infinity, hen it is the limit of (1 + 1/items_number)^items_number where e is the base of natural logarithm function - + */ constexpr double BASE_OF_THE_NATURAL_LOGARITHM = std::numbers::e; @@ -1280,4 +1280,4 @@ namespace CommonSecurity::RC6::ProcedureFunctions virtual ~BaseInterface() = default; }; -} \ No newline at end of file +} diff --git a/include/CommonSecurity/SecureHashProvider/AlgorithmBlake3.hpp b/include/CommonSecurity/SecureHashProvider/AlgorithmBlake3.hpp index 144054d..3a44b92 100644 --- a/include/CommonSecurity/SecureHashProvider/AlgorithmBlake3.hpp +++ b/include/CommonSecurity/SecureHashProvider/AlgorithmBlake3.hpp @@ -1054,16 +1054,16 @@ namespace CommonSecurity::Blake3 using CommonSecurity::Blake2::Core::HashConstants; //Generated hash size is a 64 byte or 128 byte - inline constexpr CommonToolkit::FourByte GeneratedHashBytesSize = CURRENT_SYSTEM_BITS == 32 ? 64 : 128; + inline constexpr std::size_t GeneratedHashBytesSize = _GeneratedHashBytesSize_(); //Hash data block size is a 64 byte or 128 byte - inline constexpr CommonToolkit::FourByte HashBlockBytesSize = CURRENT_SYSTEM_BITS == 32 ? 64 : 128; + inline constexpr std::size_t HashBlockBytesSize = _HashBlockBytesSize_(); //Key size is a 32 byte or 64 byte - inline constexpr CommonToolkit::FourByte KeyBytesSize = CURRENT_SYSTEM_BITS == 32 ? 32 : 64; + inline constexpr std::size_t KeyBytesSize = _KeyBytesSize_(); //Hash memory chunk size is 1 kilo-byte - inline constexpr CommonToolkit::FourByte HashChunkBytesSize = 1024; + inline constexpr std::size_t HashChunkBytesSize = 1024; inline constexpr std::uint32_t FlagChunkStart = 1 << 0; inline constexpr std::uint32_t FlagChunkEnd = 1 << 1; @@ -1558,7 +1558,7 @@ namespace CommonSecurity::Blake3 { private: - std::array ChainingValue; + std::array ChainingValue; std::uint32_t HashStateFlags = 0; std::array _this_byte_block; @@ -1633,30 +1633,14 @@ namespace CommonSecurity::Blake3 CommonToolkit::BitConverters::le32_copy(temporary_data.data(), 0, _this_byte_block.data(), _this_byte_block_size, take); else CommonToolkit::BitConverters::le64_copy(temporary_data.data(), 0, _this_byte_block.data(), _this_byte_block_size, take); + _this_byte_block_size += take; */ - - if constexpr(CURRENT_SYSTEM_BITS == 64) - { - std::ranges::copy_n( temporary_data.data() + 0, take, _this_byte_block.data() + 0 ); - if(_this_byte_block.data() != nullptr && _this_byte_block.size() == take) - _this_byte_block_size += take; - else - my_cpp2020_assert(false, "", std::source_location::current()); - } - else if constexpr(CURRENT_SYSTEM_BITS == 32) - { - std::ranges::copy_n( temporary_data.data() + 0, take, _this_byte_block.data() + 0 ); - std::ranges::copy_n( temporary_data.data() + take, take, _this_byte_block.data() + take ); - - if(_this_byte_block.data() != nullptr && _this_byte_block.size() == take) - _this_byte_block_size += take * 2; - else - my_cpp2020_assert(false, "", std::source_location::current()); - } + + std::ranges::copy_n( temporary_data.data() + 0, take, _this_byte_block.data() + 0 ); + if(_this_byte_block.data() != nullptr && _this_byte_block.size() == take) + _this_byte_block_size += take; else - { - static_assert(CURRENT_SYSTEM_BITS == 32 || CURRENT_SYSTEM_BITS == 64, "Unknown number of system bits"); - } + my_cpp2020_assert(false, "", std::source_location::current()); std::vector memory_data_slice = Core::Functions::MemoryDataSlice(temporary_data.data(), take, temporary_data.size() - take); temporary_data.clear(); @@ -1743,7 +1727,7 @@ namespace CommonSecurity::Blake3 HashMemoryChunkState ( - std::array iniital_vector_or_processed_key, + std::array iniital_vector_or_processed_key, std::size_t chunk_counter, std::uint32_t hash_state_flags ) @@ -1873,22 +1857,24 @@ namespace CommonSecurity::Blake3 //Appends a chunk to the right edge of the Merkle tree (HashTreeNode). //在Merkle树(HashTreeNode)的右侧边缘添加一个分块。 - void AppendChunkChainingValue(std::array chaining_state_data, std::size_t total_chunk_number) + void AppendChunkChainingValue(std::array& chaining_state_data, std::size_t total_chunk_number) { // This chunk might complete some subtrees - // For each completed subtree, its left child will be the current top entry in the CV stack, and its right child will be the current value of `new_cv`. - // Pop each left child off the stack, merge it with `new_cv`, and overwrite `new_cv` with the result. - // After all these merges, push the final value of `new_cv` onto the stack. + // For each completed subtree, its left child will be the current top entry in the CV stack, and its right child will be the current value of `chaining_state_data`. + // Pop each left child off the stack, merge it with `chaining_state_data`, and overwrite `chaining_state_data` with the result. + // After all these merges, push the final value of `chaining_state_data` onto the stack. // The number of completed subtrees is given by the number of trailing 0-bits in the new total number of chunks. // 这个块可能会完成一些子树 - // 对于每个完成的子树,其左边的子树将是CV堆栈中当前最上面的条目,而其右边的子树将是`new_cv`的当前值。 - // 从堆栈中弹出每个左子,与`new_cv`合并,并将结果覆盖`new_cv`。 - // 在所有这些合并之后,把`new_cv`的最终值推到栈上。 + // 对于每个完成的子树,其左边的子树将是CV堆栈中当前最上面的条目,而其右边的子树将是`chaining_state_data`的当前值。 + // 从堆栈中弹出每个左子,与`chaining_state_data`合并,并将结果覆盖`chaining_state_data`。 + // 在所有这些合并之后,把`chaining_state_data`的最终值推到栈上。 // 完成的子树的数量由新的总块数中尾部0比特的数量给出。 + + std::array update_chaining_state_data(chaining_state_data); while ((total_chunk_number & 1) == 0) { - chaining_state_data = HashDataGeneratorObject.ChainedValueOfCurrentParentTreeNode + update_chaining_state_data = HashDataGeneratorObject.ChainedValueOfCurrentParentTreeNode ( ChainedValueFromHashTreeNodeOfStackObject.Pop(), chaining_state_data, @@ -1899,7 +1885,7 @@ namespace CommonSecurity::Blake3 total_chunk_number >>= 1; } - ChainedValueFromHashTreeNodeOfStackObject.Push(chaining_state_data); + ChainedValueFromHashTreeNodeOfStackObject.Push(update_chaining_state_data); } inline void hash_transform( const CommonToolkit::OneByte* data, std::size_t data_offset_index, std::size_t data_number_blocks ) @@ -1934,12 +1920,12 @@ namespace CommonSecurity::Blake3 //Compress original bytes into the current chunk state. //将原始字节压缩到当前分块状态 - std::size_t want = Core::HashChunkBytesSize - HashChunkStateObject.CheckBlockSize(); - std::size_t take = std::min(want, span_block_size); + std::size_t want_count = Core::HashChunkBytesSize - HashChunkStateObject.CheckBlockSize(); + std::size_t other_want_count = span_block_size - index; + std::size_t take = std::min(want_count, other_want_count); std::vector memory_data_slice = Core::Functions::MemoryDataSlice(work_data_pointer, index, take); HashChunkStateObject.UpdateChunk(memory_data_slice, HashDataGeneratorObject); index += take; - span_block_size -= index; } } diff --git a/include/CommonSecurity/SecureHashProvider/Hasher.hpp b/include/CommonSecurity/SecureHashProvider/Hasher.hpp index abf56d9..ac0080a 100644 --- a/include/CommonSecurity/SecureHashProvider/Hasher.hpp +++ b/include/CommonSecurity/SecureHashProvider/Hasher.hpp @@ -8,7 +8,7 @@ * 发布 TDOM-EncryptOrDecryptFile-Reborn 是希望它能有用,但是并无保障;甚至连可销售和符合某个特定的目的都不保证。请参看 GNU 通用公共许可证,了解详情。 * 你应该随程序获得一份 GNU 通用公共许可证的复本。如果没有,请看 。 */ - + /* * Copyright (C) 2021-2022 Twilight-Dream * @@ -32,7 +32,7 @@ namespace CommonSecurity::FNV_1a::Hasher { /* - + template struct no_cryptography_hash_algorithm_fnv_1 { @@ -85,7 +85,7 @@ namespace CommonSecurity::FNV_1a::Hasher // 374144419156711147060143317175368453031918731002211u; // const std::size_t fnv_offset_basis = // 100029257958052580907070968620625704837092796014241193945225284501741471925557u; - + */ class hash_combine @@ -116,7 +116,7 @@ namespace CommonSecurity::FNV_1a::Hasher //https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function auto hashed_value = std::hash()(object); hash_seed ^= hashed_value + golden_ration + (hash_seed << 6) + (hash_seed >> 2); - return hash_seed; + return hash_seed; } }; } // namespace CommonSecurity::FNV_1a::Hasher @@ -236,7 +236,7 @@ namespace CommonSecurity::SHA::Hasher std::vector hash_value( _HashProvider.HashSize() / 8 ); this->TakeDigest( hash_value ); ss << UtilTools::DataFormating::ASCII_Hexadecmial::byteArray2HexadecimalString( hash_value ); - + //std::vector().swap( hash_value ); hash_value.clear(); hash_value.shrink_to_fit(); @@ -269,7 +269,7 @@ namespace CommonSecurity::SHA::Hasher std::string& Key, std::span salt_bytes, std::span personalization_bytes - ) + ) : _HashProvider( hashsize ) { _HashProvider.UpdateStringKey(Key); @@ -764,7 +764,7 @@ namespace CommonSecurity::DataHashingWrapper else throw std::invalid_argument(" If the size of the source string message is zero, then it cannot be transformed into the target hash digest message! "); } - + HashersAssistant() = default; ~HashersAssistant() = default; @@ -779,7 +779,7 @@ namespace CommonSecurity::DataHashingWrapper * 它可以用来保证资料的完整性,同时可以用来作某个消息的身份验证。 * https://en.wikipedia.org/wiki/HMAC * In cryptography, an HMAC (sometimes expanded as either keyed-hash message authentication code or hash-based message authentication code) - * is a specific type of message authentication code (MAC) involving a cryptographic hash function and a secret cryptographic key. + * is a specific type of message authentication code (MAC) involving a cryptographic hash function and a secret cryptographic key. * As with any MAC, it may be used to simultaneously verify both the data integrity and authenticity of a message. * HMAC can provide authentication using a shared secret instead of using digital signatures with asymmetric cryptography. * It trades off the need for a complex public key infrastructure by delegating the key exchange to the communicating parties, who are responsible for establishing and using a trusted channel to agree on the key prior to communication. @@ -865,11 +865,11 @@ namespace CommonSecurity::DataHashingWrapper HashersAssistantParameters_Instance.inputDataString = LastData; HashersAssistant::SELECT_HASH_FUNCTION( HashersAssistantParameters_Instance ); std::string LastHashedData = HashersAssistantParameters_Instance.outputHashedHexadecimalString; - + FirstData.clear(); FirstHashedData.clear(); LastData.clear(); - + HashersAssistantParameters_Instance.inputDataString.clear(); HashersAssistantParameters_Instance.outputHashedHexadecimalString.clear(); @@ -883,21 +883,21 @@ namespace CommonSecurity::DataHashingWrapper public: std::string operator()( HashersAssistantParameters& HashersAssistantParameters_Instance, const std::string& Message, const std::size_t& MessageBlockSize, std::string Key ) { - whether_occupied.wait(true, std::memory_order::seq_cst); + whether_occupied.wait(true, std::memory_order_seq_cst); - whether_occupied.store(true, std::memory_order::memory_order_seq_cst); + whether_occupied.store(true, std::memory_order_seq_cst); if(std::addressof(HashersAssistantParameters_Instance) == nullptr) { - whether_occupied.store(false, std::memory_order::memory_order_relaxed); + whether_occupied.store(false, std::memory_order_relaxed); whether_occupied.notify_all(); return std::string(); } std::string HMAC_String = HMAC_Pointer.get()->ComputeMessageAuthenticationCode( HashersAssistantParameters_Instance, Message, MessageBlockSize, Key ); - whether_occupied.store(false, std::memory_order::memory_order_relaxed); + whether_occupied.store(false, std::memory_order_relaxed); whether_occupied.notify_all(); return HMAC_String; } }; inline HMAC_Worker HMAC_FunctionObject; -} // CommonSecurity::DataHashingWrapper \ No newline at end of file +} // CommonSecurity::DataHashingWrapper diff --git a/include/CommonSecurity/SecureHashProvider/SecureHashProviderBase.hpp b/include/CommonSecurity/SecureHashProvider/SecureHashProviderBase.hpp index b2d4621..1c26e3b 100644 --- a/include/CommonSecurity/SecureHashProvider/SecureHashProviderBase.hpp +++ b/include/CommonSecurity/SecureHashProvider/SecureHashProviderBase.hpp @@ -8,7 +8,7 @@ * 发布 TDOM-EncryptOrDecryptFile-Reborn 是希望它能有用,但是并无保障;甚至连可销售和符合某个特定的目的都不保证。请参看 GNU 通用公共许可证,了解详情。 * 你应该随程序获得一份 GNU 通用公共许可证的复本。如果没有,请看 。 */ - + /* * Copyright (C) 2021-2022 Twilight-Dream * @@ -33,15 +33,15 @@ namespace CommonSecurity //初始化哈希器的状态数据 //Initialize the state data of the hashers virtual inline void StepInitialize() = 0; - + //如果源字节数据大小大于或者等于一个即将哈希的分块字节数据大小,那么就更新哈希器的状态数据:使用HashTransform私有函数来处理 【分块字节大小】*【分块字节数量】的字节数据 //If the source byte data size is greater than or equal to the size of a chunk byte data to be hashed, then update the hasher state data: use the HashTransform private function to process the byte data of [chunk byte size] * [chunk byte count] virtual inline void StepUpdate( const std::span data_value_vector ) = 0; - + //否则源字节数据小于一个即将哈希的分块字节数据大小,那么就直接使用一次HashTransform私有函数 //Otherwise, if the source byte data is smaller than the size of a chunk byte data to be hashed, then use the HashTransform private function directly once virtual inline void StepFinal( std::span hash_value_vector ) = 0; - + //散列信息的比特大小 //Bit size of hashed message virtual inline std::size_t HashSize() const = 0; @@ -165,7 +165,7 @@ namespace CommonSecurity /* Clear memory, suppressing compiler optimizations. - + @brief Sets each element of an array to 0 @param BufferDataType; is class or type @param buffer; an array of elements @@ -180,11 +180,11 @@ namespace CommonSecurity #if 1 #if 1 - + memory_set_no_optimize_function(variable_pointer, 0, size); - + #else - + // GCC 4.3.2 on Cygwin optimizes away the first store if this // loop is done in the forward direction volatile BufferDataType* data_pointer = static_cast( variable_pointer + size ); @@ -274,11 +274,11 @@ namespace CommonSecurity template struct is_byte { - static const bool value = std::is_same_v::value || std::is_same_v::value || + static const bool value = std::is_same_v || std::is_same_v || #if ( defined( _HAS_STD_BYTE ) && _HAS_STD_BYTE ) || ( defined( __cpp_lib_byte ) && __cpp_lib_byte >= 201603 ) - std::is_same_v::value || + std::is_same_v || #endif - std::is_same_v::value || std::is_same_v::value; + std::is_same_v || std::is_same_v; }; template diff --git a/include/CommonSecurity/StreamDataCryption.hpp b/include/CommonSecurity/StreamDataCryption.hpp index 9c01388..2b85231 100644 --- a/include/CommonSecurity/StreamDataCryption.hpp +++ b/include/CommonSecurity/StreamDataCryption.hpp @@ -4,12 +4,12 @@ /* - Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). - Note that other groups may also distribute working documents as Internet-Drafts. + Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). + Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/. - The eXtended-nonce ChaCha cipher construction (XChaCha) allows for ChaCha-based ciphersuites to accept a 192-bit nonce with similar guarantees to the original construction, except with a much lower probability of nonce misuse occurring. - This helps for long running TLS connections. + The eXtended-nonce ChaCha cipher construction (XChaCha) allows for ChaCha-based ciphersuites to accept a 192-bit nonce with similar guarantees to the original construction, except with a much lower probability of nonce misuse occurring. + This helps for long running TLS connections. This also enables XChaCha constructions to be stateless, while retaining the same security assumptions as ChaCha. This document defines XChaCha20, which uses HChaCha20 to convert the key and part of the nonce into a subkey, which is in turn used with the remainder of the nonce with ChaCha20 to generate a pseudorandom keystream (e.g. for message encryption). @@ -24,7 +24,7 @@ namespace CommonSecurity::StreamDataCryptographic { /* Abstract base class for XSalsa20, ChaCha20, XChaCha20 and their variants. - + Variants of Snuffle have two differences: the size of the nonce and the block function that produces a key stream block from a key, a nonce, and a counter. Subclasses of this class specifying these two information by overriding "ByteSizeOfNonces" and "ByteSizeOfKeyBlocks" and function "ProcessKeyStreamBlock(std::span nonce, std::uint32_t counter, std::span block)". Concrete implementations of this class are meant to be used to construct an AEAD with "Poly1305". @@ -36,7 +36,7 @@ namespace CommonSecurity::StreamDataCryptographic { private: - + std::unique_ptr> RNG_Pointer = nullptr; /* @@ -50,7 +50,7 @@ namespace CommonSecurity::StreamDataCryptographic { std::size_t data_size = input.size(); std::size_t number_blocks = data_size / ByteSizeOfKeyBlocks() + 1; - + bool is_counter_overflow = false; auto& RNG = *(RNG_Pointer.get()); std::vector shuffle_nonce; @@ -67,9 +67,20 @@ namespace CommonSecurity::StreamDataCryptographic if(RNG_Pointer == nullptr) { - //std::random_device TRNG; - //std::size_t RNG_Seed = TRNG(); - std::size_t RNG_Seed = ( static_cast(CurrentInitialKeySpan[0]) + static_cast(CurrentInitialKeySpan[1]) + static_cast(CurrentInitialKeySpan[2]) + static_cast(CurrentInitialKeySpan[3]) ) ^ ( static_cast(CurrentInitialKeySpan[4]) + static_cast(CurrentInitialKeySpan[5]) + static_cast(CurrentInitialKeySpan[6]) + static_cast(CurrentInitialKeySpan[7]) ); + std::uint64_t RNG_Seed = 0; + + //Does it use a true random number generator? + //是否使用真随机数生成器? + if constexpr(false) + { + std::random_device TRNG; + RNG_Seed = GenerateSecureRandomNumberSeed(TRNG); + } + else + { + RNG_Seed = ( static_cast(CurrentInitialKeySpan[0]) + static_cast(CurrentInitialKeySpan[1]) + static_cast(CurrentInitialKeySpan[2]) + static_cast(CurrentInitialKeySpan[3]) ) ^ ( static_cast(CurrentInitialKeySpan[4]) + static_cast(CurrentInitialKeySpan[5]) + static_cast(CurrentInitialKeySpan[6]) + static_cast(CurrentInitialKeySpan[7]) ); + } + RNG_Pointer = std::make_unique>(RNG_Seed); } @@ -133,7 +144,7 @@ namespace CommonSecurity::StreamDataCryptographic /* From this function, the Snuffle encryption function can be constructed using the counter mode of operation. For example, the ChaCha20 block function and how it can be used to construct the ChaCha20 encryption function are described in section 2.3 and 2.4 of RFC 8439. - + @param nonce; The initialized vector nonce. @param counter; The initialized counter @param key_stream_block; The key stream block @@ -196,7 +207,7 @@ namespace CommonSecurity::StreamDataCryptographic */ class Poly1305 { - + private: static std::vector LastBlock(std::span buffer, std::size_t index) { @@ -490,7 +501,7 @@ namespace CommonSecurity::StreamDataCryptographic : WorkerBase(initial_key, initial_counter) { - + } }; @@ -607,7 +618,7 @@ namespace CommonSecurity::StreamDataCryptographic : WorkerBase(initial_key, initial_counter) { - + } }; @@ -686,7 +697,7 @@ namespace CommonSecurity::StreamDataCryptographic my_cpp2020_assert(!nonce.empty() && nonce.size() == requirement_nonce_byte_size, error_message_stream.str().c_str(), std::source_location::current()); // The first four words (0-3) are constants: 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574. - + // Set the ChaCha20 constant. state[0] = SIGMA_TABLE[0]; state[1] = SIGMA_TABLE[1]; @@ -855,7 +866,7 @@ namespace CommonSecurity::StreamDataCryptographic // Reference papers: http://cr.yp.to/snuffle/xsalsa-20081128.pdf under 2. Specification - Definition of XSalsa20 // The first four words in diagonal (0,5,10,15) are constants: 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574. - + // Set the Salsa20 constant. state[0] = SIGMA_TABLE[0]; state[5] = SIGMA_TABLE[1]; @@ -1000,7 +1011,7 @@ namespace CommonSecurity::StreamDataCryptographic std::size_t cipher_text_padded_size = WorkerBaseWithPoly1305::GetPaddedSize(cipher_text, Poly1305::BYTES_OF_MAC_TAG); std::vector mac_data(associated_data_padded_size + cipher_text_padded_size + Poly1305::BYTES_OF_MAC_TAG, 0x00); - + // MAC Content Part std::ranges::copy_n(ad_bytes.begin(), associated_data_size, mac_data.begin()); std::ranges::copy_n(cipher_text.begin(), cipher_text_size, mac_data.begin() + associated_data_padded_size); @@ -1082,7 +1093,7 @@ namespace CommonSecurity::StreamDataCryptographic class ChaCha20WithPoly1305 : public WorkerBaseWithPoly1305 { - + public: ChaCha20WithPoly1305(std::span initial_key) { @@ -1093,7 +1104,7 @@ namespace CommonSecurity::StreamDataCryptographic class ExtendedChaCha20WithPoly1305 : public WorkerBaseWithPoly1305 { - + public: ExtendedChaCha20WithPoly1305(std::span initial_key) { @@ -1112,10 +1123,27 @@ namespace CommonSecurity::StreamDataCryptographic ) { std::uint64_t RNG_NumberSquare_SeedKey = 0; - CommonToolkit::MessagePacking(byte_datas.subspan(0, sizeof(std::uint64_t)), &RNG_NumberSquare_SeedKey); - //std::random_device random_device_object; - auto RNG_NumberSquare_Pointer = std::make_unique(0, RNG_NumberSquare_SeedKey, std::rotl(RNG_NumberSquare_SeedKey, 32), 0); + //Does it use a true random number generator? + //是否使用真随机数生成器? + if constexpr(false) + { + std::random_device random_device_object; + RNG_NumberSquare_SeedKey = GenerateSecureRandomNumberSeed(random_device_object); + } + else + { + CommonToolkit::MessagePacking(byte_datas.subspan(0, sizeof(std::uint64_t)), &RNG_NumberSquare_SeedKey); + } + + auto RNG_NumberSquare_Pointer = std::make_unique + ( + 0, + RNG_NumberSquare_SeedKey, + std::rotl(RNG_NumberSquare_SeedKey, CURRENT_SYSTEM_BITS == 32 ? 16 : 32), + 0 + ); + auto& RNG_NumberSquare = *(RNG_NumberSquare_Pointer.get()); std::vector PRNE_SeedSequence = std::vector(64, 0x00); @@ -1211,13 +1239,16 @@ namespace CommonSecurity::StreamDataCryptographic std::vector& this_message_data, std::vector& this_key_data, std::vector& this_nonce_data, - std::vector& this_poly1305_tag_data, + std::deque>& this_poly1305_tag_datas, std::vector this_associated_data = std::vector() ) { - my_cpp2020_assert( worker_mode == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_ENCRYPTER || worker_mode == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_DECRYPTER, "Invalid working mode", std::source_location::current() ); + if(worker_mode == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_ENCRYPTER) + my_cpp2020_assert(this_poly1305_tag_datas.empty(), "", std::source_location::current()); + else if(worker_mode == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_DECRYPTER) + my_cpp2020_assert(!this_poly1305_tag_datas.empty(), "", std::source_location::current()); - this_poly1305_tag_data.resize(16); + my_cpp2020_assert( worker_mode == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_ENCRYPTER || worker_mode == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_DECRYPTER, "Invalid working mode", std::source_location::current() ); AlignDataSize(data_worker, this_key_data, this_nonce_data); @@ -1229,13 +1260,15 @@ namespace CommonSecurity::StreamDataCryptographic else key_data_double_queue.push_back(this_key_data); - if(this_nonce_data.size() != 6 * sizeof(std::uint32_t)) + if(this_nonce_data.size() != data_worker.ByteSizeOfNonces()) CommonToolkit::ProcessingDataBlock::splitter(this_nonce_data, std::back_inserter(nonce_data_double_queue), data_worker.ByteSizeOfNonces()); else nonce_data_double_queue.push_back(this_nonce_data); - std::vector temporary_message_data = this_message_data; + std::vector this_poly1305_tag_data(16, 0x00); + std::vector temporary_message_data(this_message_data); + memory_set_no_optimize_function(this_message_data.data(), 0, this_message_data.size()); std::vector processed_message_data; for @@ -1252,14 +1285,15 @@ namespace CommonSecurity::StreamDataCryptographic if(worker_mode == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_ENCRYPTER) { data_worker.Encrypt(*nonce_first, temporary_message_data, processed_message_data, this_poly1305_tag_data, this_associated_data); - temporary_message_data = std::move(processed_message_data); + this_poly1305_tag_datas.push_back(this_poly1305_tag_data); } - if(worker_mode == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_DECRYPTER) + else if(worker_mode == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_DECRYPTER) { + this_poly1305_tag_data = this_poly1305_tag_datas.back(); data_worker.Decrypt(*nonce_first, temporary_message_data, processed_message_data, this_poly1305_tag_data, this_associated_data); - temporary_message_data = std::move(processed_message_data); + this_poly1305_tag_datas.pop_back(); } - std::ranges::swap_ranges(this_message_data, processed_message_data); + temporary_message_data = std::move(processed_message_data); data_worker.UpdateKey(*key_first); } @@ -1290,13 +1324,13 @@ namespace CommonSecurity::StreamDataCryptographic else key_data_double_queue.push_back(this_key_data); - if(this_nonce_data.size() != 6 * sizeof(std::uint32_t)) + if(this_nonce_data.size() != data_worker.ByteSizeOfNonces()) CommonToolkit::ProcessingDataBlock::splitter(this_nonce_data, std::back_inserter(nonce_data_double_queue), data_worker.ByteSizeOfNonces()); else nonce_data_double_queue.push_back(this_nonce_data); - std::vector temporary_message_data = this_message_data; - + std::vector temporary_message_data(this_message_data); + memory_set_no_optimize_function(this_message_data.data(), 0, this_message_data.size()); std::vector processed_message_data; for @@ -1378,7 +1412,7 @@ namespace CommonSecurity::StreamDataCryptographic this_key_data.resize(key_data.size()); std::ranges::copy(key_data.begin(), key_data.end(), this_key_data.begin()); this_nonce_data.resize(nonce_data.size()); - std::ranges::copy(nonce_data.begin(), nonce_data.end(), nonce_data.begin()); + std::ranges::copy(nonce_data.begin(), nonce_data.end(), this_nonce_data.begin()); memory_set_no_optimize_function(message_data.data(), 0, message_data.size()); memory_set_no_optimize_function(key_data.data(), 0, key_data.size()); @@ -1397,20 +1431,25 @@ namespace CommonSecurity::StreamDataCryptographic std::span message_data_span { message_data }; std::span key_data_span { key_data }; std::span nonce_data_span { nonce_data }; - + this_message_data.resize(message_data_span.size()); std::ranges::copy(message_data_span.begin(), message_data_span.end(), this_message_data.begin()); this_key_data.resize(key_data_span.size()); std::ranges::copy(key_data_span.begin(), key_data_span.end(), this_key_data.begin()); this_nonce_data.resize(nonce_data_span.size()); - std::ranges::copy(nonce_data_span.begin(), nonce_data_span.end(), nonce_data_span.begin()); + std::ranges::copy(nonce_data_span.begin(), nonce_data_span.end(), this_nonce_data.begin()); memory_set_no_optimize_function(std::addressof(message_data), 0, std::ranges::size(message_data)); memory_set_no_optimize_function(std::addressof(key_data), 0, std::ranges::size(key_data)); memory_set_no_optimize_function(std::addressof(nonce_data), 0, std::ranges::size(message_data)); } - return AlgorithmExecutor(data_worker, this_message_data, this_key_data, this_nonce_data); + std::vector processed_message_data = AlgorithmExecutor(data_worker, this_message_data, this_key_data, this_nonce_data); + + memory_set_no_optimize_function(this_key_data.data(), 0, this_key_data.size()); + memory_set_no_optimize_function(this_nonce_data.data(), 0, this_nonce_data.size()); + + return processed_message_data; } } } @@ -1682,7 +1721,7 @@ namespace CommonSecurity::OldStreamDataCryptographic { std::uint32_t temporary_integer = work_state_block_span.operator[](index) + state_block_span.operator[](index); std::span temporary_data_array_span = data_format_exchanger.Unpacker_4Byte(temporary_integer); - + key_stream_block.operator[](index * 4) = temporary_data_array_span.operator[](0); key_stream_block.operator[](index * 4 + 1) = temporary_data_array_span.operator[](1); key_stream_block.operator[](index * 4 + 2) = temporary_data_array_span.operator[](2); @@ -1713,7 +1752,7 @@ namespace CommonSecurity::OldStreamDataCryptographic { inner_block(state) } - + state += initial_state return serialize(state) } @@ -1728,7 +1767,7 @@ namespace CommonSecurity::OldStreamDataCryptographic } // and - + chacha20_encrypt(key, counter, nonce, plaintext): { for j = 0 upto floor(len(plaintext)/64)-1 @@ -1746,7 +1785,7 @@ namespace CommonSecurity::OldStreamDataCryptographic } return encrypted_message } - + */ template void ChaCha20_TransformData(std::span buffer, std::size_t start_index, std::size_t end_index) @@ -1832,7 +1871,7 @@ namespace CommonSecurity::OldStreamDataCryptographic //With random number device WorkerChaCha20() { - this->FillStateBlocks_Chacha20(); + this->FillStateBlocks_Chacha20(); } //With user integer data @@ -1868,12 +1907,12 @@ namespace CommonSecurity::OldStreamDataCryptographic an extended-nonce Salsa20 variant used in NaCl [12]. HChaCha20 is initialized the same way as the ChaCha cipher, - except that HChaCha20 uses a 128-bit nonce and has no counter. + except that HChaCha20 uses a 128-bit nonce and has no counter. Instead, the block counter is replaced by the first 32 bits of the nonce. Consider the two figures below, - where each non-whitespace character represents one nibble of information about the ChaCha states (all numbers little-endian): - + where each non-whitespace character represents one nibble of information about the ChaCha states (all numbers little-endian): + cccccccc cccccccc cccccccc cccccccc kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk @@ -2031,7 +2070,7 @@ namespace CommonSecurity::OldStreamDataCryptographic static std::vector ExtendedChaCha20(std::span message_data, std::span key_data, std::span nonce_data, std::uint32_t counter = 1) { WorkerExtendedChaCha20 extended_chacha20_worker(key_data, nonce_data); - + std::array subkey_block = { 0x0000000, 0x0000000, 0x0000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000 }; extended_chacha20_worker.HChaCha20(subkey_block); @@ -2062,7 +2101,7 @@ namespace CommonSecurity::OldStreamDataCryptographic static std::vector ExtendedChaCha20(std::span message_data, std::span key_data, std::span nonce_data, std::uint32_t counter = 1) { WorkerExtendedChaCha20 extended_chacha20_worker(key_data, nonce_data); - + std::array subkey_block = { 0x0000000, 0x0000000, 0x0000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000 }; extended_chacha20_worker.HChaCha20(subkey_block); @@ -2087,9 +2126,27 @@ namespace CommonSecurity::OldStreamDataCryptographic ) { std::uint64_t RNG_NumberSquare_SeedKey = 0; - CommonToolkit::MessagePacking(byte_datas.subspan(0, sizeof(std::uint64_t)), &RNG_NumberSquare_SeedKey); - auto RNG_NumberSquare_Pointer = std::make_unique(0, RNG_NumberSquare_SeedKey, std::rotl(RNG_NumberSquare_SeedKey, 32), 0); + //Does it use a true random number generator? + //是否使用真随机数生成器? + if constexpr(false) + { + std::random_device random_device_object; + RNG_NumberSquare_SeedKey = GenerateSecureRandomNumberSeed(random_device_object); + } + else + { + CommonToolkit::MessagePacking(byte_datas.subspan(0, sizeof(std::uint64_t)), &RNG_NumberSquare_SeedKey); + } + + auto RNG_NumberSquare_Pointer = std::make_unique + ( + 0, + RNG_NumberSquare_SeedKey, + std::rotl(RNG_NumberSquare_SeedKey, CURRENT_SYSTEM_BITS == 32 ? 16 : 32), + 0 + ); + auto& RNG_NumberSquare = *(RNG_NumberSquare_Pointer.get()); std::vector PRNE_SeedSequence = std::vector(64, 0x00); diff --git a/include/CommonToolkit/BytesExchangeInteger.hpp b/include/CommonToolkit/BytesExchangeInteger.hpp index 786f5ad..7009d9d 100644 --- a/include/CommonToolkit/BytesExchangeInteger.hpp +++ b/include/CommonToolkit/BytesExchangeInteger.hpp @@ -33,7 +33,7 @@ namespace CommonToolkit destination_pointer -= 1; } // end for } // end function ReverseByteArray - + static std::int32_t ReverseBytesInt32(const std::int32_t value) { auto integer_a = value & 0xFF; @@ -58,8 +58,8 @@ namespace CommonToolkit static std::uint32_t ReverseBytesUInt32(const std::uint32_t value) { - return (value & std::uint32_t(0x000000FF)) << 24 | - (value & std::uint32_t(0x0000FF00)) << 8 | + return (value & std::uint32_t(0x000000FF)) << 24 | + (value & std::uint32_t(0x0000FF00)) << 8 | (value & std::uint32_t(0x00FF0000)) >> 8 | (value & std::uint32_t(0xFF000000)) >> 24; } // end function ReverseBytesUInt32 @@ -81,7 +81,7 @@ namespace CommonToolkit { return std::int32_t(std::uint32_t(std::uint32_t(std::uint32_t(value) >> (ShiftBits & 31)) | (std::uint32_t(std::int32_t(std::uint32_t(0 - std::uint32_t(std::uint32_t(value) >> 31)) & - std::uint32_t(std::int32_t(0 - (bool((ShiftBits & 31) != 0)))))) << (32 - (ShiftBits & 31))))); + std::uint32_t(std::int32_t(0 - (bool((ShiftBits & 31) != 0)))))) << (32 - (ShiftBits & 31))))); } // end function Asr32 //Arithmetic bit-shift 64 @@ -190,8 +190,8 @@ namespace CommonToolkit lsource_block += 1; destination_pointer_index += 1; - } // end while - } // end else + } // end while + } // end else } // end function swap_copy_to_u64 static std::uint32_t be2me_32(const std::uint32_t number) @@ -254,7 +254,7 @@ namespace CommonToolkit destination_pointer_index, data_size ); - } // end if + } // end if else { if(destination_pointer == nullptr || source_pointer == nullptr) @@ -292,10 +292,10 @@ namespace CommonToolkit destination_pointer_index, data_size ); - } // end if + } // end if else { - + if(destination_pointer == nullptr || source_pointer == nullptr) my_cpp2020_assert(false, "", std::source_location::current()); @@ -331,7 +331,7 @@ namespace CommonToolkit destination_pointer_index, data_size ); - } // end if + } // end if else { if(destination_pointer == nullptr || source_pointer == nullptr) @@ -369,7 +369,7 @@ namespace CommonToolkit destination_pointer_index, data_size ); - } // end if + } // end if else { if(destination_pointer == nullptr || source_pointer == nullptr) @@ -431,7 +431,7 @@ namespace CommonToolkit } #if defined( BYTE_SWAP_FUNCTON ) && __cplusplus >= 202002L - + /* Reference source code: https://gist.github.com/raidoz/4163b8ec6672aabb0656b96692af5e33 cross-platform / cross-compiler standalone endianness conversion @@ -440,8 +440,7 @@ namespace CommonToolkit { namespace Implementation { - /* C */ - extern "C" inline unsigned short __cdecl _builtin_byteswap_uint16(const unsigned short value) + inline std::uint16_t _builtin_byteswap_uint16(const std::uint16_t& value) { unsigned short other_value = 0; other_value = (value << 8); @@ -449,8 +448,7 @@ namespace CommonToolkit return other_value; } - /* C */ - extern "C" inline unsigned int __cdecl _builtin_byteswap_uint32(const unsigned int value) + inline std::uint32_t _builtin_byteswap_uint32(const std::uint32_t& value) { unsigned int other_value = 0; other_value = (value << 24); @@ -460,8 +458,7 @@ namespace CommonToolkit return other_value; } - /* C */ - extern "C" inline unsigned long long __cdecl _builtin_byteswap_uint64(const unsigned long long value) + inline std::uint64_t _builtin_byteswap_uint64(const std::uint64_t& value) { unsigned long long other_value = 0; other_value = (value << 56); @@ -476,7 +473,7 @@ namespace CommonToolkit } //! C++ Byte-swap 16-bit unsigned short - [[nodiscard]] static inline constexpr unsigned short Byteswap(const unsigned short ByteValue) noexcept + [[nodiscard]] static inline constexpr std::uint16_t Byteswap(const std::uint16_t& ByteValue) noexcept { if (std::is_constant_evaluated()) { @@ -495,10 +492,10 @@ namespace CommonToolkit return _builtin_byteswap_uint16(ByteValue); } } - - //Type unsigned long equal to type unsigned int + + //Type unsigned long equal to type unsigned int //! C++ Byte-swap 32-bit unsigned int - [[nodiscard]] static inline constexpr unsigned int Byteswap(const unsigned int ByteValue) noexcept + [[nodiscard]] static inline constexpr std::uint32_t Byteswap(const std::uint32_t& ByteValue) noexcept { if (std::is_constant_evaluated()) { @@ -522,7 +519,7 @@ namespace CommonToolkit } //! C++ Byte-swap 64-bit unsigned long long - [[nodiscard]] static inline constexpr unsigned long long Byteswap(const unsigned long long ByteValue) noexcept + [[nodiscard]] static inline constexpr std::uint64_t Byteswap(const std::uint64_t& ByteValue) noexcept { if (std::is_constant_evaluated()) { @@ -595,7 +592,7 @@ namespace CommonToolkit #endif } } - + template requires std::is_integral_v [[nodiscard]] constexpr Type byteswap(const Type ByteValue) noexcept { @@ -607,15 +604,15 @@ namespace CommonToolkit } else if constexpr (sizeof(ThisType) == 2) { - return static_cast(Implementation::Byteswap(static_cast(ByteValue))); + return static_cast(Implementation::Byteswap(static_cast(ByteValue))); } else if constexpr (sizeof(ThisType) == 4) { - return static_cast(Implementation::Byteswap(static_cast(ByteValue))); + return static_cast(Implementation::Byteswap(static_cast(ByteValue))); } else if constexpr (sizeof(ThisType) == 8) { - return static_cast(Implementation::Byteswap(static_cast(ByteValue))); + return static_cast(Implementation::Byteswap(static_cast(ByteValue))); } else if constexpr (std::same_as) { @@ -823,15 +820,15 @@ namespace CommonToolkit }; /* - + Example Code: - + std::deque Word; unsigned int InputWord = 0; unsigned int OutputWord = 0; std::vector bytes - { + { static_cast(Word.operator[](0)), static_cast(Word.operator[](1)), static_cast(Word.operator[](2)), @@ -857,7 +854,7 @@ namespace CommonToolkit bytes.clear(); words.clear(); - + */ template @@ -895,7 +892,7 @@ namespace CommonToolkit *output++ = ByteSwap::byteswap(value); - #endif + #endif } } else @@ -956,7 +953,7 @@ namespace CommonToolkit } /* - + Example Code: std::deque Word; @@ -964,7 +961,7 @@ namespace CommonToolkit unsigned int InputWord = 0; unsigned int OutputWord = 0; std::vector bytes - { + { static_cast(Word.operator[](0)), static_cast(Word.operator[](1)), static_cast(Word.operator[](2)), @@ -990,7 +987,7 @@ namespace CommonToolkit bytes.clear(); words.clear(); - + */ template @@ -1010,7 +1007,7 @@ namespace CommonToolkit { // intentional copy for (IntegerType value : input) - { + { #if __cpp_lib_byteswap value = std::byteswap(value); diff --git a/include/CommonToolkit/CPP2020_Concept.hpp b/include/CommonToolkit/CPP2020_Concept.hpp index 7045237..ec1b6e4 100644 --- a/include/CommonToolkit/CPP2020_Concept.hpp +++ b/include/CommonToolkit/CPP2020_Concept.hpp @@ -8,7 +8,7 @@ * 发布 TDOM-EncryptOrDecryptFile-Reborn 是希望它能有用,但是并无保障;甚至连可销售和符合某个特定的目的都不保证。请参看 GNU 通用公共许可证,了解详情。 * 你应该随程序获得一份 GNU 通用公共许可证的复本。如果没有,请看 。 */ - + /* * Copyright (C) 2021-2022 Twilight-Dream * @@ -129,10 +129,10 @@ namespace EODF_Reborn_CommonToolkit concept IsTypeFromBaseClass = std::is_base_of_v< BaseClassType, DerivedClassType >; template < typename DataType > - concept IsSimpleType = std::is_arithmetic_v< DataType > || std::is_enum_v< DataType > || std::is_class_v< DataType > || std::is_union_v< DataType > || std::is_reference_v< DataType > && !std::is_null_pointer_v< DataType > && !std::is_array_v< DataType >; + concept IsSimpleType = std::is_arithmetic_v< DataType > || std::is_enum_v< DataType > || std::is_class_v< DataType > || std::is_union_v< DataType > || std::is_reference_v< DataType > && ( !std::is_null_pointer_v< DataType > ) && ( !std::is_array_v< DataType > ); template < typename DataType, typename ReferenceType, typename PointerType > - concept IsCustomIteratorType = IsSimpleType< DataType > && std::is_reference_v< ReferenceType > &&( std::is_pointer_v< PointerType > || std::is_member_pointer_v< PointerType > && !std::is_null_pointer_v< PointerType > ); + concept IsCustomIteratorType = IsSimpleType< DataType > && std::is_reference_v< ReferenceType > &&( std::is_pointer_v< PointerType > || std::is_member_pointer_v< PointerType > && ( !std::is_null_pointer_v< PointerType > ) ); template concept IsKeyValueMapType = std::same_as>; @@ -140,4 +140,4 @@ namespace EODF_Reborn_CommonToolkit } // namespace CPP2020_Concepts } // namespace EODF_Reborn_CommonToolkit -#endif \ No newline at end of file +#endif diff --git a/include/CommonToolkit/CommonToolkit.hpp b/include/CommonToolkit/CommonToolkit.hpp index 2716435..387485e 100644 --- a/include/CommonToolkit/CommonToolkit.hpp +++ b/include/CommonToolkit/CommonToolkit.hpp @@ -8,7 +8,7 @@ * 发布 TDOM-EncryptOrDecryptFile-Reborn 是希望它能有用,但是并无保障;甚至连可销售和符合某个特定的目的都不保证。请参看 GNU 通用公共许可证,了解详情。 * 你应该随程序获得一份 GNU 通用公共许可证的复本。如果没有,请看 。 */ - + /* * Copyright (C) 2021-2022 Twilight-Dream * @@ -66,8 +66,13 @@ inline std::wstring string2wstring(const std::string& _string) std::size_t target_wstring_count = source_string_count + (found_not_ascii_count / 2); wide_character_buffer.resize(target_wstring_count); + + #if defined(_MSC_VER) std::size_t _converted_count = 0; ::mbstowcs_s(&_converted_count, &wide_character_buffer[0], target_wstring_count, _string.c_str(), ((size_t)-1)); + #else + ::mbstowcs(&wide_character_buffer[0], _string.c_str(), target_wstring_count); + #endif std::size_t _target_wstring_size = 0; for(auto begin = wide_character_buffer.begin(), end = wide_character_buffer.end(); begin != end && *begin != L'\0'; begin++) @@ -76,37 +81,38 @@ inline std::wstring string2wstring(const std::string& _string) } std::wstring _wstring{ wide_character_buffer.data(), _target_wstring_size }; + #if defined(_MSC_VER) if(_converted_count == 0) { throw std::runtime_error("The function string2wstring is not work !"); } + #endif + + if(found_not_ascii_count > 0) + { + //Need Contains character('\0') then check size + if(((_target_wstring_size + 1) - source_string_count) != (found_not_ascii_count / 2)) + { + throw std::runtime_error("The function string2wstring, An error occurs during conversion !"); + } + else + { + return _wstring; + } + } else { - if(found_not_ascii_count > 0) + //Need Contains character('\0') then check size + if((_target_wstring_size + 1) != source_string_count) { - //Need Contains character('\0') then check size - if(((_target_wstring_size + 1) - source_string_count) != (found_not_ascii_count / 2)) - { - throw std::runtime_error("The function string2wstring, An error occurs during conversion !"); - } - else - { - return _wstring; - } + throw std::runtime_error("The function string2wstring, An error occurs during conversion !"); } else { - //Need Contains character('\0') then check size - if((_target_wstring_size + 1) != source_string_count) - { - throw std::runtime_error("The function string2wstring, An error occurs during conversion !"); - } - else - { - return _wstring; - } + return _wstring; } } + } inline std::string wstring2string(const std::wstring& _wstring) @@ -126,11 +132,16 @@ inline std::string wstring2string(const std::wstring& _wstring) ++found_not_ascii_count; } } - std::size_t target_string_count = source_wstring_count + found_not_ascii_count * 2; + std::size_t target_string_count = source_wstring_count + found_not_ascii_count * 2; character_buffer.resize(target_string_count); - ::size_t _converted_count = 0; + + #if defined(_MSC_VER) + std::size_t _converted_count = 0; ::wcstombs_s(&_converted_count, &character_buffer[0], target_string_count, _wstring.c_str(), ((size_t)-1)); + #else + ::wcstombs(&character_buffer[0], _wstring.c_str(), target_string_count); + #endif std::size_t _target_string_size = 0; for(auto begin = character_buffer.begin(), end = character_buffer.end(); begin != end && *begin != '\0'; begin++) @@ -139,33 +150,33 @@ inline std::string wstring2string(const std::wstring& _wstring) } std::string _string{ character_buffer.data(), _target_string_size }; + #if defined(_MSC_VER) if(_converted_count == 0) { throw std::runtime_error("The function wstring2string is not work !"); } + #endif + + if(found_not_ascii_count > 0) + { + if(((_target_string_size + 1) - source_wstring_count) != (found_not_ascii_count * 2)) + { + throw std::runtime_error("The function wstring2string, An error occurs during conversion !"); + } + else + { + return _string; + } + } else { - if(found_not_ascii_count > 0) + if((_target_string_size + 1) != source_wstring_count) { - if(((_target_string_size + 1) - source_wstring_count) != (found_not_ascii_count * 2)) - { - throw std::runtime_error("The function wstring2string, An error occurs during conversion !"); - } - else - { - return _string; - } + throw std::runtime_error("The function wstring2string, An error occurs during conversion !"); } else { - if((_target_string_size + 1) != source_wstring_count) - { - throw std::runtime_error("The function wstring2string, An error occurs during conversion !"); - } - else - { - return _string; - } + return _string; } } } @@ -242,7 +253,7 @@ namespace CommonToolkit while (first != last) { *first++ = value; - + if constexpr(is_increment_or_decrement) { if(value + 1 == std::numeric_limits::min()) @@ -274,10 +285,10 @@ namespace CommonToolkit *first = value; first++; - + */ *first++ = value; - + if constexpr(is_increment_or_decrement) { //AdditionOverflows @@ -309,7 +320,7 @@ namespace CommonToolkit *first = value; first--; - + */ *first-- = value; @@ -393,13 +404,13 @@ namespace CommonToolkit template concept IsClassObjectComparerType = _Half_part_of_class_object_comparer && IsArithmeticDifferencesComparableType; - + #if defined(__cpp_lib_char8_t) inline std::string from_u8string(const char8_t* utf8_string_data, std::size_t size) { std::u8string value = std::u8string(utf8_string_data, size); - + #if __cplusplus >= 202002L return std::string(std::bit_cast(&value), size); #else @@ -600,7 +611,7 @@ namespace CommonToolkit constexpr bool output_range_is_array_class_type = IsArrayClassType(); constexpr bool output_sub_range_is_array_class_type = IsArrayClassType(); - if constexpr( input_range_is_array_class_type || output_range_is_array_class_type || output_sub_range_is_array_class_type && !is_key_value_range ) + if constexpr( input_range_is_array_class_type || output_range_is_array_class_type || output_sub_range_is_array_class_type && ( !is_key_value_range ) ) { auto beginIterator = std::ranges::begin( this_output_range ); auto endIterator = std::ranges::end( this_output_range ); @@ -622,7 +633,7 @@ namespace CommonToolkit }*/ std::ranges::advance( range_beginIterator, offsetCount ); - + if( beginIterator != endIterator ) std::ranges::advance( beginIterator, 1 ); } @@ -651,7 +662,7 @@ namespace CommonToolkit { auto offsetCount = std::min( partition_size, static_cast( std::ranges::distance( range_beginIterator, range_endIterator ) ) ); output_subrange_value_t sub_range_container( range_beginIterator, range_beginIterator + offsetCount ); - + if constexpr ( is_key_value_range ) { this_output_range.emplace_hint( this_output_range.end(), std::move( sub_range_container ) ); @@ -869,7 +880,7 @@ inline int CatchErrorCode( const std::error_code& error_code_object ) inline void AnalysisErrorCode( const std::error_code& error_code_object ) { const int error_code_number = error_code_object.value(); - + #if 0 if(error_code_number != 0) @@ -878,7 +889,7 @@ inline void AnalysisErrorCode( const std::error_code& error_code_object ) std::cout << CommonToolkit::from_u8string(u8"发生错误,已获得标准系统错误代码,代码为:") << error_code_number << ", 中止..." << std::endl; std::cout << "Error occurred, Standard system error codes have been obtained, code is: " << error_code_number << ", aborting..." << std::endl; std::cout << CommonToolkit::from_u8string(u8"The error message is(错误消息是): ") << error_message << std::endl; - + throw std::system_error(error_code_object); } @@ -890,11 +901,11 @@ inline void AnalysisErrorCode( const std::error_code& error_code_object ) std::cout << CommonToolkit::from_wstring(L"发生错误,已获得标准系统错误代码,代码为:") << error_code_number << CommonToolkit::from_wstring(L", 中止...") << std::endl; std::cout << "Error occurred, Standard system error codes have been obtained, code is: " << error_code_number << ", aborting..." << std::endl; std::cout << CommonToolkit::from_wstring(L"The error message is(错误消息是): ") << error_message << std::endl; - + throw std::system_error(error_code_object); } #endif } -#endif // !COMMON_TOOLKIT_HPP \ No newline at end of file +#endif // !COMMON_TOOLKIT_HPP diff --git a/include/CustomSecurity/ByteSubstitutionBoxToolkit.hpp b/include/CustomSecurity/ByteSubstitutionBoxToolkit.hpp index 9e5dc4d..d82b163 100644 --- a/include/CustomSecurity/ByteSubstitutionBoxToolkit.hpp +++ b/include/CustomSecurity/ByteSubstitutionBoxToolkit.hpp @@ -1268,19 +1268,19 @@ namespace CustomSecurity::ByteSubstitutionBoxToolkit AutoFloatingType ComputeTransparencyOrderFastVersion() { AutoFloatingType answer = 0.0f; - AutoFloatingType temporary_value = 0.0f, sigma_value = 0.0f, sigma2_value = 0.0f, treshold_value = 0.0f; + AutoFloatingType temporary_value = 0.0f, sigma_value = 0.0f, sigma2_value = 0.0f, threshold_value = 0.0f; AutoFloatingType AdderNumbersOfSigma2 = 0.0f; AutoFloatingType DifferenceValue = static_cast( ( 1 << (2 * OutputPowerOfTwo) ) - Shift_OutputSize ); AutoFloatingType MultiplicationProduct = static_cast(OutputPowerOfTwo * Shift_OutputSize); for(std::uint32_t index_b = 0; index_b < Shift_OutputSize; ++index_b) { - treshold_value = static_cast(OutputPowerOfTwo - 2 * HammingWeightArray[index_b]); - if(treshold_value < 0) - treshold_value *= (-1.0f); - treshold_value = (treshold_value - answer) * DifferenceValue; + threshold_value = static_cast(OutputPowerOfTwo - 2 * HammingWeightArray[index_b]); + if(threshold_value < 0) + threshold_value *= (-1.0f); + threshold_value = (threshold_value - answer) * DifferenceValue; - if(treshold_value >= 0) + if(threshold_value >= 0) { sigma2_value = 0.0f; for(std::uint32_t index_a = 1; index_a < Shift_OutputSize; ++index_a) @@ -1292,9 +1292,9 @@ namespace CustomSecurity::ByteSubstitutionBoxToolkit } AdderNumbersOfSigma2 = MultiplicationProduct - 2 * sigma_value; - if(sigma_value > treshold_value) + if(sigma_value > threshold_value) break; - temporary_value = treshold_value - (sigma_value / DifferenceValue); + temporary_value = threshold_value - (sigma_value / DifferenceValue); if(AdderNumbersOfSigma2 < 0) AdderNumbersOfSigma2 *= (-1.0f); diff --git a/include/CustomSecurity/CrypticDataThreadingWrapper.hpp b/include/CustomSecurity/CrypticDataThreadingWrapper.hpp index 88511f1..6ec93fc 100644 --- a/include/CustomSecurity/CrypticDataThreadingWrapper.hpp +++ b/include/CustomSecurity/CrypticDataThreadingWrapper.hpp @@ -32,14 +32,14 @@ namespace CrypticDataThreadingWrapper private: struct TaskStatusData { - std::vector _Status_Key; - std::size_t _Status_FileBiockSize; - std::size_t _Status_FileDataOffest; + std::vector _Status_SymmetricSecretKey_; + std::size_t _Status_FileBiockSize_; + std::size_t _Status_FileDataOffest_; TaskStatusData(std::vector& key, std::size_t FileBiockSize, std::size_t FileWhere) { - _Status_Key = key; - _Status_FileBiockSize = FileBiockSize; - _Status_FileDataOffest = FileWhere; + _Status_SymmetricSecretKey_ = key; + _Status_FileBiockSize_ = FileBiockSize; + _Status_FileDataOffest_ = FileWhere; } }; @@ -48,48 +48,58 @@ namespace CrypticDataThreadingWrapper ( std::deque>& key, const std::filesystem::path inputFileName, const std::filesystem::path outputFileName, - std::size_t fileSize, + std::size_t fileByteSize, const Cryptograph::CommonModule::CryptionMode2MCAC4_FDW choiseWorker, - std::size_t planRunThread = 128, std::size_t fileBlock_MetaByteSizeCount = 8 + std::size_t planRunThread = 128, std::size_t fileBlock_NumberOfMegaByteSize = 8 ) + : + _SymmetricSecretKeyData_(key), _InputFileName_(inputFileName), _OutputFileName_(outputFileName), + _FileByteSize_(fileByteSize), _ChoiseWorkerMode_(choiseWorker) { - _Key = key; - _InputFileName = inputFileName; - _OutputFileName = outputFileName; - _FileSize = fileSize; - _OneFileBlock_MegaByteSize = 1024 * 16; - _ChoiseWorker = choiseWorker; - switch (_ChoiseWorker) + _OneFileBlock_MegaByteSize_ = 1024 * 16; //16 Mega byte + + auto CheckFileByteSize = std::filesystem::file_size(_InputFileName_); + _FileByteSize_ = ( fileByteSize == CheckFileByteSize ? fileByteSize : CheckFileByteSize ); + + //在加密模式:大小是 OneFileBlock *= 64 + //在解密模式:大小是 OneFileBlock *= 65 + //In encrypted mode: size is OneFileBlock *= 64 + //In decryption mode: size is OneFileBlock *= 65 + switch (_ChoiseWorkerMode_) { case Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_ENCRYPTER: - _OneFileBlock_MegaByteSize = _OneFileBlock_MegaByteSize * 64; + _OneFileBlock_MegaByteSize_ *= 64; break; case Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_DECRYPTER: - _OneFileBlock_MegaByteSize = _OneFileBlock_MegaByteSize * 65; + _OneFileBlock_MegaByteSize_ *= 65; break; } if(planRunThread <= std::thread::hardware_concurrency() / 2) { - _PlanRunThread = planRunThread; + _RunThreadTaskCount_ = planRunThread; } else { - _PlanRunThread = planRunThread / 4; + _RunThreadTaskCount_ = planRunThread / 4; } - _EachFileBlock_MegaByteSize = _OneFileBlock_MegaByteSize * fileBlock_MetaByteSizeCount; + //The fileBlock_MegaByteSizeOfCount default value is 8 + //If you change it when you use encryption, you also need to change it when you use decryption + //fileBlock_NumberOfMegaByteSize的默认值是8 + //如果在使用加密的时候改动了它,那么在使用解密的时候也需要改动它 + _EachFileBlock_MegaByteSize_ = _OneFileBlock_MegaByteSize_ * fileBlock_NumberOfMegaByteSize; } ~FileDataHelper() { - if (push_future.joinable()) + if (push_future_thread.joinable()) { - push_future.join(); + push_future_thread.join(); } - if (pop_future.joinable()) + if (pop_future_thread.joinable()) { - pop_future.join(); + pop_future_thread.join(); } } @@ -102,30 +112,34 @@ namespace CrypticDataThreadingWrapper FileDataHelper(FileDataHelper& _object) = delete; protected: - std::thread push_future; - std::thread pop_future; - std::atomic is_push_done = false; - std::atomic is_pop_done = false; - std::atomic ThreadCount = 0; + std::thread push_future_thread; + std::thread pop_future_thread; + //是否完成了处理操作 + //Whether the processing operation is completed + std::atomic is_processing_operation_done = false; + std::atomic CurrentThreadTaskCount = 0; std::deque TasksStatusDataDeque; - std::deque> _Key; - std::deque>> _FileData; + std::deque> _SymmetricSecretKeyData_; + std::deque>> _FileDataWithAsyncDeque_; private: - - //1024 * 16 解密*65/加密*64 - std::size_t _OneFileBlock_MegaByteSize; - Cryptograph::CommonModule::CryptionMode2MCAC4_FDW _ChoiseWorker; - std::filesystem::path _InputFileName; - std::filesystem::path _OutputFileName; - std::size_t _FileSize; - //256 - std::size_t _PlanRunThread; + const std::filesystem::path _InputFileName_; + const std::filesystem::path _OutputFileName_; + + //The size of a block of the file with mega bytes + //文件的一个分块大小,以Mega字节为单位 + std::size_t _OneFileBlock_MegaByteSize_; + Cryptograph::CommonModule::CryptionMode2MCAC4_FDW _ChoiseWorkerMode_; + std::size_t _FileByteSize_; - //8 MetaByte, 如果加密的时候需要改动,解密的时候也一样需要改动 - std::size_t _EachFileBlock_MegaByteSize; + //Maybe this value can be 256? + //Number of tasks planned to run threads + //计划运行线程的任务数 + std::size_t _RunThreadTaskCount_; + + std::size_t _EachFileBlock_MegaByteSize_; private: void before_run(); @@ -138,132 +152,126 @@ namespace CrypticDataThreadingWrapper inline void FileDataHelper::before_run() { - unsigned long filesize = std::filesystem::file_size(_InputFileName); - unsigned long fileWhereOffset = 0; - auto iterator_key = _Key.begin(); + std::size_t fileSize = _FileByteSize_; + std::size_t fileWhereOffset = 0; + auto iterator_key = _SymmetricSecretKeyData_.begin(); - while ( filesize > _EachFileBlock_MegaByteSize) + while ( fileSize > _EachFileBlock_MegaByteSize_) { - if (iterator_key == _Key.end()) + if (iterator_key == _SymmetricSecretKeyData_.end()) { - iterator_key = _Key.begin(); + iterator_key = _SymmetricSecretKeyData_.begin(); } TasksStatusDataDeque.push_back ( - TaskStatusData { *iterator_key, _EachFileBlock_MegaByteSize, fileWhereOffset } + TaskStatusData { *iterator_key, _EachFileBlock_MegaByteSize_, fileWhereOffset } ); - filesize = filesize - _EachFileBlock_MegaByteSize; - fileWhereOffset += _EachFileBlock_MegaByteSize; + fileSize -= _EachFileBlock_MegaByteSize_; + fileWhereOffset += _EachFileBlock_MegaByteSize_; ++iterator_key; } - iterator_key = _Key.begin(); + iterator_key = _SymmetricSecretKeyData_.begin(); TasksStatusDataDeque.push_back ( - TaskStatusData { *iterator_key ,filesize ,fileWhereOffset } + TaskStatusData { *iterator_key ,fileSize ,fileWhereOffset } ); - this->push_future = std::thread(&FileDataHelper::read_run, std::ref(*this)); - this->pop_future = std::thread(&FileDataHelper::write_run, std::ref(*this)); + this->push_future_thread = std::thread(&FileDataHelper::read_run, std::ref(*this)); + this->pop_future_thread = std::thread(&FileDataHelper::write_run, std::ref(*this)); } inline void FileDataHelper::read_run() { while (!TasksStatusDataDeque.empty()) { - if (ThreadCount.load() < _PlanRunThread) + if (CurrentThreadTaskCount.load() < _RunThreadTaskCount_) { - ++(this->ThreadCount); - _FileData.push_back(std::async(std::launch::async, &FileDataHelper::ThreadTask, std::ref(*this), TasksStatusDataDeque.front())); + ++(this->CurrentThreadTaskCount); + _FileDataWithAsyncDeque_.push_back( std::async(std::launch::async, &FileDataHelper::ThreadTask, std::ref(*this), TasksStatusDataDeque.front()) ); TasksStatusDataDeque.pop_front(); } } - is_push_done = true; + is_processing_operation_done = true; } inline void FileDataHelper::write_run() { std::ofstream ofs; + ofs.open(_OutputFileName_, std::ios::out | std::ios::binary); - ofs.open(_OutputFileName, std::ios::out | std::ios::binary); if (!ofs.is_open()) + my_cpp2020_assert(false, "Error when open to a output file: failed to access.", std::source_location::current()); + + if (_ChoiseWorkerMode_ == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_ENCRYPTER) { - std::runtime_error access_file_is_failed("Failed to access the output file !"); - throw access_file_is_failed; - } - if (_ChoiseWorker == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_ENCRYPTER) - { - std::vector Filedata; - while (!is_push_done) + std::vector fileData; + while (!is_processing_operation_done) { - if (!_FileData.empty()) + if (!_FileDataWithAsyncDeque_.empty()) { - Filedata = _FileData.front().get(); - ofs.write(Filedata.data(), Filedata.size()); - _FileData.pop_front(); + fileData = _FileDataWithAsyncDeque_.front().get(); + ofs.write(fileData.data(), fileData.size()); + _FileDataWithAsyncDeque_.pop_front(); } } - while (!_FileData.empty()) + while (!_FileDataWithAsyncDeque_.empty()) { - Filedata = _FileData.front().get(); - ofs.write(Filedata.data(), Filedata.size()); - _FileData.pop_front(); + fileData = _FileDataWithAsyncDeque_.front().get(); + ofs.write(fileData.data(), fileData.size()); + _FileDataWithAsyncDeque_.pop_front(); } } - else if (_ChoiseWorker == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_DECRYPTER) + else if (_ChoiseWorkerMode_ == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_DECRYPTER) { - std::vector Filedata; + std::vector fileData; std::streamsize writedCount = 0; - int AlignmentCount = _FileSize % 64; + int alignmentCount = _FileByteSize_ % 64; - while (!is_push_done) + while (!is_processing_operation_done) { - if (_FileData.size() > 1) + if (_FileDataWithAsyncDeque_.size() > 1) { - Filedata = _FileData.front().get(); + fileData = _FileDataWithAsyncDeque_.front().get(); - writedCount = ofs.rdbuf()->sputn(Filedata.data(), Filedata.size()); - if(writedCount != Filedata.size()) - { - std::runtime_error writing_file_has_been_error("Error while writing size a file !"); - throw writing_file_has_been_error; - } - _FileData.pop_front(); - } - } + writedCount = ofs.rdbuf()->sputn(fileData.data(), fileData.size()); - while (_FileData.size() > 1) - { - Filedata = _FileData.front().get(); + if(writedCount != fileData.size()) + my_cpp2020_assert(false, "Error when writing to a file: file data size does not match !", std::source_location::current()); - //ofs.write(Filedata.data(), Filedata.size()); - writedCount = ofs.rdbuf()->sputn(Filedata.data(), Filedata.size()); - if(writedCount != Filedata.size()) - { - std::runtime_error writing_file_has_been_error("Error while writing size a file !"); - throw writing_file_has_been_error; + _FileDataWithAsyncDeque_.pop_front(); } - _FileData.pop_front(); } - Filedata = _FileData.front().get(); - int index = 64 - AlignmentCount; - while (index--) + while (_FileDataWithAsyncDeque_.size() > 1) { - Filedata.pop_back(); + fileData = _FileDataWithAsyncDeque_.front().get(); + + //ofs.write(fileData.data(), fileData.size()); + writedCount = ofs.rdbuf()->sputn(fileData.data(), fileData.size()); + + if(writedCount != fileData.size()) + my_cpp2020_assert(false, "Error when writing to a file: file data size does not match !", std::source_location::current()); + + _FileDataWithAsyncDeque_.pop_front(); } + fileData = _FileDataWithAsyncDeque_.front().get(); - //ofs.write(Filedata.data(), Filedata.size()); - writedCount = ofs.rdbuf()->sputn(Filedata.data(), Filedata.size()); - if(writedCount != Filedata.size()) + unsigned int filePaddedByteDataSize = 64 - alignmentCount; + while (--filePaddedByteDataSize) { - std::runtime_error writing_file_has_been_error("Error while writing size a file !"); - throw writing_file_has_been_error; + fileData.pop_back(); } + + //ofs.write(fileData.data(), fileData.size()); + writedCount = ofs.rdbuf()->sputn(fileData.data(), fileData.size()); + + if(writedCount != fileData.size()) + my_cpp2020_assert(false, "Error when writing to a file: file data size does not match !", std::source_location::current()); } else { @@ -275,66 +283,63 @@ namespace CrypticDataThreadingWrapper inline std::vector FileDataHelper::ThreadTask(TaskStatusData taskStatusData) { - std::vector Filedata; + std::vector fileData; std::streamsize readedCount = 0; - //Filedata.reserve(task_data.m_FileBiockSize); - Filedata.resize(taskStatusData._Status_FileBiockSize); + //fileData.reserve(taskStatusData._Status_FileBiockSize_); + fileData.resize(taskStatusData._Status_FileBiockSize_); + std::ifstream ifs; + ifs.open(_InputFileName_, std::ios::in | std::ios::binary); - ifs.open(_InputFileName, std::ios::in | std::ios::binary); if (!ifs.is_open()) { - std::runtime_error access_file_is_failed("Failed to access the input file !"); - throw access_file_is_failed; + my_cpp2020_assert(false, "Error when open to a input file: failed to access.", std::source_location::current()); } else { - ifs.seekg(taskStatusData._Status_FileDataOffest); + ifs.seekg(taskStatusData._Status_FileDataOffest_); - //ifs.read(&Filedata[0], taskStatusData._Status_FileBiockSize); - readedCount = ifs.rdbuf()->sgetn(&Filedata[0], taskStatusData._Status_FileBiockSize); - if (readedCount != taskStatusData._Status_FileBiockSize) - { - std::runtime_error reading_file_has_been_error("Error while reading size a file !"); - throw reading_file_has_been_error; - } + //ifs.read(&fileData[0], taskStatusData._Status_FileBiockSize_); + readedCount = ifs.rdbuf()->sgetn(&fileData[0], taskStatusData._Status_FileBiockSize_); + ifs.close(); } - if (Filedata.size()!= taskStatusData._Status_FileBiockSize) - { - std::runtime_error corruption_occurs_data_by_encrypted("Corruption occurs after by data encryption !"); - throw corruption_occurs_data_by_encrypted; - } + if(readedCount != taskStatusData._Status_FileBiockSize_) + my_cpp2020_assert(false, "Error when reading to a file: file data size does not match !", std::source_location::current()); - std::size_t index; - switch (_ChoiseWorker) + std::size_t index = 0; + switch (_ChoiseWorkerMode_) { case Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_ENCRYPTER: { - index = taskStatusData._Status_FileBiockSize % 64; + if (fileData.size() != taskStatusData._Status_FileBiockSize_) + my_cpp2020_assert(false, "Error when operating data to a file: Corruption occurs after by data encryption !", std::source_location::current()); + + index = taskStatusData._Status_FileBiockSize_ % 64; + if (index != 0) { index = 64 - index; - CommonSecurity::RNG_Xoshiro::xoshiro256 RandomGeneraterByReallyTime(std::chrono::system_clock::now().time_since_epoch().count()); - CommonSecurity::ShufflingRangeDataDetails::UniformIntegerDistribution number_distribution(0, 255); + std::random_device HardwareRandomDevice; + CommonSecurity::RNG_Xoshiro::xoshiro256 RandomGeneraterBySecureSeed( CommonSecurity::GenerateSecureRandomNumberSeed( HardwareRandomDevice ) ); + CommonSecurity::ShufflingRangeDataDetails::UniformIntegerDistribution UniformDistribution(0, 255); while (index--) { - auto integer = static_cast(number_distribution(RandomGeneraterByReallyTime)); - char temporaryData{ static_cast(integer) }; - Filedata.push_back(temporaryData); + auto randomInteger = static_cast(UniformDistribution(RandomGeneraterBySecureSeed)); + char filePaddingByteData{ static_cast(randomInteger) }; + fileData.push_back(filePaddingByteData); } } break; } case Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_DECRYPTER: { - index = taskStatusData._Status_FileBiockSize % 65; + index = taskStatusData._Status_FileBiockSize_ % 65; + if (index != 0) - { - std::runtime_error corruption_occurs_data_by_decrypted("Corruption occurs after by data decryption !"); - throw corruption_occurs_data_by_decrypted; - } + my_cpp2020_assert(false, "Error when operating data to a file: Corruption occurs after by data decryption !", std::source_location::current()); + break; } default: @@ -345,24 +350,24 @@ namespace CrypticDataThreadingWrapper } } - if (_ChoiseWorker == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_ENCRYPTER) + /* + Use custom symmetric encryption and decryption algorithms: OaldresPuzzle-Cryptic 隐秘的奥尔德雷斯之谜 + 使用自定义的对称加密和解密算法:隐秘的奥尔德雷斯之谜 + */ + + if (_ChoiseWorkerMode_ == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_ENCRYPTER) { Cryptograph::Implementation::Encrypter custom_encrypter; - custom_encrypter.Main(Filedata, taskStatusData._Status_Key); + custom_encrypter.Main(fileData, taskStatusData._Status_SymmetricSecretKey_); } - else if (_ChoiseWorker == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_DECRYPTER) + else if (_ChoiseWorkerMode_ == Cryptograph::CommonModule::CryptionMode2MCAC4_FDW::MCA_DECRYPTER) { Cryptograph::Implementation::Decrypter custom_decrypter; - custom_decrypter.Main(Filedata, taskStatusData._Status_Key); - } - else - { - std::cout << "Wrong worker is selected" << std::endl; - abort(); + custom_decrypter.Main(fileData, taskStatusData._Status_SymmetricSecretKey_); } - --(this->ThreadCount); - return Filedata; + --(this->CurrentThreadTaskCount); + return fileData; } } // namespace CrypticDataThreadingWrapper diff --git a/include/CustomSecurity/CryptionWorker.hpp b/include/CustomSecurity/CryptionWorker.hpp index 55dc2ed..1855861 100644 --- a/include/CustomSecurity/CryptionWorker.hpp +++ b/include/CustomSecurity/CryptionWorker.hpp @@ -25,8 +25,11 @@ namespace Cryptograph::Implementation { /* - Implementation of Custom Encrypted Data Worker + Implementation of Custom Data Encrypting Worker 自定义加密数据工作器的实现 + + OaldresPuzzle-Cryptic + 隐秘的奥尔德雷斯之谜 */ class Encrypter { @@ -42,8 +45,10 @@ namespace Cryptograph::Implementation using namespace CommonSecurity; std::size_t PlainText_size = PlainText.size(); - std::byte temporaryBinaryPassword {default_binary_key}; + std::byte temporaryBinaryPassword { default_binary_key }; + Cryptograph::Encryption_Tools::Encryption Worker; + std::vector temporaryIndexSplited = CommonToolkit::make_vector(std::make_integer_sequence{}); for ( std::size_t datablock_size = 0; datablock_size < PlainText_size; datablock_size += 64 ) @@ -60,7 +65,7 @@ namespace Cryptograph::Implementation //随机置换 //Random Displacement - std::mt19937 pseudoRandomGenerator { static_cast( temporaryBinaryPassword ) }; + CommonSecurity::RNG_Xoshiro::xoshiro256 pseudoRandomGenerator { static_cast( temporaryBinaryPassword ^ Key[0] ) }; CommonSecurity::ShuffleRangeData( temporaryIndexSplited, pseudoRandomGenerator ); //第二次循环加密 @@ -88,12 +93,14 @@ namespace Cryptograph::Implementation std::size_t Remainder_64 = Data.size() & 63; std::size_t NeedPaddingCount = 63 - Remainder_64; - CommonSecurity::RNG_Xoshiro::xoshiro256 RandomGeneraterByReallyTime (std::chrono::system_clock::now().time_since_epoch().count()); - CommonSecurity::ShufflingRangeDataDetails::UniformIntegerDistribution number_distribution(0, 255); + + std::random_device HardwareRandomDevice; + std::mt19937 RandomGeneraterBySecureSeed ( CommonSecurity::GenerateSecureRandomNumberSeed(HardwareRandomDevice) ); + CommonSecurity::ShufflingRangeDataDetails::UniformIntegerDistribution UniformDistribution(0, 255); for (int loopCount = 0; loopCount < NeedPaddingCount; ++loopCount) { - auto integer = static_cast(number_distribution(RandomGeneraterByReallyTime)); + auto integer = static_cast( UniformDistribution(RandomGeneraterBySecureSeed) ); std::byte byteData{ static_cast(integer) }; temporaryBinaryData = byteData; Data.push_back(temporaryBinaryData); @@ -154,8 +161,11 @@ namespace Cryptograph::Implementation /* - Implementation of Custom Decrypted Data Worker + Implementation of Custom Data Decrypting Worker 自定义解密数据工作器的实现 + + OaldresPuzzle-Cryptic + 隐秘的奥尔德雷斯之谜 */ class Decrypter { @@ -170,10 +180,12 @@ namespace Cryptograph::Implementation { using namespace CommonSecurity; - std::byte temporaryBinaryPassword{default_binary_key}; - std::byte temporaryBinaryPassword2{default_binary_key}; + std::byte temporaryBinaryPassword{ default_binary_key }; + std::byte temporaryBinaryPassword2{ default_binary_key }; + Cryptograph::Encryption_Tools::Encryption MakeKey; Cryptograph::Decryption_Tools::Decryption Worker; + std::byte temporaryBinaryData; std::vector temporaryIndexSplited = CommonToolkit::make_vector(std::make_integer_sequence{}); @@ -191,7 +203,7 @@ namespace Cryptograph::Implementation //随机置换 //Random Displacement - std::mt19937 pseudoRandomGenerator { static_cast( temporaryBinaryPassword ) }; + CommonSecurity::RNG_Xoshiro::xoshiro256 pseudoRandomGenerator { static_cast( temporaryBinaryPassword ^ Key[0] ) }; CommonSecurity::ShuffleRangeData( temporaryIndexSplited, pseudoRandomGenerator ); //第一次循环解密 @@ -228,7 +240,7 @@ namespace Cryptograph::Implementation */ void UnpaddingData(std::vector& Data) const { - std::size_t count = std::to_integer(Data.back()); + std::size_t count = static_cast(Data.back()); Data.pop_back(); while (count--) { diff --git a/include/CustomSecurity/CustomCryption.hpp b/include/CustomSecurity/CustomCryption.hpp index 71a59ef..99e4b3e 100644 --- a/include/CustomSecurity/CustomCryption.hpp +++ b/include/CustomSecurity/CustomCryption.hpp @@ -294,7 +294,7 @@ namespace Cryptograph::CommonModule namespace Cryptograph::DataPermutation { //16进制字符串数据 - class HexadecimalStringCoder + struct HexadecimalStringCoder { // 数据置换函数 // @@ -302,39 +302,42 @@ namespace Cryptograph::DataPermutation // Parameters: Hexadecimal formated string std::string DataDisorder( const std::string& string_file_data ) { - if ( string_file_data.size() % 16 != 0 || string_file_data.empty() == true ) + std::string encoded = std::string( string_file_data ); + + if(string_file_data.size() < 2) { - return std::string(); + return encoded; } - std::string encoded = std::string( string_file_data ); + std::vector byte_array; + std::size_t accumulator = string_file_data.size(); - //运行循环次数 - //RTNOC (Run The Number Of Cycles) + for(const auto& character : string_file_data) + { + byte_array.push_back(character); + accumulator += static_cast(character); + } //正向置换加密 //Forward permutation encryption - for ( size_t round = 0, index = 0, RTNOC = encoded.size(); round < ( RTNOC / 2 ) && index < RTNOC; round += 16, index++ ) + std::size_t index = encoded.size() - 1; + while(index > 0) { - std::swap( encoded[ index ], encoded.at( round + 16 ) ); - std::swap( encoded[ index ], encoded.at( round + 8 ) ); - std::swap( encoded[ index ], encoded.at( round + 1 ) ); - std::swap( encoded[ index ], encoded.at( round + 9 ) ); - std::swap( encoded[ index ], encoded.at( round + 15 ) ); - std::swap( encoded[ index ], encoded.at( round + 7 ) ); - std::swap( encoded[ index ], encoded.at( round + 2 ) ); - std::swap( encoded[ index ], encoded.at( round + 10 ) ); - std::swap( encoded[ index ], encoded.at( round + 14 ) ); - std::swap( encoded[ index ], encoded.at( round + 6 ) ); - std::swap( encoded[ index ], encoded.at( round + 3 ) ); - std::swap( encoded[ index ], encoded.at( round + 11 ) ); - std::swap( encoded[ index ], encoded.at( round + 4 ) ); - std::swap( encoded[ index ], encoded.at( round + 12 ) ); - std::swap( encoded[ index ], encoded.at( round + 5 ) ); - std::swap( encoded[ index ], encoded.at( round + 13 ) ); + const std::size_t round_index = accumulator % (index + 1); + std::swap(byte_array[index], byte_array[round_index]); + --index; } - std::cout << "The file_string_data encode result is: " << encoded << std::endl; + encoded.clear(); + encoded.shrink_to_fit(); + for(auto& byte : byte_array) + { + encoded.push_back(static_cast(byte)); + } + + byte_array.clear(); + byte_array.shrink_to_fit(); + std::cout << "The string encode result is: " << encoded << std::endl; //Return ciphertext data return encoded; @@ -344,41 +347,44 @@ namespace Cryptograph::DataPermutation // // Return: Ordered hexadecimal formated string // Parameters: Disorded hexadecimal formated string - std::string DataOrder( std::string& string_file_data ) + std::string DataOrder( const std::string& string_file_data ) { - if ( string_file_data.size() % 16 != 0 || string_file_data.empty() == true ) + std::string decoded = std::string( string_file_data ); + + if(string_file_data.size() < 2) { - return std::string(); + return decoded; } - std::string decoded = std::string( string_file_data ); + std::vector byte_array; + std::size_t accumulator = string_file_data.size(); - //运行循环次数 - //RTNOC (Run The Number Of Cycles) + for(const auto& character : string_file_data) + { + byte_array.push_back(character); + accumulator += static_cast(character); + } //逆向置换解密 //Reverse permutation decryption - for ( size_t round = 0, index = 0, RTNOC = decoded.size(); round < ( RTNOC / 2 ) && index < RTNOC; round += 16, index++ ) + std::size_t index = 0; + while(index < decoded.size()) { - std::swap( decoded[ index ], decoded.at( round + 13 ) ); - std::swap( decoded[ index ], decoded.at( round + 5 ) ); - std::swap( decoded[ index ], decoded.at( round + 12 ) ); - std::swap( decoded[ index ], decoded.at( round + 4 ) ); - std::swap( decoded[ index ], decoded.at( round + 11 ) ); - std::swap( decoded[ index ], decoded.at( round + 3 ) ); - std::swap( decoded[ index ], decoded.at( round + 6 ) ); - std::swap( decoded[ index ], decoded.at( round + 14 ) ); - std::swap( decoded[ index ], decoded.at( round + 10 ) ); - std::swap( decoded[ index ], decoded.at( round + 2 ) ); - std::swap( decoded[ index ], decoded.at( round + 7 ) ); - std::swap( decoded[ index ], decoded.at( round + 15 ) ); - std::swap( decoded[ index ], decoded.at( round + 9 ) ); - std::swap( decoded[ index ], decoded.at( round + 1 ) ); - std::swap( decoded[ index ], decoded.at( round + 8 ) ); - std::swap( decoded[ index ], decoded.at( round + 16 ) ); + const std::size_t round_index = accumulator % (index + 1); + std::swap(byte_array[index], byte_array[round_index]); + ++index; } - std::cout << "The file_string_data decode result is: " << decoded << std::endl; + decoded.clear(); + decoded.shrink_to_fit(); + for(auto& byte : byte_array) + { + decoded.push_back(static_cast(byte)); + } + + byte_array.clear(); + byte_array.shrink_to_fit(); + std::cout << "The string decode result is: " << decoded << std::endl; //Return plaintext data return decoded; @@ -388,6 +394,13 @@ namespace Cryptograph::DataPermutation namespace Cryptograph::Encryption_Tools { + /* + @author Project Owner and Module Designer: Twilight-Dream + @author Algorithm Designer: Spiritual-Fish + + @brief OaldresPuzzle-Cryptic's Core - Symmetric Encryption Algorithm Implementation + @brief OaldresPuzzle-Cryptic的核心 - 对称加密算法实现 + */ class Encryption { @@ -469,6 +482,13 @@ namespace Cryptograph::Encryption_Tools namespace Cryptograph::Decryption_Tools { + /* + @author Project Owner and Module Designer: Twilight-Dream + @author Algorithm Designer: Spiritual-Fish + + @brief OaldresPuzzle-Cryptic's Core - Symmetric Decryption Algorithm Implementation + @brief OaldresPuzzle-Cryptic的核心 - 对称解密算法实现 + */ class Decryption { diff --git a/include/CustomSecurity/DataObfuscator.hpp b/include/CustomSecurity/DataObfuscator.hpp index 73e6e87..6c28425 100644 --- a/include/CustomSecurity/DataObfuscator.hpp +++ b/include/CustomSecurity/DataObfuscator.hpp @@ -1022,14 +1022,18 @@ namespace CustomSecurity::DataObfuscator auto random_number_c = random_number_distribution2(RandomNumberGenerator2); auto random_number_d = random_number_distribution2(RandomNumberGenerator2); - ThisAffineTransformationParameters.MultiplicationNumber = random_number_a ^= ( 1 << (random_number_c & 7)); + ThisAffineTransformationParameters.MultiplicationNumber = random_number_a ^= ( 1 << (random_number_c & 7)); ThisAffineTransformationParameters.MultiplicationNumber2 = random_number_b ^= ( 1 << (random_number_d & 7)); - ThisAffineTransformationParameters.AdditionNumber = random_number_c; - ThisAffineTransformationParameters.AdditionNumber2 = random_number_d; - // Multipliers number must have an odd number of set bits // 乘法器必须有奇数的设置位 + // Random_Number(0~255) -> MathTools::CheckParityBits() -> static_cast() -> Exclusive_OR 1 -> Exclusive_OR Random_Number + ThisAffineTransformationParameters.MultiplicationNumber ^= static_cast( MathTools::CheckParityBits(ThisAffineTransformationParameters.MultiplicationNumber) ) ^ 1; + ThisAffineTransformationParameters.MultiplicationNumber2 ^= static_cast( MathTools::CheckParityBits(ThisAffineTransformationParameters.MultiplicationNumber2) ) ^ 1; + + ThisAffineTransformationParameters.AdditionNumber = random_number_c; + ThisAffineTransformationParameters.AdditionNumber2 = random_number_d; + } while (!CheckThisAffineTransformationParameters()); std::uint32_t random_number = random_number_distribution(RandomNumberGenerator); @@ -1381,6 +1385,25 @@ namespace CustomSecurity::DataObfuscator return IsChangedData; } + CustomDataObfuscator + ( + bool UnlimitValue_GF_257 = false + ) + : ThisAffineTransformationParameters(UnlimitValue_GF_257) + { + auto& RandomNumberGenerator = *(PRNG_Pointer.get()); + auto& RandomNumberGenerator2 = *(PRNG_Pointer2.get()); + + std::random_device random_device_object; + + RandomNumberGenerator.seed( random_device_object ); + RandomNumberGenerator2.seed( random_device_object ); + + ShuffleThisAffineTransformationParameters(); + + BuildBox(); + } + CustomDataObfuscator ( std::size_t X_Seed, @@ -1870,14 +1893,18 @@ namespace CustomSecurity::DataObfuscator auto random_number_c = random_number_distribution2(RandomNumberGenerator2); auto random_number_d = random_number_distribution2(RandomNumberGenerator2); - ThisAffineTransformationParameters.MultiplicationNumber = random_number_a ^= ( 1 << (random_number_c & 7)); + ThisAffineTransformationParameters.MultiplicationNumber = random_number_a ^= ( 1 << (random_number_c & 7)); ThisAffineTransformationParameters.MultiplicationNumber2 = random_number_b ^= ( 1 << (random_number_d & 7)); - ThisAffineTransformationParameters.AdditionNumber = random_number_c; - ThisAffineTransformationParameters.AdditionNumber2 = random_number_d; - // Multipliers number must have an odd number of set bits // 乘法器必须有奇数的设置位 + // Random_Number(0~255) -> MathTools::CheckParityBits() -> static_cast() -> Exclusive_OR 1 -> Exclusive_OR Random_Number + ThisAffineTransformationParameters.MultiplicationNumber ^= static_cast( MathTools::CheckParityBits(ThisAffineTransformationParameters.MultiplicationNumber) ) ^ 1; + ThisAffineTransformationParameters.MultiplicationNumber2 ^= static_cast( MathTools::CheckParityBits(ThisAffineTransformationParameters.MultiplicationNumber2) ) ^ 1; + + ThisAffineTransformationParameters.AdditionNumber = random_number_c; + ThisAffineTransformationParameters.AdditionNumber2 = random_number_d; + } while (!CheckThisAffineTransformationParameters()); std::uint32_t random_number = random_number_distribution(RandomNumberGenerator); @@ -2238,6 +2265,25 @@ namespace CustomSecurity::DataObfuscator return IsChangedData; } + CustomDataObfuscator + ( + bool UnlimitValue_GF_257 = false + ) + : ThisAffineTransformationParameters(UnlimitValue_GF_257) + { + auto& RandomNumberGenerator = *(PRNG_Pointer.get()); + auto& RandomNumberGenerator2 = *(PRNG_Pointer2.get()); + + std::random_device random_device_object; + + RandomNumberGenerator.seed( random_device_object ); + RandomNumberGenerator2.seed( random_device_object ); + + ShuffleThisAffineTransformationParameters(); + + BuildBox(); + } + CustomDataObfuscator ( std::size_t X_Seed, diff --git a/include/FileProcessing/FileOperationNew.hpp b/include/FileProcessing/FileOperationNew.hpp index 072c17f..1ef3432 100644 --- a/include/FileProcessing/FileOperationNew.hpp +++ b/include/FileProcessing/FileOperationNew.hpp @@ -8,7 +8,7 @@ * 发布 TDOM-EncryptOrDecryptFile-Reborn 是希望它能有用,但是并无保障;甚至连可销售和符合某个特定的目的都不保证。请参看 GNU 通用公共许可证,了解详情。 * 你应该随程序获得一份 GNU 通用公共许可证的复本。如果没有,请看 。 */ - + /* * Copyright (C) 2021-2022 Twilight-Dream * @@ -122,9 +122,9 @@ namespace FileProcessing::Operation << "Current Thread ID: " << std::this_thread::get_id() << std::endl; auto dataTransmisionWithStartTime = std::chrono::system_clock::now(); - while (FDCM_Adapter_Pointer->allFileDataIsReaded.load( std::memory_order::memory_order_acquire ) == false) + while (FDCM_Adapter_Pointer->allFileDataIsReaded.load( std::memory_order_acquire ) == false) { - if(TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.load( std::memory_order::memory_order_acquire ) == false && TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.load( std::memory_order::memory_order_acquire ) == true) + if(TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.load( std::memory_order_acquire ) == false && TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.load( std::memory_order_acquire ) == true) { BugFix: @@ -149,23 +149,23 @@ namespace FileProcessing::Operation _fileDataByteSize += partElementSize; } - FDCM_Adapter_Pointer->fileDataByteReadedCount.store( _fileDataByteSize, std::memory_order::memory_order_relaxed ); + FDCM_Adapter_Pointer->fileDataByteReadedCount.store( _fileDataByteSize, std::memory_order_relaxed ); } - if(TaskStatusData_Pointer->bufferDataMap.empty() && TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.load( std::memory_order::memory_order_acquire ) == true && TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.load( std::memory_order::memory_order_acquire ) == false) + if(TaskStatusData_Pointer->bufferDataMap.empty() && TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.load( std::memory_order_acquire ) == true && TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.load( std::memory_order_acquire ) == false) { - TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.wait(true, std::memory_order::memory_order_seq_cst ); - TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.wait(false, std::memory_order::memory_order_seq_cst ); + TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.wait(true, std::memory_order_seq_cst ); + TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.wait(false, std::memory_order_seq_cst ); } - else if(FDCM_Adapter_Pointer->fileDataByteReadedCount.load( std::memory_order::memory_order_relaxed ) == FileDataByteSize) + else if(FDCM_Adapter_Pointer->fileDataByteReadedCount.load( std::memory_order_relaxed ) == FileDataByteSize) { - FDCM_Adapter_Pointer->allFileDataIsReaded.store( true, std::memory_order::memory_order_release ); + FDCM_Adapter_Pointer->allFileDataIsReaded.store( true, std::memory_order_release ); FDCM_Adapter_Pointer->allFileDataIsReaded.notify_all(); } - else if(!TaskStatusData_Pointer->bufferDataMap.empty() && TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.load( std::memory_order::memory_order_acquire ) == true && TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.load( std::memory_order::memory_order_acquire ) == false) + else if(!TaskStatusData_Pointer->bufferDataMap.empty() && TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.load( std::memory_order_acquire ) == true && TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.load( std::memory_order_acquire ) == false) { - TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.store( true, std::memory_order::memory_order_release ); - TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.store( false, std::memory_order::memory_order_release ); + TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.store( true, std::memory_order_release ); + TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.store( false, std::memory_order_release ); TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.notify_one(); TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.notify_one(); @@ -200,7 +200,7 @@ namespace FileProcessing::Operation try { - if( TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.load( std::memory_order::memory_order_acquire ) == true && TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.load( std::memory_order::memory_order_acquire ) == false ) + if( TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.load( std::memory_order_acquire ) == true && TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.load( std::memory_order_acquire ) == false ) { std::cout << "Note that the file is about to be read!\n" << "Current Thread ID: " << std::this_thread::get_id() << std::endl; @@ -240,12 +240,12 @@ namespace FileProcessing::Operation //对已经分裂的数据块,进行编号记录 //Numbered records for splited data blocks - std::pair> pairBufferDataNode = std::make_pair( TaskStatusData_Pointer->currentDataBlockNumber.load( std::memory_order::memory_order_acquire ), TaskStatusData_Pointer->bufferData ); + std::pair> pairBufferDataNode = std::make_pair( TaskStatusData_Pointer->currentDataBlockNumber.load( std::memory_order_acquire ), TaskStatusData_Pointer->bufferData ); TaskStatusData_Pointer->bufferDataMap.insert( std::move( pairBufferDataNode ) ); TaskStatusData_Pointer->currentDataBlockNumber += 1; std::vector().swap( TaskStatusData_Pointer->bufferData ); - TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.store( false, std::memory_order::memory_order_release ); + TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.store( false, std::memory_order_release ); if ( TaskStatusData_Pointer->bufferDataMap.size() == TaskStatusData_Pointer->filePartDataProcessingByTaskCount ) { @@ -360,9 +360,9 @@ namespace FileProcessing::Operation << "Current Thread ID: " << std::this_thread::get_id() << std::endl; auto dataTransmisionWithStartTime = std::chrono::system_clock::now(); - while (FDCM_Adapter_Pointer->allFileDataIsWrited.load( std::memory_order::memory_order_acquire ) == false) + while (FDCM_Adapter_Pointer->allFileDataIsWrited.load( std::memory_order_acquire ) == false) { - if(TaskStatusData_Pointer->bufferIsOccupiedWithMoving.load( std::memory_order::memory_order_acquire ) == true && TaskStatusData_Pointer->bufferIsOccupiedWithWriting.load( std::memory_order::memory_order_acquire ) == false) + if(TaskStatusData_Pointer->bufferIsOccupiedWithMoving.load( std::memory_order_acquire ) == true && TaskStatusData_Pointer->bufferIsOccupiedWithWriting.load( std::memory_order_acquire ) == false) { BugFix: @@ -408,7 +408,7 @@ namespace FileProcessing::Operation //对可能重分过的数据块,进行编号记录 //Numbered records of data blocks that may have been re-splited - std::pair> pairBufferDataNode = std::make_pair( TaskStatusData_Pointer->currentDataBlockGroupNumber.load( std::memory_order::memory_order_acquire ), std::move( temporaryBufferData ) ); + std::pair> pairBufferDataNode = std::make_pair( TaskStatusData_Pointer->currentDataBlockGroupNumber.load( std::memory_order_acquire ), std::move( temporaryBufferData ) ); TaskStatusData_Pointer->bufferDataMap.insert( std::move( pairBufferDataNode ) ); TaskStatusData_Pointer->currentDataBlockGroupNumber += 1; @@ -426,13 +426,13 @@ namespace FileProcessing::Operation if(TaskStatusData_Pointer->bufferDataBlockChain.empty() && TaskStatusData_Pointer->bufferDataMap.empty() && pointerWithFileDataBlockChain->empty()) { - TaskStatusData_Pointer->bufferIsOccupiedWithMoving.store( false, std::memory_order::memory_order_release ); - TaskStatusData_Pointer->bufferIsOccupiedWithWriting.store( true, std::memory_order::memory_order_release ); + TaskStatusData_Pointer->bufferIsOccupiedWithMoving.store( false, std::memory_order_release ); + TaskStatusData_Pointer->bufferIsOccupiedWithWriting.store( true, std::memory_order_release ); TaskStatusData_Pointer->bufferIsOccupiedWithMoving.notify_one(); TaskStatusData_Pointer->bufferIsOccupiedWithWriting.notify_one(); - FDCM_Adapter_Pointer->allFileDataIsWrited.wait( false, std::memory_order::memory_order_seq_cst ); + FDCM_Adapter_Pointer->allFileDataIsWrited.wait( false, std::memory_order_seq_cst ); } else { @@ -473,7 +473,7 @@ namespace FileProcessing::Operation } else { - if ( TaskStatusData_Pointer->bufferIsOccupiedWithMoving.load( std::memory_order::memory_order_acquire ) == false && TaskStatusData_Pointer->bufferIsOccupiedWithWriting.load( std::memory_order::memory_order_acquire ) == true ) + if ( TaskStatusData_Pointer->bufferIsOccupiedWithMoving.load( std::memory_order_acquire ) == false && TaskStatusData_Pointer->bufferIsOccupiedWithWriting.load( std::memory_order_acquire ) == true ) { std::cout << "Note that the file is about to be write!\n" << "Current Thread ID: " << std::this_thread::get_id() << std::endl; @@ -882,14 +882,14 @@ namespace FileProcessing::Operation { for(;;) { - if(TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.load( std::memory_order::memory_order_acquire ) == true && TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.load( std::memory_order::memory_order_acquire ) == false) + if(TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.load( std::memory_order_acquire ) == true && TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.load( std::memory_order_acquire ) == false) { break; } else if(TaskStatusData_Pointer->bufferDataMap.empty() && _filePointerPosition != fileDataByteSize) { - TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.store( true, std::memory_order::memory_order_release ); - TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.store( false, std::memory_order::memory_order_release ); + TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.store( true, std::memory_order_release ); + TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.store( false, std::memory_order_release ); TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.notify_one(); TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.notify_one(); @@ -937,8 +937,8 @@ namespace FileProcessing::Operation } } - TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.exchange( true, std::memory_order::memory_order_release ); - TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.exchange( false, std::memory_order::memory_order_release ); + TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.exchange( true, std::memory_order_release ); + TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.exchange( false, std::memory_order_release ); TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.notify_one(); TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.notify_one(); @@ -951,14 +951,14 @@ namespace FileProcessing::Operation if(TaskStatusData_Pointer != nullptr) { - TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.exchange( false, std::memory_order::memory_order_seq_cst ); - TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.exchange( true, std::memory_order::memory_order_seq_cst ); + TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.exchange( false, std::memory_order_seq_cst ); + TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.exchange( true, std::memory_order_seq_cst ); TaskStatusData_Pointer->bufferIsNotOccupiedWithMoving.notify_one(); TaskStatusData_Pointer->bufferIsNotOccupiedWithReading.notify_one(); } - FDCM_Adapter_Pointer->allFileDataIsReaded.wait( false, std::memory_order::memory_order_seq_cst ); + FDCM_Adapter_Pointer->allFileDataIsReaded.wait( false, std::memory_order_seq_cst ); return; } @@ -968,10 +968,10 @@ namespace FileProcessing::Operation //https://en.cppreference.com/w/cpp/experimental/future/is_ready //std::experimental::future::is_ready - + auto asyncTaskFurture_MovingBufferData = std::async(std::launch::async, lambda_MovingBufferData); - if ( FDCM_Adapter_Pointer->allFileDataIsReaded.load( std::memory_order::memory_order_acquire ) == false ) + if ( FDCM_Adapter_Pointer->allFileDataIsReaded.load( std::memory_order_acquire ) == false ) { ThreadingToolkit::Wrapper::AsyncTask_SyncWrapper( lambda_ReadingData ); asyncTaskFurture_MovingBufferData.get(); @@ -1006,7 +1006,7 @@ namespace FileProcessing::Operation 把当前线程的调用控制权立即转移给线程池对象(一个可等待的表达式), 等到线程池对象完全创建多个线程对象之后,由线程池Coroutine任务的等待器(自行实现), 立即转移它的调用控制权,恢复给当前线程所执行的函数。 - + About Coroutine's task functions, the co_await operator works: The function executed by the current thread is suspended by the Coroutine's task that transferring control of the current thread's invocation to a thread pool object ( the expression of awaitable) immediately @@ -1033,7 +1033,7 @@ namespace FileProcessing::Operation std::unique_ptr FS_Object = std::make_unique(); std::ofstream* FS_Object_Pointer = FS_Object.get(); - + //访问这个文件时,截断这个文件数据,不可恢复 //When accessing this file, the data of this file is truncated and cannot be recovered. FS_Object_Pointer->open( filePathName, std::ios::out |std::ios::trunc | std::ios::binary ); @@ -1060,23 +1060,23 @@ namespace FileProcessing::Operation WritingFileDataFlag: statusWriting = this->WritingFileData( TaskStatusData_Pointer.get(), FS_Object_Pointer, fileDataByteSize, _filePointerPosition ); - FDCM_Adapter_Pointer->fileDataByteWritedCount.store( _filePointerPosition, std::memory_order::memory_order_relaxed ); + FDCM_Adapter_Pointer->fileDataByteWritedCount.store( _filePointerPosition, std::memory_order_relaxed ); switch ( statusWriting ) { case FileProcessing::Operation::BinaryStreamWriter::WritingStatus::WRITING_WAIT_DATA_READY: { - + for(;;) { - if(TaskStatusData_Pointer->bufferIsOccupiedWithMoving.load( std::memory_order::memory_order_acquire ) == false && TaskStatusData_Pointer->bufferIsOccupiedWithWriting.load( std::memory_order::memory_order_acquire ) == true ) + if(TaskStatusData_Pointer->bufferIsOccupiedWithMoving.load( std::memory_order_acquire ) == false && TaskStatusData_Pointer->bufferIsOccupiedWithWriting.load( std::memory_order_acquire ) == true ) { break; } else if(TaskStatusData_Pointer->bufferDataBlockChain.empty() && !TaskStatusData_Pointer->bufferDataMap.empty() && _filePointerPosition != fileDataByteSize) { - TaskStatusData_Pointer->bufferIsOccupiedWithMoving.store( false, std::memory_order::memory_order_release ); - TaskStatusData_Pointer->bufferIsOccupiedWithWriting.store( true, std::memory_order::memory_order_release ); + TaskStatusData_Pointer->bufferIsOccupiedWithMoving.store( false, std::memory_order_release ); + TaskStatusData_Pointer->bufferIsOccupiedWithWriting.store( true, std::memory_order_release ); TaskStatusData_Pointer->bufferIsOccupiedWithMoving.notify_one(); TaskStatusData_Pointer->bufferIsOccupiedWithWriting.notify_one(); @@ -1122,13 +1122,13 @@ namespace FileProcessing::Operation if(TaskStatusData_Pointer != nullptr) { - TaskStatusData_Pointer->bufferIsOccupiedWithMoving.exchange( true, std::memory_order::memory_order_seq_cst ); - TaskStatusData_Pointer->bufferIsOccupiedWithWriting.exchange( false, std::memory_order::memory_order_seq_cst ); + TaskStatusData_Pointer->bufferIsOccupiedWithMoving.exchange( true, std::memory_order_seq_cst ); + TaskStatusData_Pointer->bufferIsOccupiedWithWriting.exchange( false, std::memory_order_seq_cst ); TaskStatusData_Pointer->bufferIsOccupiedWithMoving.notify_one(); TaskStatusData_Pointer->bufferIsOccupiedWithWriting.notify_one(); - FDCM_Adapter_Pointer->allFileDataIsWrited.exchange( true, std::memory_order::memory_order_seq_cst ); + FDCM_Adapter_Pointer->allFileDataIsWrited.exchange( true, std::memory_order_seq_cst ); FDCM_Adapter_Pointer->allFileDataIsWrited.notify_all(); } @@ -1148,7 +1148,7 @@ namespace FileProcessing::Operation auto asyncTaskFurture_WritingData = std::async(std::launch::async, lambda_WritingData); - if ( FDCM_Adapter_Pointer->allFileDataIsWrited.load( std::memory_order::memory_order_acquire ) == false ) + if ( FDCM_Adapter_Pointer->allFileDataIsWrited.load( std::memory_order_acquire ) == false ) { ThreadingToolkit::Wrapper::AsyncTask_SyncWrapper( lambda_MovingDataBlock ); @@ -1163,4 +1163,4 @@ namespace FileProcessing::Operation } // namespace FileProcessing::Operation -#endif \ No newline at end of file +#endif diff --git a/include/FileProcessing/FileProcessing.hpp b/include/FileProcessing/FileProcessing.hpp index 52b4e5f..66eef0f 100644 --- a/include/FileProcessing/FileProcessing.hpp +++ b/include/FileProcessing/FileProcessing.hpp @@ -8,7 +8,7 @@ * 发布 TDOM-EncryptOrDecryptFile-Reborn 是希望它能有用,但是并无保障;甚至连可销售和符合某个特定的目的都不保证。请参看 GNU 通用公共许可证,了解详情。 * 你应该随程序获得一份 GNU 通用公共许可证的复本。如果没有,请看 。 */ - + /* * Copyright (C) 2021-2022 Twilight-Dream * @@ -49,6 +49,8 @@ namespace FileProcessing //This file size std::size_t FileSize = 0; + #if defined(_WIN32) + //文件主要名 //This file main name std::wstring FileMainName; @@ -56,11 +58,23 @@ namespace FileProcessing //文件扩展名 //This file extension name std::wstring FileExtensionName; - + + #else + + //文件主要名 + //This file main name + std::string FileMainName; + + //文件扩展名 + //This file extension name + std::string FileExtensionName; + + #endif + //原文件哈希 //Hashing of original file data std::string FileDataHashedID; - + //文件压缩后数据的哈希 //Hashing of data after file compression std::string FileCompressdDataHashID = "NULL_HASH_ID"; @@ -68,19 +82,19 @@ namespace FileProcessing //原文件数据经过密码处理之后的哈希 //Hash of the original file data after cryptographic processing std::string FileProceesedDataHashID; - + //密码1的哈希数据() //The Password One Hash Data std::vector PasswordOneHashData; - + //密码2的哈希数据() //The Password Two Hash Data std::vector PasswordTwoHashData; - + //密码3的哈希数据() //The Password Three Hash Data std::vector PasswordThreeHashData; - + //密码4的哈希数据() //The Password Four Hash Data std::vector PasswordFourHashData; diff --git a/include/Support+Library/Support-Library.hpp b/include/Support+Library/Support-Library.hpp index 2611f46..4e3e8fb 100644 --- a/include/Support+Library/Support-Library.hpp +++ b/include/Support+Library/Support-Library.hpp @@ -22,8 +22,8 @@ #pragma once -#ifndef SUPPORT_LINRARY_HPP -#define SUPPORT_LINRARY_HPP +#ifndef SUPPORT_LIBRARY_HPP +#define SUPPORT_LIBRARY_HPP #include #include @@ -78,7 +78,7 @@ #include #include -//Multi-Threading-Devlopment-ISO-C++ Standard Libary +//Multi-Threading-Development-ISO-C++ Standard Library #include #include #include @@ -291,6 +291,8 @@ inline void operator delete[](void* pointer_with_array_value) static constexpr size_t CURRENT_SYSTEM_BITS = (std::numeric_limits::digits * sizeof(void*)); +#if __cplusplus >= 202002L + inline void my_cpp2020_assert(const bool JudgmentCondition, const char* ErrorMessage, std::source_location AssertExceptionDetailTrackingObject) { if(!JudgmentCondition) @@ -609,4 +611,6 @@ std::optional try_allocate_temporary_memory_size(std::size_t memory return temporary_memory_byte_size; } -#endif // !SUPPORT_LINRARY_H +#endif + +#endif // !SUPPORT_LIBRARY_H diff --git a/include/UtilTools/CompressDataProcessing.hpp b/include/UtilTools/CompressDataProcessing.hpp index a395852..71c41fb 100644 --- a/include/UtilTools/CompressDataProcessing.hpp +++ b/include/UtilTools/CompressDataProcessing.hpp @@ -20,6 +20,8 @@ * You should get a copy of the GNU General Public License with your program. If not, see . */ +#pragma once + #include "Support+Library/Support-MyType.hpp" #ifndef HUFFMAN_TREE_TEST diff --git a/include/UtilTools/DataFormating.hpp b/include/UtilTools/DataFormating.hpp index e511738..412aa99 100644 --- a/include/UtilTools/DataFormating.hpp +++ b/include/UtilTools/DataFormating.hpp @@ -786,7 +786,6 @@ namespace UtilTools::DataFormating { constexpr char transArray[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - auto byteArraySize = byteArray.end() - byteArray.begin(); std::string hexadecimalString; for ( auto begin = byteArray.begin(), end = byteArray.end(); begin != end; begin++ ) diff --git a/include/UtilTools/DataStreamConverter.hpp b/include/UtilTools/DataStreamConverter.hpp index 758f0f2..c84397b 100644 --- a/include/UtilTools/DataStreamConverter.hpp +++ b/include/UtilTools/DataStreamConverter.hpp @@ -8,7 +8,7 @@ * 发布 TDOM-EncryptOrDecryptFile-Reborn 是希望它能有用,但是并无保障;甚至连可销售和符合某个特定的目的都不保证。请参看 GNU 通用公共许可证,了解详情。 * 你应该随程序获得一份 GNU 通用公共许可证的复本。如果没有,请看 。 */ - + /* * Copyright (C) 2021-2022 Twilight-Dream * @@ -143,25 +143,10 @@ namespace UtilTools::DataStreamConverter // For integer and hexadecimal string the exchange converter // For integer and string the exchange converter - template - requires std::is_integral_v - std::string IntegerToString( const AnyInteger* input, const std::size_t& input_size, bool raw_mode ); - - template - requires std::is_integral_v - std::vector StringToInteger( const std::string& input, bool raw_mode ); - - template - requires std::is_integral_v - std::string Integer2Hexadecimal( const AnyInteger& input ); - - template - requires std::is_integral_v - AnyInteger Hexadecimal2Integer( const std::string& input ); - //--------------------------------------------------------------------------- // Convert a numbers to a string //--------------------------------------------------------------------------- + template requires std::is_integral_v std::string IntegerToString( const AnyInteger* input, const std::size_t& input_size, bool raw_mode = true ) @@ -250,6 +235,7 @@ namespace UtilTools::DataStreamConverter //--------------------------------------------------------------------------- // Convert a string to a numbers //--------------------------------------------------------------------------- + template requires std::is_integral_v std::vector StringToInteger( const std::string& input, bool raw_mode = true ) @@ -408,4 +394,4 @@ namespace UtilTools::DataStreamConverter return output; } -} // namespace UtilTools::DataStreamConverter \ No newline at end of file +} // namespace UtilTools::DataStreamConverter diff --git a/source-code/IsFor_EODF_Reborn.hpp b/source-code/IsFor_EODF_Reborn.hpp index 421c43a..f5b405e 100644 --- a/source-code/IsFor_EODF_Reborn.hpp +++ b/source-code/IsFor_EODF_Reborn.hpp @@ -8,7 +8,7 @@ * 发布 TDOM-EncryptOrDecryptFile-Reborn 是希望它能有用,但是并无保障;甚至连可销售和符合某个特定的目的都不保证。请参看 GNU 通用公共许可证,了解详情。 * 你应该随程序获得一份 GNU 通用公共许可证的复本。如果没有,请看 。 */ - + /* * Copyright (C) 2021-2022 Twilight-Dream * @@ -82,7 +82,7 @@ * @author Project Owner and Module Designer: Twilight-Dream * @author Algorithm Designer: Spiritual-Fish * @author Tech Supporter : XiLiuFeng -* +* * 功能名:隐秘的奥尔德雷斯之谜 * Function Name: OaldresPuzzle-Cryptic * @@ -92,7 +92,7 @@ * * 联系方式: * Contact details: -* +* * With by bilibili website personal space: * Twilight-Dream https://space.bilibili.com/21974189 * Spiritual-Fish https://space.bilibili.com/1545018134 @@ -330,7 +330,7 @@ namespace EODF_Reborn //TODO encrypted_byte_data = custom_encrypter.Main( byte_data, byte_key_data ); - + Cryptograph::CommonModule::Adapters::classicByteFromByte(encrypted_byte_data, encrypted_data); return encrypted_data; @@ -449,7 +449,7 @@ namespace EODF_Reborn std::vector temporary_data { file_data_begin, file_data_begin + iterator_offset }; temporary_processed_data = common_passcoder_reference.Encrypt(temporary_data, temporary_classic_byte_key_data); - + ++builded_key_stream_begin; file_data_begin += iterator_offset; @@ -539,7 +539,7 @@ namespace EODF_Reborn std::vector temporary_data { file_data_begin, file_data_begin + iterator_offset }; temporary_processed_data = common_passcoder_reference.Decrypt(temporary_data, temporary_classic_byte_key_data); - + ++builded_key_stream_begin; decrypted_classic_all_byte.push_back(temporary_processed_data); @@ -591,7 +591,7 @@ namespace EODF_Reborn std::vector temporary_data { file_data_begin, file_data_begin + iterator_offset }; temporary_processed_data = common_passcoder_reference.Decrypt(temporary_data, temporary_classic_byte_key_data); - + ++builded_key_stream_begin; file_data_begin += iterator_offset; @@ -684,7 +684,7 @@ namespace EODF_Reborn //[packing and unpacking] //相关的内存映射对象数据,将会被进行打包和进行解包 //The associated memory mapped object data will be packaged and unpacked - + mio::mmap_source mapped_ro_object; auto mmap_data_package = MIO_LibraryHelper::MappingMemoryMapObject_TryAssociateFile_ToPack(file_path_name, managed_ro_mmap_pointer); bool associated_mmap_data_package_status = MIO_LibraryHelper::MappedMemoryMapObject_FromUnpack(mmap_data_package, mapped_ro_object); @@ -766,7 +766,7 @@ namespace EODF_Reborn } } - + /* 构建密钥流 Building a keystream @@ -781,7 +781,7 @@ namespace EODF_Reborn std::unique_ptr HashTokenHelperPointer = std::make_unique(HashTokenForDataParameters_Instance); std::optional Optional_HashTokenResult = std::optional(); - + switch (HashTokenForDataParameters_Instance.HashersAssistantParameters_Instance.hash_mode) { case Hasher::WORKER_MODE::SHA2_512: @@ -890,12 +890,12 @@ namespace EODF_Reborn //[packing and unpacking] //相关的内存映射对象数据,将会被进行打包和进行解包 //The associated memory mapped object data will be packaged and unpacked - + mio::mmap_sink mapped_rw_object; std::error_code error_code_object; auto mmap_data_package = MIO_LibraryHelper::MappingMemoryMapObject_TryAssociateFile_ToPack(encrypted_file_name, managed_rw_mmap_pointer); bool associated_mmap_data_package_status = MIO_LibraryHelper::MappedMemoryMapObject_FromUnpack(mmap_data_package, mapped_rw_object, error_code_object); - + if (associated_mmap_data_package_status) { auto file_data_begin = mapped_rw_object.begin(); @@ -925,7 +925,7 @@ namespace EODF_Reborn if(iterator_offset < need_process_block_size) { std::vector file_data_part { file_data_begin, file_data_begin + iterator_offset }; - + //Encryption Function //this->_EncryptingData_MemoryMappcation_(file_data_part, custom_encrypter, builded_key_stream, builded_key_stream_begin, builded_key_stream_end); @@ -947,7 +947,7 @@ namespace EODF_Reborn else { std::vector file_data_part { file_data_begin, file_data_begin + need_process_block_size }; - + //Encryption Function //this->_EncryptingData_MemoryMappcation_(file_data_part, custom_encrypter, builded_key_stream, builded_key_stream_begin, builded_key_stream_end); @@ -1037,7 +1037,7 @@ namespace EODF_Reborn //[packing and unpacking] //相关的内存映射对象数据,将会被进行打包和进行解包 //The associated memory mapped object data will be packaged and unpacked - + mio::mmap_sink mapped_rw_object; std::error_code error_code_object; auto mmap_data_package = MIO_LibraryHelper::MappingMemoryMapObject_TryAssociateFile_ToPack(decrypted_file_name, managed_rw_mmap_pointer); @@ -1072,7 +1072,7 @@ namespace EODF_Reborn if(iterator_offset < need_process_block_size) { std::vector file_data_part { file_data_begin, file_data_begin + iterator_offset }; - + //Decryption Function //this->_DecryptingData_MemoryMappcation_(file_data_part, custom_decrypter, builded_key_stream, builded_key_stream_begin, builded_key_stream_end); @@ -1094,7 +1094,7 @@ namespace EODF_Reborn else { std::vector file_data_part { file_data_begin, file_data_begin + need_process_block_size }; - + //Decryption Function //this->_DecryptingData_MemoryMappcation_(file_data_part, custom_decrypter, builded_key_stream, builded_key_stream_begin, builded_key_stream_end); @@ -1349,7 +1349,7 @@ namespace EODF_Reborn std::function taskFunction = std::bind_front(&CryptographFileDataHelper::EncryptionFileWithMemoryMapping, this, std::ref(file_path_name), std::ref(encrypted_file_name), std::ref(buildedKeyStream), std::ref(profile_builder), std::ref(threadPoolVersion1)); std::future asyncTask = std::async(std::launch::async, taskFunction); - + while (std::future_status::ready != asyncTask.wait_for(std::chrono::seconds(10))) { if(std::future_status::ready == asyncTask.wait_for(std::chrono::seconds(10))) @@ -1402,11 +1402,11 @@ namespace EODF_Reborn auto& fileDataPart = *(pointer_filedata_blockchain.get()); //Do File Encryption - + /* - + Cryptograph::Implementation::Encrypter CustomEncrypter; - + auto buildedKeyStreamBegin = buildedKeyStream.begin(); auto buildedKeyStreamEnd = buildedKeyStream.end(); @@ -1424,7 +1424,7 @@ namespace EODF_Reborn ++buildedKeyStreamBegin; } } - + */ /*Cryptograph::CommonModule::ConversionBufferData_Output(FDCM_adapter_pointer, bytesPointer); @@ -1458,11 +1458,19 @@ namespace EODF_Reborn std::ofstream outputProfileObject; + #if defined(_WIN32) + #define CURRENT_PATH_POINT_STRING L"." + #else + #define CURRENT_PATH_POINT_STRING "." + #endif + profile_builder.FileMainName = file_path_name.filename(); - profile_builder.FileMainName.resize(profile_builder.FileMainName.find(L".", 0)); + profile_builder.FileMainName.resize(profile_builder.FileMainName.find(CURRENT_PATH_POINT_STRING, 0)); profile_builder.FileExtensionName = file_path_name.extension(); profile_builder.CryptographDataEnumType = cryptograph_function_type; + #undef CURRENT_PATH_POINT_STRING + outputProfileObject.open(profile_path_name, std::ios::binary | std::ios::trunc); if(outputProfileObject.is_open()) { @@ -1556,7 +1564,7 @@ namespace EODF_Reborn } FileProcessing::CryptographProfileBuilder profile_builder; - + std::ifstream inputProfileObject; inputProfileObject.open(profile_path_name, std::ios::binary); @@ -1583,7 +1591,7 @@ namespace EODF_Reborn std::optional>> optional_buildedKeyStream = futureTask_buildingKeyStream.get(); threadPoolVersion1.finished(); - + std::deque> buildedKeyStream; if(optional_buildedKeyStream.has_value()) @@ -1640,7 +1648,7 @@ namespace EODF_Reborn return false; } - std::cout << "Please wait for your file to be decrypted......" << std::endl; + std::cout << "Please wait for your file to be decrypted......" << std::endl; /*std::vector buildedKeyBlock; @@ -1749,9 +1757,9 @@ namespace EODF_Reborn if(UseMemoryMappcation) { std::function taskFunction = std::bind_front(&CryptographFileDataHelper::DecryptionFileWithMemoryMapping, this, std::ref(file_path_name), std::ref(decrypted_file_name), std::ref(buildedKeyStream), std::ref(profile_builder), std::ref(threadPoolVersion1)); - + std::future asyncTask = std::async(std::launch::async, taskFunction); - + while (std::future_status::ready != asyncTask.wait_for(std::chrono::seconds(10))) { if(std::future_status::ready == asyncTask.wait_for(std::chrono::seconds(10))) @@ -1854,9 +1862,9 @@ namespace EODF_Reborn */ //Do File Decryption - + /* - + Cryptograph::Implementation::Decrypter CustomDecrypter; auto buildedKeyStreamBegin = buildedKeyStream.begin(); @@ -1876,7 +1884,7 @@ namespace EODF_Reborn ++buildedKeyStreamBegin; } } - + */ /*Cryptograph::CommonModule::ConversionBufferData_Output(FDCM_adapter_pointer, bytesPointer); @@ -1927,4 +1935,4 @@ namespace EODF_Reborn }; } // namespace MainProgram_ModulemImplementation -} // namespace EODF_Reborn \ No newline at end of file +} // namespace EODF_Reborn